Calendar and Time-Zones in C++20: Time of Day

Calendar and Time-Zones in C++20: Time of Day

With C++20, the chrono library from C++11 receives important additions. The most prominent ones are a calendar and time-zones support. But this is by far not all. C++20 gets new clocks, powerful formatting functionality for time durations, and a time of day type.

Before I dive into the extended chrono library and, in particular, in this post into the new type std::chrono::time_of_day, I have to make a few remarks. In short, I call all date and time utilities provided by chrono the time library.

The time library in C++11

To get the most out of this post, a basic understanding of the chrono library is essential. C++11 introduced three main components to deal with time:

  • A time point is defined by a starting point, the so-called epoch, and additional time duration.
  • A time duration  which is the difference between two time-points. It is given by the number of ticks.
  • A clock consists of a starting point (epoch) and a tick so that the current time point can be calculated.

Honestly, time is for me a mysterium. On one hand, each of us has an intuitive idea of time, on the other hand, defining it formally is extremely challenging. For example, the three components time point, time duration, and clock depend on each other. If you want to know more about the time functionality in C++11, read my previous posts: time.

The chrono Extensions in C++20

C++20 adds new components to the chrono library:

  • The time of day is the time duration since midnight split into hours, minutes, seconds, and fractional seconds.
  • Calendar stands for various calendar dates such as year, a month, a weekday, or the n-th day of a week.
  • A time-zone represents time specific to a geographic area.

Essentially, the time-zone functionality (C++20) is based on the calendar functionality (C++20) and the calendar functionality (C++20) is based on the original chrono functionality (C++11).

But that is not all. The extension includes new clocks. Thanks to the formatting library in C++20, time durations can be read or written.

The date Prototype Library

While writing this post, no C++ compiler supports the chrono extensions in C++20 so far. Thanks to the prototype library date from Howard Hinnant, which is essentially a superset of the extended time functionality in C++20, I can experiment with it. The library is hosted on GitHub. There are various ways to use the date prototype:

  1. You can try it out on wandbox. Howard has uploaded the date.h header which is sufficient to play with the new type std::time_of_day and the calendar. Here is Howard's link: Try it out on wandbox!
  2. Copy the header date.h into the search path of your C++ compiler.
  3. Download the project and build it. The already mentioned GitHub page date gives you more information.

I made my first steps with the online compiler wandbox but switched to the strategy 2.

Required C++ standard

In general, a C++14 compiler is sufficient to use the date library. There is one exception to this rule which I experienced with the following call:

auto timeOfDay = date::time_of_day(10.h + 98min + 2020s + 0.5s); // C++20

auto timeOfDay = date::hh_mm_ss(10.h + 98min + 2020s + 0.5s);    // C++17

I used in my first tries the first call. The first line requires class template argument deduction for alias templates. time_of_day is an alias for hh_mm_ss: using time_of_day_day = hh_mm_ss<Duration>. When you now replace the alias with the class template such as in the second line (C++17), you need a C++17. Class template argument deduction is a C++17.

Read more details to class template argument deduction here: C++17: What's new in the Core Language?

Issue Solved

With C++20 time_of_day was renamed to hh_mm_ss. Howard Hinnant, the creator of the date library and designer of the chrono addition, gave me the crucial hint: "Prefer to use hh_mm_ss in place of time_of_day. time_of_day got renamed to hh_mm_ss during the standardization process for C++20, and so time_of_day remains strictly as a backwards compatible shim for current and past users of this lib."

This are typcial Odysses you have, when you are an early adpoter. 

Porting to C++20

When you only use the content of the date prototype that is part of C++20, porting it to C++ 20 is no big deal. Replace the date header files with the header file <chrono> and the namespace date with the namespace std::chrono:

#include "date.h"    
//#include <chrono>

int main() {

     using namespace std::chrono_literals;
    
     auto am = date::is_am(10h);   
     // auto am = std::chrono::is_am(10h);  

} 

Now, I write about the chrono extensions in C++20.

Time of Day

std::chrono::hh_mm_ss is the duration since midnight split into hours, minutes, seconds, and fractional seconds. This type is typically used as a formatting tool. First, the following table gives you a concise overview of std::chrono::hh_mm_ss instance tOfDay.

No alt text provided for this image

The following program uses the functions:

// timeOfDay.cpp

#include "date.h"
#include <iostream>

int main() {
     using namespace date;                                           // (3)
     using namespace std::chrono_literals; 

     std::cout << std::boolalpha << std::endl;
    
     auto timeOfDay = date::hh_mm_ss(10.5h + 98min + 2020s + 0.5s);  // (1)
    
     std::cout<< "timeOfDay: " << timeOfDay << std::endl;            // (2)

     std::cout << std::endl;

     std::cout << "timeOfDay.hours(): " << timeOfDay.hours() << std::endl;             // (4)
     std::cout << "timeOfDay.minutes(): " << timeOfDay.minutes() << std::endl;         // (4)
     std::cout << "timeOfDay.seconds(): " << timeOfDay.seconds() << std::endl;         // (4)
     std::cout << "timeOfDay.subseconds(): " << timeOfDay.subseconds() << std::endl;   // (4)
     std::cout << "timeOfDay.to_duration(): " << timeOfDay.to_duration() << std::endl; // (5)

     std::cout << std::endl;

     std::cout << "date::hh_mm_ss(45700.5s): " << date::hh_mm_ss(45700.5s) << '\n';  // (6)

     std::cout << std::endl;

     std::cout << "date::is_am(5h): " << date::is_am(5h) << std::endl;                 // (7)    
     std::cout << "date::is_am(15h): " << date::is_am(15h) << std::endl;               // (7)

     std::cout << std::endl;
     
     std::cout << "date::make12(5h): " << date::make12(5h) << std::endl;               // (7)   
     std::cout << "date::make12(15h): " << date::make12(15h) << std::endl;             // (7) 

}

In line (1), I create a new instance of std::chrono::hh_mm_ss: timeOfDay. Thanks to the chrono literals from C++14, I just can add a few time durations to initialize a time of day object. With C++20, you can directly output timeOfDay (line 2). This is the reason I have to introduce the namespace date in line 3. The rest should be straightforward to read. The lines (4) display the components of the time since midnight in hours, minutes, seconds, and fractional seconds. Line (5) returns the time duration since midnight in seconds. Line (6) is more interesting: the given seconds correspond to the time displayed in line (2). Line (7) returns if the given hour is a.m. Line (8) finally returns the 12-hour equivalent of the given hour.

Thanks to the date library, here is the output of the program:

No alt text provided for this image

What's next?

My next post presents the next component of the extended chrono library: calendar.

 

Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Venkata Ramesh Gudpati, Tobias Zindl, Marko, G Prvulovic, Reinhold Dr?ge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Darshan Mody, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, espkk, Wolfgang G?rtner, Louis St-Amour, Stephan Roslen, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Avi Kohn, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Neil Wang, Friedrich Huber, Sudhakar Balagurusamy, and lennonli.

 

Thanks in particular to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, and Dendi Suhubdy

 

 

Seminars

I'm happy to give online-seminars or face-to-face seminars world-wide. Please call me if you have any questions.

Standard Seminars 

Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.

Contact Me

Modernes C++

要查看或添加评论,请登录

Rainer Grimm的更多文章

社区洞察

其他会员也浏览了