C++20 calendars and time zones

A couple years ago I wrote a post called A better date and time C++ library about Howard Hinnant’s date library (I actually planned for several posts, but only the first was materialized). A slightly modified version of the library has been voted in for C++ 20 at the ISO committee meeting in Jacksonville this month. You can find the actual proposal here D0355R7: Extending <chrono> to Calendars and Time Zones.

This addition to the chrono library provides two things:

  • calendar support: on one hand, types that represent the year, month and day, and various combinations, such as a specific day in a month (month_day) or the last day in a month (month_day_last), a specific month of the year (year_month) and others, and on the other hand operations with dates for the Gregorian calendar.
  • time zones support: the ability the represent time points in a specific time zone (from the IANA time zones database).

The library is not implemented yet by any compiler but you can find it on Github and you can try it on Wandbox. Mind that the namespace of this implementation is date, but it will actually be part of std::chrono.

Here are just some random examples of using the new features:

  • Representing dates:
    auto d1 = 2018_y / mar / 27;
    auto d2 = 27_d / mar / 2018;
    auto d3 = mar / 27 / 2018;
    year_month_day today = floor<days>(system_clock::now());
    assert(d1 == d2);
    assert(d2 == d3);
    assert(d3 == today);
  • Determining the last day of February the current year:
    auto today = year_month_day{ floor<days>(system_clock::now()) };
    auto ymdl = year_month_day_last(today.year(), month_day_last{ month{ 2 } });
    auto last_day_feb = year_month_day{ ymdl };
    assert(last_day_feb == 2018_y/feb/28); // for 2018
  • Number of days between two dates:
    inline int number_of_days(sys_days const & first,
                              sys_days const & last)
       return (last - first).count();
    auto days = number_of_days(2018_y / apr / 1, 2018_y / dec / 25); 
    assert(days == 268);
  • Printing the current time in the current time zone:
    auto time = floor<std::chrono::milliseconds>(system_clock::now());
    std::cout << std::left << std::setw(25) << std::setfill(' ')
              << "Time"
              << time << std::endl;
    auto localtime = zoned_time<std::chrono::milliseconds>(date::current_zone(), time);
    std::cout << std::left << std::setw(25) << std::setfill(' ')
              << "Local"
              << localtime << std::endl;

    The result is something like this (my local time zone is Europe/Bucharest):

    Time                     2018-03-27 10:52:17.081
    Local                    2018-03-27 13:52:17.081 EEST
  • Printing the current time in different time zones (localtime is the object from example above):
    auto zone_names = {
    for(auto const& name : zone_names)
       std::cout << std::left << std::setw(25) << std::setfill(' ')
                 << name
                 << zoned_time<std::chrono::milliseconds>(name, localtime) 
                 << std::endl;

    The result looks like this:

    Asia/Tokyo               2018-03-27 19:52:17.081 JST
    Asia/Hong_Kong           2018-03-27 18:52:17.081 HKT
    Europe/Bucharest         2018-03-27 13:52:17.081 EEST
    Europe/Berlin            2018-03-27 12:52:17.081 CEST
    Europe/London            2018-03-27 11:52:17.081 BST
    America/New_York         2018-03-27 06:52:17.081 EDT
    Pacific/Honolulu         2018-03-27 00:52:17.081 HST

The date and time utilities page at http://en.cppreference.com/w/cpp/chrono is already updated with references to the added extensions, although most of the documentation is just empty for now. However, you can find all that you need in the project documentation on Github.

1 Reply to “C++20 calendars and time zones”

  1. Great. Please publish full and working programs without using auto. You are trying to educate, than don’t hide half of the code.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.