C++20: Time of Day

This new data type std::chrono::hh_mm_ss in C++20 stands for the time of day.

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.

Depending on the used time duration, the static member provides the appropriate tOfDay.fractional_width. If no such value of fractional_width in the range [0, 18] exists, then fractional_width is 6. See for example, std::chrono::duration<int, std::ratio<1, 3>> in the following table.

The use of the chrono type std::chrono::hh_mm_ss is straightforward.

// timeOfDay.cpp

#include <chrono>
#include <iostream>

int main() {
                                                            
     using namespace std::chrono_literals; 

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

     std::cout << '\n';

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

     std::cout << '\n';

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

     std::cout << '\n';

     std::cout << "std::chrono::is_am(5h): " << std::chrono::is_am(5h) << '\n';     // (7)    
     std::cout << "std::chrono::is_am(15h): " << std::chrono::is_am(15h) << '\n';   // (7)

     std::cout << '\n';
     
     std::cout << "std::chrono::make12(5h): " << std::chrono::make12(5h) << '\n';   // (7)   
     std::cout << "std::chrono::make12(15h): " << std::chrono::make12(15h) << '\n'; // (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 can add a few time durations to initialize a time-of-day object. With C++20, you can directly output timeOfDay (line 2). The rest should be straightforward to read. 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.

Here is the output of the program:

Calendar Date

A new type of the chrono extension in C++20 is a calendar date. C++20 supports various ways to create a calendar date and interact with them. First of all: What is a calendar date?

  •  A calendar date consists of a year, a month, and a day. Consequently, C++20 has a specific data type std::chrono::year_month_day. C++20 has way more to offer. The following table should give you an overview of calendar types before I show you various use cases.

Thanks to the cute syntax, you can use  std::chrono::operator / to create Gregorian calendar dates.

The calendar data types support various operations. The following table gives an overview. For readability reasons, I partially ignore the namespace std::chrono.

The increment and decrement operations ++/-- are supported in the prefix and postfix version. Adding or subtraction +/- requires objects of type std::chrono::duration. That means when you build the difference of two objects of calendar type std::chrono::day you get an object of type std::chrono::days. <=> is the new three-way comparison operator.

 

Rainer D 6 P2 500x500Modernes C++ Mentoring

  • "Fundamentals for C++ Professionals" (open)
  • "Design Patterns and Architectural Patterns with C++" (open)
  • "C++20: Get the Details" (open)
  • "Concurrency with Modern C++" (open)
  • "Generic Programming (Templates) with C++": October 2024
  • "Embedded Programming with Modern C++": October 2024
  • "Clean Code: Best Practices for Modern C++": March 2025
  • Do you want to stay informed: Subscribe.

     

    The following program uses the operations on the calendar types.

    // calendarOperations.cpp
    
    #include <chrono>
    #include <iostream>
    
    int main() {
    
      std::cout << '\n';
    
      using std::chrono::Monday;
      using std::chrono::Saturday;
    
      using std::chrono::March;
      using std::chrono::June;
      using std::chrono::July;
    
      using std::chrono::days;
      using std::chrono::months;
      using std::chrono::years;
    
      using std::chrono::last;
    
      using namespace std::chrono_literals;
    
      std::cout << std::boolalpha;
    
      std::cout << "March: " << March << '\n';                                            
      std::cout << "March + months(3): " << March + months(3) << '\n';                      // (1)
      std::cout << "March - months(25): " << March - months(25) << '\n';                    // (5)  
      std::cout << "July - June: " <<  July - June << '\n';                                 // (6)
      std::cout << "June < July: " << (June < July) << '\n';                                // (7)
    
      std::cout << '\n';
     
      std::cout << "Saturday: " << Saturday << '\n';
      std::cout << "Saturday + days(3): " << Saturday + days(3) << '\n';                    // (2)
      std::cout << "Saturday - days(22): " << Saturday - days(22) << '\n';                  // (8)
      std::cout << "Saturday - Monday: " <<  Saturday - Monday << '\n';                     // (9)
    
      std::cout << '\n';
    
      std::cout << "2021y/March: " << 2021y/March << '\n';                                  // (3)
      std::cout << "2021y/March + years(3) - months(35): "                                  // (10)
                << 2021y/March + years(3) - months(35) << '\n';
      std::cout << "2022y/July - 2021y/June: " << 2022y/July - 2021y/June << '\n';         // (11)
      std::cout << "2021y/June > 2021y/July: " << (2021y/June > 2021y/July) << '\n';       // (12)
    
      std::cout << '\n';
    
      std::cout << "2021y/March/Saturday[last]: " << 2021y/March/Saturday[last] << '\n';   // (4)
      std::cout << "2021y/March/Saturday[last] + months(13) + years(3): " 
                << 2021y/March/Saturday[last] + months(13) + years(3) << '\n';
      std::cout << "2021y/July/Saturday[last] - months(1) == 2021y/June/Saturday[last]: "
                << (2021y/July/Saturday[last] - months(1) == 2021y/June/Saturday[last]) 
                << '\n';
    
      std::cout << '\n';
    
    }
    

    The program performs operations on std::chrono::month (line 1), std::chrono::weekday (line 2), std::chrono::year_month (line 3), and std::chrono::year_month_weekday_last (line 4).

    Adding or subtracting the time duration std::chrono::months automatically applies modulo operations (lines 5 and 6). Subtracting two std::chrono::month objects returns 1 month. One month has 2629746 seconds (line 7). Accordingly, you can add or subtract a time duration std::chrono::days to or from a calendar data std::chrono::day (lines 8 and 9). Subtracting two std::chrono::day objects returns a std::chrono::days object. std::chrono::year_month allows the subtraction (line 10), the difference (line 11), and the comparison of time points (line 12). Objects of type std::chrono::weekday_last allow the addition/subtraction of the time durations std::chrono::months and std::chrono::years. In addition, these std::chrono::weekday_last objects can be compared.

    What’s Next?

    C++20 supports constants and literals to make using calendar-date types more convenient.

    Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Stephen Kelley, Kyle Dean, Tusar Palauri, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, Marco Parri Empoli, Philipp Lenk, Charles-Jianye Chen, Keith Jeffery, Matt Godbolt, and Honey Sukesan.

    Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.

    My special thanks to Embarcadero
    My special thanks to PVS-Studio
    My special thanks to Tipi.build 
    My special thanks to Take Up Code
    My special thanks to SHAVEDYAKS

    Modernes C++ GmbH

    Modernes C++ Mentoring (English)

    Do you want to stay informed about my mentoring programs? Subscribe Here

    Rainer Grimm
    Yalovastraße 20
    72108 Rottenburg

    Mobil: +49 176 5506 5086
    Mail: schulung@ModernesCpp.de
    Mentoring: www.ModernesCpp.org

    Modernes C++ Mentoring,