12#ifndef DOCWIRE_CONVERT_CHRONO_H
13#define DOCWIRE_CONVERT_CHRONO_H
15#include "convert_base.h"
19#include "with_date_format.h"
20#include "convert_numeric.h"
29inline bool try_to_int(std::string_view sv,
int& out)
noexcept
39inline std::optional<std::chrono::sys_seconds> create_sys_seconds(
int year,
int month,
int day,
int hour,
int minute,
int second)
noexcept
41 using namespace std::chrono;
43 const year_month_day ymd{std::chrono::year{year}, std::chrono::month{
static_cast<unsigned>(month)}, std::chrono::day{
static_cast<unsigned>(day)}};
47 if (hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 60)
50 return sys_days{ymd} + hours{hour} + minutes{minute} + seconds{second};
53inline std::optional<std::chrono::sys_seconds> parse_iso8601(std::string_view s)
noexcept
55 int y, m, d, h, min, sec;
57 if (s.length() >= 19 &&
58 try_to_int(s.substr(0, 4), y) && s[4] ==
'-' &&
59 try_to_int(s.substr(5, 2), m) && s[7] ==
'-' &&
60 try_to_int(s.substr(8, 2), d) && s[10] ==
'T' &&
61 try_to_int(s.substr(11, 2), h) && s[13] ==
':' &&
62 try_to_int(s.substr(14, 2), min) && s[16] ==
':' &&
63 try_to_int(s.substr(17, 2), sec))
64 return create_sys_seconds(y, m, d, h, min, sec);
68inline std::optional<std::chrono::sys_seconds> parse_openoffice_legacy(std::string_view s)
noexcept
70 int y, m, d, h, min, sec;
72 if (s.length() >= 17 &&
73 try_to_int(s.substr(0, 4), y) &&
74 try_to_int(s.substr(4, 2), m) &&
75 try_to_int(s.substr(6, 2), d) && s[8] ==
';' &&
76 try_to_int(s.substr(9, 2), h) &&
77 try_to_int(s.substr(11, 2), min) &&
78 try_to_int(s.substr(13, 2), sec))
79 return create_sys_seconds(y, m, d, h, min, sec);
83inline std::optional<std::chrono::sys_seconds> parse_asn1(std::string_view s)
noexcept
85 int y, m, d, h, min, sec;
87 if (s.length() >= 14 &&
88 try_to_int(s.substr(0, 4), y) &&
89 try_to_int(s.substr(4, 2), m) &&
90 try_to_int(s.substr(6, 2), d) &&
91 try_to_int(s.substr(8, 2), h) &&
92 try_to_int(s.substr(10, 2), min) &&
93 try_to_int(s.substr(12, 2), sec))
94 return create_sys_seconds(y, m, d, h, min, sec);
105 DOCWIRE_LOG_SCOPE(s);
106 return detail::parse_iso8601(s.v);
113 DOCWIRE_LOG_SCOPE(s);
114 return detail::parse_openoffice_legacy(s.v);
121 DOCWIRE_LOG_SCOPE(s);
122 return detail::parse_asn1(s.v);
131 auto ymd = std::chrono::year_month_day{std::chrono::floor<std::chrono::days>(tp)};
132 auto time = std::chrono::hh_mm_ss{tp - std::chrono::floor<std::chrono::days>(tp)};
134 auto to_string_padded = [](
int value) {
135 return (value < 10 ?
"0" :
"") + std::to_string(value);
138 return std::to_string(
static_cast<int>(ymd.year())) +
'-' +
139 to_string_padded(
static_cast<unsigned>(ymd.month())) +
'-' +
140 to_string_padded(
static_cast<unsigned>(ymd.day())) +
' ' +
141 to_string_padded(time.hours().count()) +
':' +
142 to_string_padded(time.minutes().count()) +
':' +
143 to_string_padded(time.seconds().count());
Namespace for type conversion utilities.
std::optional< std::chrono::sys_seconds > convert_impl(with::date_format::iso8601 s, dest_type_tag< std::chrono::sys_seconds >) noexcept
Converts an ISO 8601 date string to sys_seconds.
constexpr std::optional< To > try_to(const From &from) noexcept
Tries to convert a value of type From to type To.
A tag type used for dispatching convert_impl overloads based on the destination type.