Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
statementreply opened this issue Dec 9, 2020 · 1 comment
Open
Labels
bug Something isn't working chrono C++20 chrono

Comments

@statementreply
Copy link
Contributor

statementreply commented Dec 9, 2020

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.

@CaseyCarter CaseyCarter added the bug Something isn't working label Dec 9, 2020
@CaseyCarter
Copy link
Member

Thanks for the detailed report, @statementreply!

@MahmoudGSaleh MahmoudGSaleh added the chrono C++20 chrono label May 4, 2022
CaseyCarter pushed a commit that referenced this issue May 18, 2023
…#3681)

Part of #1588.

`_Xtime_get_ticks` and `system_clock::now` would no longer be equal after a future leap second when #1520 is eventually fixed. This PR changes the clock used in `_To_timespec64_sys_10_day_clamped` to be consistent with code that consumes its result, e.g. `target` in https://github.com/microsoft/STL/blob/091cad2eaaa5bc25873eb7261cae57ab123592f3/stl/src/cond.cpp#L72-L80
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working chrono C++20 chrono
Projects
None yet
3 participants