16 static inline std::string to_x509_time_string(
const std::tm& time)
20 return fmt::format(
"{:%Y%m%d%H%M%SZ}", time);
23 static inline std::string to_x509_time_string(
24 const std::chrono::system_clock::time_point& time)
26 return to_x509_time_string(fmt::gmtime(time));
29 static inline std::chrono::system_clock::time_point time_point_from_string(
30 const std::string& time)
33 const char* ts = time.c_str();
35 auto accepted_formats = {
40 for (
const auto* afmt : accepted_formats)
44 auto* sres = strptime(ts, afmt, &t);
45 if (sres !=
nullptr && *sres ==
'\0')
47 auto r = std::chrono::system_clock::from_time_t(timegm(&t));
48 r -= std::chrono::seconds(t.tm_gmtoff);
54 std::vector<std::pair<const char*, int>> more_formats = {
56 {
"%04u-%02u-%02u %02u:%02u:%f %d:%02u", 8},
57 {
"%04u-%02u-%02uT%02u:%02u:%f %d:%02u", 8},
58 {
"%04u-%02u-%02u %02u:%02u:%f %03d %02u", 8},
59 {
"%02u%02u%02u%02u%02u%02f%03d%02u", 8},
60 {
"%04u%02u%02u%02u%02u%02f%03d%02u", 8},
61 {
"%04u-%02u-%02uT%02u:%02u:%f", 6},
62 {
"%04u-%02u-%02u %02u:%02u:%f", 6}};
64 for (
auto [fmt, n] : more_formats)
75 int rs = sscanf(ts, fmt, &y, &m, &d, &h, &mn, &s, &oh, &om);
76 if (rs >= 1 && rs == n)
78 using namespace std::chrono;
80 if (strncmp(fmt,
"%02u", 4) == 0)
83 y += y >= 50 ? 1900 : 2000;
88 auto date = year_month_day(year(y), month(m), day(d));
91 !date.ok() || (rs >= 6 && (h > 24 || mn > 60 || s < 0.0)) ||
92 (rs >= 8 && (s > 60.0 || oh < -23 || oh > 23 || om > 60)))
97 system_clock::time_point r = (sys_days)date;
100 r += hours(h) + minutes(mn) + microseconds((
long)(s * 1e6));
104 r -= hours(oh) + minutes(om);
112 throw std::runtime_error(
113 fmt::format(
"'{}' does not match any accepted time format", time));
116 static inline std::string to_x509_time_string(
const std::string& time)
118 return to_x509_time_string(time_point_from_string(time));
Definition contiguous_set.h:12