Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create date object in C++?

Tags:

c++

c++-chrono

What is the proper way to create Date object in C++? I want C++ analogy of this python code:

import datetime

x = datetime.date(2020, 5, 17)
delta = datetime.timedelta(days=1)
x = x + delta

I was reading about chrono and found only time_point https://en.cppreference.com/w/cpp/chrono/time_point

but I don't see constructor like this date(year=2020, month=1, day=2)

like image 998
mascai Avatar asked Sep 05 '25 00:09

mascai


1 Answers

chrono doesn't add calendrical support until C++20, and the various implementations are still working on that. Microsoft VC++ is solidly out front and currently shipping the full spec. Otherwise you can use my free, open source library with C++11/14/17 which implements the new chrono calendrical support, except it is in namespace date. I'll describe C++20, just know that if that isn't available to you, there's a workaround for that.

C++20 has two (or more) date types. These are the main two:

  • sys_days
  • year_month_day

sys_days is a chrono::time_point based on system_clock, but with a precision of days. It is actually a type alias for:

time_point<system_clock, days>

All this type does is hold an integral count of days after 1970-01-01 (or before for negative values). This makes it very efficient at day-oriented arithmetic. It is also good at converting to a date-time type, which is just any system_clock-based-time_point with a precision finer than days, such as system_clock::time_point (typically microseconds to nanoseconds precision).

year_month_day is a {year, month, day} data structure. It is very good at year and month arithmetic. And it has very efficient access to the year, month and day fields.

One can implicitly convert between sys_days and year_month_day, in either direction, with no information loss.

year_month_day ymd = ...;  // some date
sys_days       sd = ymd;   // the same date in a different data structure
ymd = sd;                  // round trip - no change in value

One can easily create a year_month_day with "conventional syntax", for example:

auto ymd = 2020y/5/17;

ymd has type year_month_day, with the year 2020, the month 5 (or May), and the day 17. The y suffix on 2020 denotes a value of year, and the '/' operators assume the next two integers represent month and day in that order.

Two other orders are permissible: month/day/year and day/month/year. As long as the first field is strongly typed, the following two fields can be either strongly typed, or just int.

auto ymd2 = May/17/2020;  // ymd2 == ymd
auto ymd3 = 17d/5/2020;   // ymd3 == ymd

Your example code can be written:

sys_days x = 2020y/5/17;
x += days{1};
  • The conventional syntax creates a year_month_day which implicitly converts to sys_days.
  • One day is added to the value creating a sys_days equal to 2020y/5/18.

Other date types in C++20 include:

  • local_days : good for keeping the difference between the date local to a time zone, as opposed to UTC.
  • year_month_weekday : good for specifying dates such as the third Sunday of May 2020 (Sunday[3]/May/2020).

One can inter-convert among the various date types, for example:

year_month_day ymd4{Sunday[3]/May/2020};  // ymd4 == ymd
like image 131
Howard Hinnant Avatar answered Sep 07 '25 13:09

Howard Hinnant