10static constexpr std::array<std::string_view, 7> days = {
11 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
14static constexpr std::array<std::string_view, 12> months = {
15 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
16 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
19template<
bool FIRST,
unsigned MUL>
20[[nodiscard]]
static constexpr bool parseDigit(
unsigned c, std::integral
auto&
t)
23 if (c > 9)
return false;
24 if constexpr (FIRST) {
50 case 'n': tm.tm_mon = 5;
break;
51 case 'l': tm.tm_mon = 6;
break;
66 case 'r': tm.tm_mon = 2;
break;
67 case 'y': tm.tm_mon = 4;
break;
109 if (!parseDigit<true, 10>(s[8], tm.tm_mday))
return INVALID_TIME_T;
110 if (!parseDigit<false, 1>(s[9], tm.tm_mday))
return INVALID_TIME_T;
117 if (!parseDigit<true, 10>(s[11], tm.tm_hour))
return INVALID_TIME_T;
118 if (!parseDigit<false, 1>(s[12], tm.tm_hour))
return INVALID_TIME_T;
125 if (!parseDigit<true, 10>(s[14], tm.tm_min))
return INVALID_TIME_T;
126 if (!parseDigit<false, 1>(s[15], tm.tm_min))
return INVALID_TIME_T;
133 if (!parseDigit<true, 10>(s[17], tm.tm_sec))
return INVALID_TIME_T;
134 if (!parseDigit<false, 1>(s[18], tm.tm_sec))
return INVALID_TIME_T;
141 if (!parseDigit<true, 1000>(s[20], tm.tm_year))
return INVALID_TIME_T;
142 if (!parseDigit<false, 100>(s[21], tm.tm_year))
return INVALID_TIME_T;
143 if (!parseDigit<false, 10>(s[22], tm.tm_year))
return INVALID_TIME_T;
144 if (!parseDigit<false, 1>(s[23], tm.tm_year))
return INVALID_TIME_T;
154 if (time < 0) time = 0;
155 struct tm* tm = localtime(&time);
156 std::ostringstream sstr;
157 sstr << std::setfill(
'0')
158 << days [tm->tm_wday] <<
' '
159 << months[tm->tm_mon] <<
' '
160 << std::setw(2) << tm->tm_mday <<
' '
161 << std::setw(2) << tm->tm_hour <<
':'
162 << std::setw(2) << tm->tm_min <<
':'
163 << std::setw(2) << tm->tm_sec <<
' '
164 << std::setw(4) << (tm->tm_year + 1900);
std::string toString(time_t time)
time_t fromString(std::span< const char, 24 > s)
constexpr time_t INVALID_TIME_T