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 = { "Asia/Tokyo", "Asia/Hong_Kong", "Europe/Bucharest", "Europe/Berlin", "Europe/London", "America/New_York", "Pacific/Honolulu", }; 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.
Great. Please publish full and working programs without using auto. You are trying to educate, than don’t hide half of the code.