While the <chrono> header has been available as part of the STL since C++11, among the changes included in C++20 there were several extensions to chrono including support for calendrical types, time zones, leap seconds, and integration with format. A great deal of innovation and work was required in order to complete these additional features; shipping these new C++20 additions so soon would not have been possible without the amazing support of the open-source community. In particular, I would like to recognize the significant contributions from Matt Stephansonstatementreply, and Daniel Marshall in helping complete our implementation.

Overview & Examples

There were numerous additions to the <chrono> header in the changes for C++20, and here I’d like to highlight a few.

Calendrical Types

The PR GH-323: Partially implement P0355R7, authored by Daniel Marshall added a long list of new calendrical types to the header for date support. For example:

Here we create a year object for the year 2021, then use it to create a year_month_day object representing May 20, 2021 or World Bee Day. We then use an alternate form to represent the exact same day by making a month_weekday object representing the third Thursday of May (indicated with the Thurs[3] which is creating a weekday_indexed object) in an unspecified year, and then using that to create a year_month_weekday object by combining It with the integer 2021 which is interpreted as the year.

You can see that the library now includes a variety of different calendrical types that allow users to create dates in a variety of different ways. These different forms of dates are intended to be very easy-to-use and intuitive, so that users can choose the method most comfortable or natural to them.

Time Zones

Awareness of time zones were another significant addition to the <chrono> header, which included new types (e.g., time_zonetzdbzoned_time) as well as significant consideration for how to manage the data that library’s newfound time-zone-awareness would require. A small example displaying an example of the new time zone feature follows:

This is only a small example of the functionalities included in newly-added time zone support. The feature also supports converting between different time zones, notions of “local” time, and possibilities of ambiguous or nonexistent conversions to/from time zones due to daylight savings transitions.  In this example, we first attain a reference to the most up-to-date tzdb object which contains data about time zones. We then use it to look up the America/Los Angeles time zone (GMT-07:00) by name, storing a time_zone pointer pointing to that entry in the tzdb. Next we create a specific date (corresponding to World Nutella Day) using local_days and some of the calendrical types mentioned above, which we can then use to create a zoned_time object which pairs a specific date/time (in this case World Nutella Day at 03:44:12) with a given time zone (America/Los Angeles in this case). We then use the America/Los Angeles zoned_time to create a zoned_time corresponding to UTC time, illustrating the time zone conversion functionality.

One specific challenge that we encountered in our implementation was how to actually access the data that the time zones required. The C++20 Standard defines the time zone functionality in terms of the IANA database, however MSVC’s STL would not be able to ship the entire database with its implementation due to its size and the issue of how to provide updates to it. We had to explore alternate options as we pondered how to support this Standard-mandated feature without subjecting our customers to absurd header size increases. We eventually discovered the ICU library which ships as part of the Windows 10 operating system in more recent versions (19H1 and after) and derives its data from the IANA database itself. As a result, updates to the time zone data will be executed along with updates to the OS through Windows Update. While our current implementation relies on the availability of the ICU DLL in more recent OS versions, we have plans to revisit the issue and investigate implementing a fallback for older operating systems. While there are a few discrepancies between the IANA database and the ICU library, the data should largely be the same.

Leap Seconds

Our recent changes also include support for tracking leap seconds, largely implemented in MattStephanson’s GH-1671: C++20 clocks, clock_cast, tzdb::leap_seconds, with valuable input from statementreply. With this new support, you can ask whether a given time occurs during a leap second insertion or removal (fun fact, both positive and negative leap seconds are possible!) or not. C++20 also added several new clock types (in addition to system_clocksteady_clock, and high_resolution_clock which have existed since C++11), some of them leap-second-aware (such as utc_clock) while others are not (such as system_clock). We detect new leap seconds through Windows registries (with the guidance of Dan Cuomo’s networking blogpost), so any new leap seconds will need to be detected through Windows updates as well.

#announcement #c++

C++20's Extensions to Chrono Available in Visual Studio 2019 version 16.10
1.40 GEEK