Calendar and Time-Zones in C++20: Calendar Dates


A new type of the chrono extension in C++20 is a calendar date. C++20 offers various ways to create a calendar date and interact with them.



It took me a while to understand the almost twenty calendar-related data types. For that reason, I start with a calendar date. As in my last post, "Calendar and Time-Zones in C++20: Time of Day ", I use the date library from Howard Hinnant as the prototype of the new chrono extension.


Calendar Date

A calendar date is a date that 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. Both tables present the first overview.




Let's start simple. The following program createCalendar.cpp shows various ways to create calendar-related dates.


// createCalendar.cpp

#include <iostream>
#include "date.h"
int main() {

    std::cout << std::endl;
    using namespace date;

    constexpr auto yearMonthDay{year(1940)/month(6)/day(26)};            // (1)
    std::cout << yearMonthDay << " ";
    std::cout << date::year_month_day(1940_y, June, 26_d) << std::endl;  // (2)

    std::cout << std::endl;

    constexpr auto yearMonthDayLast{year(2010)/March/last};              // (3)
    std::cout << yearMonthDayLast << " ";
    std::cout << date::year_month_day_last(2010_y, month_day_last(month(3))) <<  std::endl;

    constexpr auto yearMonthWeekday{year(2020)/March/Thursday[2]};       // (4)
    std::cout << yearMonthWeekday << " ";
    std::cout << date::year_month_weekday(2020_y, month(March), Thursday[2]) <<  std::endl;

    constexpr auto yearMonthWeekdayLast{year(2010)/March/Monday[last]};  // (5)
    std::cout << yearMonthWeekdayLast << " ";
    std::cout << date::year_month_weekday_last(2010_y, month(March), weekday_last(Monday)) <<  std::endl;

    std::cout << std::endl;

    constexpr auto day_{day(19)};          // (5)
    std::cout << day_  << " ";
    std::cout << date::day(19) << std::endl;

    constexpr auto month_{month(1)};       // (6)
    std::cout << month_  << " ";
    std::cout << date::month(1) << std::endl;

    constexpr auto year_{year(1988)};      // (7)
    std::cout << year_  << " ";
    std::cout << date::year(1988) << std::endl;

    constexpr auto weekday_{weekday(5)};
    std::cout << weekday_  << " ";
    std::cout << date::weekday(5) << std::endl;
    constexpr auto yearMonth{year(1988)/1};
    std::cout << yearMonth  << " ";
    std::cout << date::year_month(year(1988), January) << std::endl;
    constexpr auto monthDay{10/day(22)};
    std::cout << monthDay <<  " ";
    std::cout << date::month_day(October, day(22)) << std::endl;

    constexpr auto monthDayLast{June/last};
    std::cout << monthDayLast << " ";
    std::cout << date::month_day_last(month(6)) << std::endl;
    constexpr auto monthWeekday{2/Monday[3]};
    std::cout << monthWeekday << " ";
    std::cout << date::month_weekday(February, Monday[3]) << std::endl;
    constexpr auto monthWeekDayLast{June/Sunday[last]};
    std::cout << monthWeekDayLast << " ";
    std::cout << date::month_weekday_last(June, weekday_last(Sunday)) << std::endl;

    std::cout << std::endl;



There are essentially two ways to create a calendar date. You can use the so-called cute syntax yearMonthDay{year(1940)/month(6)/day(26)} (line 1), or you can use the explicit type date::year_month_day(1940_y, June, 26_d) (line 2). In order not to overwhelm you, I delay my explanation of the cute syntax to the next  section of this post. The explicit type is quite interesting because it uses the date time literals 1940_y, 26_d, and the predefined constant June. With C++20, the date literals 1940_y and 26_d are written without an underscore: 1940y  and 26d. This was the obvious part.

Line (3), line (4), and line (5) offer convenient ways to create calendar dates.

  • Line (3): the last day of March 2010: {year(2010)/March/last} or year_month_day_last(2010_y, month_day_last(month(3))
  • Line (4): the second Thursday of March 2020: {year(2020)/March/Thursday[2]} or year_month_weekday(2020_y, month(March), Thursday[2])
  • Line (5): the last Monday of March 2010: {year(2010)/March/Monday[last]} or year_month_weekday_last(2010_y, month(March), weekday_last(Monday))

The remaining calendar types stand for a day (line 6), a month (line 7), or a year (line 8). You can combine and use them as basic building blocks for fully specified calendar dates, such as the lines (3) to (4).

Before I dive more into the details, here is the output of the program.


As promised, let me write about the cute syntax.

Cute Syntax

The cute syntax consists of overloaded division operators to specify a calendar date. The overloaded operators support time literals (e.g.: 2020_y, 31_d) and constants (January, February, March, April, May, June, July, August, September, October, November, December).

The following three combinations of year, month, and day are possible when you use the cute syntax.

  1. year/month/day
  2. day/month/year
  3. month/day/year

These combinations are not arbitrarily chosen because they are the used ones worldwide. Each other combination is not allowed

Consequently, when you choose the type year, month, or day for the first argument, the type for the remaining two arguments is no longer necessary anymore, and an integral would do the job.


// cuteSyntax.cpp

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

int main() {

    std::cout << std::endl;

    using namespace date;

    constexpr auto yearMonthDay{year(1966)/6/26};
    std::cout << yearMonthDay << std::endl;

    constexpr auto dayMonthYear{day(26)/6/1966};
    std::cout << dayMonthYear << std::endl;

    constexpr auto monthDayYear{month(6)/26/1966};
    std::cout << monthDayYear << std::endl;

    constexpr auto yearDayMonth{year(1966)/month(26)/6};  //(1)
    std::cout << yearDayMonth << std::endl;

    std::cout << std::endl;



The combination year/day/month (line 1) is not allowed and causes a run-time message.

cuteSyntaxI assume you want to display a calendar date {year(2010)/March/last} in a readable form such as 2020-03-31. This is a job for the local_days or sys_days operator.

Displaying Calendar Dates

Thanks to std::chrono::local_days or std::chrono::sys_days, you can convert calendar dates to a std::chrono::time_point representing the same date as this year_month_day. I use std::chrono::sys_days in my example. std::chrono::sys_days is based on std::chrono::system_clock. Let me convert the calendar dates (line (3) - line (5) from the previous program createCalendar.cpp.


// sysDays.cpp

#include <iostream>
#include "date.h"
int main() {

    std::cout << std::endl;
    using namespace date;

    constexpr auto yearMonthDayLast{year(2010)/March/last};
    std::cout << "sys_days(yearMonthDayLast): " << sys_days(yearMonthDayLast)  <<  std::endl;

    constexpr auto yearMonthWeekday{year(2020)/March/Thursday[2]};
    std::cout << "sys_days(yearMonthWeekday): " <<  sys_days(yearMonthWeekday) << std::endl;

    constexpr auto yearMonthWeekdayLast{year(2010)/March/Monday[last]};
    std::cout << "sys_days(yearMonthWeekdayLast): " << sys_days(yearMonthWeekdayLast) << std::endl;

    std::cout << std::endl;

    constexpr auto leapDate{year(2012)/February/last};                // (1)
    std::cout << "sys_days(leapDate): " << sys_days(leapDate) << std::endl;

    constexpr auto noLeapDate{year(2013)/February/last};              // (2)
    std::cout << "sys_day(noLeapDate): " << sys_days(noLeapDate) << std::endl;

    std::cout << std::endl;



The std::chrono::last constant let me easily determine who many days a month has. Consequently, the output shows it that 2012 is a leap year but not 2013.


What's next?

Working with calendar dates becomes really powerful when you check if a calendar date is valid or when you add a time duration to it.


Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, Marko, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, espkk, Louis St-Amour, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Neil Wang, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Tobi Heideman, Daniel Hufschläger, Red Trip, Alexander Schwarz, Tornike Porchxidze, Alessandro Pezzato, Evangelos Denaxas, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Dimitrov Tsvetomir, Leo Goodstadt, Eduardo Velasquez, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, and Michael Young.


Thanks in particular to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, and Bhushan Ivatury.



My special thanks to Embarcadero CBUIDER STUDIO FINAL ICONS 1024 Small



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

Bookable (Online)


Standard Seminars (English/German)

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


Contact Me

Modernes C++,





Tags: time

My Newest E-Books

Course: Modern C++ Concurrency in Practice

Course: C++ Standard Library including C++14 & C++17

Course: Embedded Programming with Modern C++

Course: Generic Programming (Templates)

Course: C++ Fundamentals for Professionals

Interactive Course: The All-in-One Guide to C++20

Subscribe to the newsletter (+ pdf bundle)

Blog archive

Source Code


Today 2027

Yesterday 7541

Week 24953

Month 194370

All 7462210

Currently are 170 guests and no members online

Kubik-Rubik Joomla! Extensions

Latest comments