microsoft / microsoft/STL

<chrono>: system_clock could be off after a future leap second

Open
#1,520 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug chrono
Dominant language
C++
Stars
11.1k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

Describe the bug

Since Windows 10 1809 and Windows Server 2019, FILETIME includes leap seconds after 2018-06 (configurable system-wide, enabled by default), and will no longer be a constant offset from system_clock. system_clock::now needs to be updated to account for future leap seconds, if enabled on the system.

Command-line test case

  1. Run the following command once as administrator. Note that this inserts a fake leap second (2020-11-30T23:59:60Z). The system clock and file modification times after 2020-11-30 will be off by 1 second.

    C:\WINDOWS\system32>w32tm /leapseconds /add:+2020-11-30T23:59:59 /force /testmode
    成功地执行了命令。
    

    The following command can be used to check the status of leap seconds.

    C:\WINDOWS\system32>w32tm /leapseconds /getstatus /verbose
    [闰秒]
    Enabled: 1 (Local)
    Number of Leap Seconds (after June 2018): 1 (Local)
    Leap Seconds List (Local):
    +2020-11-30T23:59:59
    
  2. Run the test case.

    D:\Temp>type leap_second_2.cpp
    
    #include <Windows.h>
    #include <chrono>
    #include <cstdio>
    
    using namespace std;
    using namespace std::chrono;
    
    int main() {
        SYSTEMTIME win_sys_time;
        GetSystemTime(&win_sys_time);
    
        const auto stl_sys_time = system_clock::now();
        const auto stl_total = stl_sys_time.time_since_epoch();
        const auto stl_days = floor<duration<int, ratio<86400>>>(stl_total);
        const auto stl_hours = floor<duration<int, ratio<3600>>>(stl_total - stl_days);
        const auto stl_minutes = floor<duration<int, ratio<60>>>(stl_total - stl_days - stl_hours);
        const auto stl_seconds = floor<duration<int>>(stl_total - stl_days - stl_hours - stl_minutes);
        const auto stl_100ns =
            floor<duration<int, ratio<1, 10'000'000>>>(stl_total - stl_days - stl_hours - stl_minutes - stl_seconds);
    
        printf("Windows: %.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d\n", win_sys_time.wYear, win_sys_time.wMonth, win_sys_time.wDay,
            win_sys_time.wHour, win_sys_time.wMinute, win_sys_time.wSecond, win_sys_time.wMilliseconds);
        printf("    STL: %10d %.2d:%.2d:%.2d.%.7d\n", stl_days.count(), stl_hours.count(), stl_minutes.count(),
            stl_seconds.count(), stl_100ns.count());
    }
    
    D:\Temp>cl /EHsc /W4 /WX /std:c++latest leap_second_2.cpp
    Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29617 for x64
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /std:c++latest is provided as a preview of language features from the latest C++
    working draft, and we're eager to hear about bugs and suggestions for improvements.
    However, note that these features are provided as-is without support, and subject
    to changes or removal as the working draft evolves. See
    https://go.microsoft.com/fwlink/?linkid=2045807 for details.
    
    leap_second_2.cpp
    Microsoft (R) Incremental Linker Version 14.28.29617.0
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /out:leap_second_2.exe
    leap_second_2.obj
    
    D:\Temp>.\leap_second_2.exe
    Windows: 2020-12-09 06:38:33.802
        STL:      18605 06:38:34.8027188
    
  3. After testing, run the following command as administrator and reboot to revert the fake leap second.

    C:\WINDOWS\system32>w32tm /leapseconds /remove:+2020-11-30T23:59:59 /force /testmode
    成功地执行了命令。
    

Expected behavior

GetSystemTime and system_clock::now should return the same time.

STL version

Microsoft Visual Studio Community 2019 Preview
版本 16.9.0 Preview 2.0

Additional context

Related to implementation of C++20 file_clock::to_sys xor file_clock::to_utc.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the implementation of system_clock::now on Windows and the related C++20 file_clock::to_sys and file_clock::to_utc paths mentioned in the issue. Reproduce the discrepancy with the supplied w32tm and leap_second_2.cpp commands, then verify that GetSystemTime and system_clock::now agree when future leap seconds are enabled.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.