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)
32 const char* ts = time.c_str();
34 auto accepted_formats = {
39 for (
auto afmt : accepted_formats)
43 auto sres = strptime(ts, afmt, &t);
44 if (sres != NULL && *sres ==
'\0')
46 auto r = std::chrono::system_clock::from_time_t(timegm(&t));
47 r -= std::chrono::seconds(t.tm_gmtoff);
53 std::vector<std::pair<const char*, int>> more_formats = {
55 {
"%04u-%02u-%02u %02u:%02u:%f %d:%02u", 8},
56 {
"%04u-%02u-%02uT%02u:%02u:%f %d:%02u", 8},
57 {
"%04u-%02u-%02u %02u:%02u:%f %03d %02u", 8},
58 {
"%02u%02u%02u%02u%02u%02f%03d%02u", 8},
59 {
"%04u%02u%02u%02u%02u%02f%03d%02u", 8},
60 {
"%04u-%02u-%02uT%02u:%02u:%f", 6},
61 {
"%04u-%02u-%02u %02u:%02u:%f", 6}};
63 for (
auto [fmt, n] : more_formats)
65 unsigned y = 0, m = 0, d = 0, h = 0, mn = 0, om = 0;
69 int rs = sscanf(ts, fmt, &y, &m, &d, &h, &mn, &s, &oh, &om);
70 if (rs >= 1 && rs == n)
72 using namespace std::chrono;
74 if (strncmp(fmt,
"%02u", 4) == 0)
77 y += y >= 50 ? 1900 : 2000;
82 auto date = year_month_day(year(y), month(m), day(d));
85 !date.ok() || (rs >= 6 && (h > 24 || mn > 60 || s < 0.0)) ||
86 (rs >= 8 && (s > 60.0 || oh < -23 || oh > 23 || om > 60)))
91 system_clock::time_point r = (sys_days)date;
93 r += hours(h) + minutes(mn) + microseconds((
long)(s * 1e6));
95 r -= hours(oh) + minutes(om);
101 throw std::runtime_error(
102 fmt::format(
"'{}' does not match any accepted time format", time));
105 static inline std::string to_x509_time_string(
const std::string& time)
107 return to_x509_time_string(time_point_from_string(time));
Definition contiguous_set.h:12