If you have c++20, or will use Howard Hinnant date/time library, then Howard Hannant's answer is better, as it gives you a constexpr time_point.
However, if one doesn't yet have c++20 and wants to avoid adding more external libraries, then this answer is still useful.
You can set the members of the std::tm
individually in the initializer, to avoid parsing a string.
// 9th January, 2014
#define DAY 9
#define MONTH 1
#define YEAR 2014
std::tm tm = { /* .tm_sec = */ 0,
/* .tm_min = */ 0,
/* .tm_hour = */ 0,
/* .tm_mday = */ (DAY),
/* .tm_mon = */ (MONTH) - 1,
/* .tm_year = */ (YEAR) - 1900,
};
tm.tm_isdst = -1; // Use DST value from local time zone
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
The designated initializers are commented out since they are only available in C++20 (though gcc has supported trivial designated initializers as an extension for some time and would work with this case). The fields initialized to zero could be omitted if one had full C++20 designated initializers and wanted midnight on the target date.
It is important to note that mktime
will interpret the tm
as local time, not GMT nor UTC. If tm_isdst
is not set to -1, it will be local standard time, even if daylight savings (summer time) would be in use in the local time zone for the time specified.
Producing a UTC time point from a std::tm
, a problem shared with your example, is addressed in other questions, such as Easy way to convert a struct tm (expressed in UTC) to time_t type