<chrono>: system_clock could be off after a future leap second
Nobody has claimed this yet.
- 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
-
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 -
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 -
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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