`<chrono>`: Improve exception messages when OS support is unavailable for time zones
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
Overview
The STL's VS 2019 16.10 Changelog explained:
While the STL generally provides all features on all supported versions of Windows, leap seconds and time zones (which change over time) require OS support that was added to Windows 10. Specifically, updating the leap second database requires Windows 10 version 1809 or later, and time zones require
icu.dllwhich is provided by Windows 10 version 1903/19H1 or later. This applies to both client and server OSes; note that Windows Server 2019 is based on Windows 10 version 1809.
When OS support is unavailable, we throw exceptions, as permitted by the Standard. However, if a programmer isn't already aware of the OS version dependency here, deducing "the end user's OS is too old" from the exception message can be an excessively mysterious process.
#1911 asks whether a fallback mechanism can be implemented for old OSes. There are no current plans to do so, and I believe that this will remain infeasible. However, it should be fairly simple to enhance the exception messages here.
Leap seconds require Windows 10 version 1809 or later
I believe that this happens in __std_tzdb_get_leap_seconds:
For old OSes, I don't believe that we throw an exception:
It looks like we silently say "there's no post-2018 leap second data" for old OSes. If I'm right, then there's no exception message that needs to be enhanced here. (Leap seconds are also much less "popular" than time zones.)
Time zones require Windows 10 version 1903/19H1 or later
_Init_icu_functions is the single place where we load icu.dll:
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/src/tzdb.cpp#L66
The only caller is the wrapper _Acquire_icu_functions:
Which in turn has 3 callsites: __std_tzdb_get_time_zones, __std_tzdb_get_current_zone, __std_tzdb_get_sys_info:
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/src/tzdb.cpp#L357-L358
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/src/tzdb.cpp#L460-L461
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/src/tzdb.cpp#L501-L502
They all report __std_tzdb_error::_Win_error (because we haven't even loaded ICU yet; _Icu_error is for when we've loaded ICU but it fails later). They're all called via _Make_unique_tzdb_info:
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/inc/chrono#L1837-L1838
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/inc/chrono#L2069
https://github.com/microsoft/STL/blob/442029c6fa37f1b6f9203357de09672d5704077c/stl/inc/chrono#L2110
Which has conveniently extracted the common pattern here (thanks to #4119):
Therefore, I believe that the _XGetLastError() is the single location that we need to modify. Unfortunately, _XGetLastError() was not designed to be extensible - it combines calling GetLastError() and throwing a system_error with it:
To throw a better exception here, without try-catch-rethrow, we'd need to inject a new function into the import lib. (I think we should continue to capture GetLastError(), but provide an additional message mentioning that the OS version may be relevant.)
Suggested message
Windows versioning is complicated (but not nearly as much as MSVC versioning 😹) so for clarity I suggest a message like:
"C++20 chrono time zone support requires Windows 10 version 1903/19H1, Windows 11, Windows Server 2022, or later."
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 in stl/src/tzdb.cpp at _Init_icu_functions and _Acquire_icu_functions, then inspect stl/inc/chrono around _Make_unique_tzdb_info and the _XGetLastError path in stl/src/xonce.cpp. Confirm how the existing Windows error is captured and identify the supported OS-version wording needed for time-zone failures. Done means the relevant exception preserves the system error while explaining the OS requirement.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100