in include/ylt/standalone/cinatra/time_util.hpp [104:255]
inline std::pair<bool, std::time_t> get_timestamp(const String &gmt_time_str) {
using namespace time_util;
std::string_view sv(gmt_time_str);
int year, month, day, hour, min, sec, day_of_week;
int len_of_gmt_time_str = (int)gmt_time_str.length();
int len_of_processed_part = 0;
int len_of_ignored_part = 0; // second_decimal_part is ignored
char c;
constexpr std::array<component_of_time_format, 32> real_format =
time_util::get_format<Format>();
if constexpr (Format == time_format::utc_format) {
day_of_week = -1;
}
else if (Format == time_format::utc_without_punctuation_format) {
day_of_week = -1;
}
for (auto &comp : real_format) {
switch (comp) {
case component_of_time_format::ending:
goto travel_done;
break;
case component_of_time_format::colon:
case component_of_time_format::comma:
case component_of_time_format::SP:
case component_of_time_format::hyphen:
case component_of_time_format::dot:
case component_of_time_format::T:
case component_of_time_format::Z:
if (len_of_gmt_time_str - len_of_processed_part < 1) {
return {false, 0};
}
c = sv[len_of_processed_part];
if ((comp == component_of_time_format::Z && c != 'Z') ||
(comp == component_of_time_format::T && c != 'T') ||
(comp == component_of_time_format::dot && c != '.') ||
(comp == component_of_time_format::hyphen && c != '-') ||
(comp == component_of_time_format::SP && c != ' ') ||
(comp == component_of_time_format::colon && c != ':') ||
(comp == component_of_time_format::comma && c != ',')) {
return {false, 0};
}
len_of_processed_part += 1;
break;
case component_of_time_format::year:
if (len_of_gmt_time_str - len_of_processed_part < 4) {
return {false, 0};
}
if ((year = get_digit(sv.substr(len_of_processed_part, 4), 4)) == -1) {
return {false, 0};
}
len_of_processed_part += 4;
break;
case component_of_time_format::month_name:
if (len_of_gmt_time_str - len_of_processed_part < 3) {
return {false, 0};
}
if ((month = get_month_index(sv.substr(len_of_processed_part, 3))) ==
-1) {
return {false, 0};
}
len_of_processed_part += 3;
break;
case component_of_time_format::hour:
case component_of_time_format::minute:
case component_of_time_format::second:
case component_of_time_format::month:
case component_of_time_format::day:
if (len_of_gmt_time_str - len_of_processed_part < 2) {
return {false, 0};
}
int digit;
if ((digit = get_digit(sv.substr(len_of_processed_part, 2), 2)) == -1) {
return {false, 0};
}
if (comp == component_of_time_format::hour) {
hour = digit;
if (hour < 0 || hour >= 24) {
return {false, 0};
}
}
else if (comp == component_of_time_format::minute) {
min = digit;
if (min < 0 || min >= 60) {
return {false, 0};
}
}
else if (comp == component_of_time_format::month) {
month = digit;
if (month < 1 || month > 12) {
return {false, 0};
}
month--;
}
else if (comp == component_of_time_format::second) {
sec = digit;
if (sec < 0 || sec >= 60) {
return {false, 0};
}
}
else {
day = digit;
}
len_of_processed_part += 2;
break;
case component_of_time_format::day_name:
if (len_of_gmt_time_str - len_of_processed_part < 3) {
return {false, 0};
}
if ((day_of_week = get_day_index(sv.substr(len_of_processed_part, 3))) <
0) {
return {false, 0};
}
len_of_processed_part += 3;
break;
case component_of_time_format::GMT:
if (len_of_gmt_time_str - len_of_processed_part < 3) {
return {false, 0};
}
if (sv.substr(len_of_processed_part, 3) != "GMT") {
return {false, 0};
}
len_of_processed_part += 3;
break;
case component_of_time_format::second_decimal_part:
int cur = len_of_processed_part;
while (cur < len_of_gmt_time_str &&
(sv[cur] >= '0' && sv[cur] <= '9')) {
len_of_ignored_part++;
cur++;
}
if (cur == len_of_processed_part) {
return {false, 0};
}
len_of_processed_part = cur;
break;
}
}
travel_done:
if ((len_of_processed_part != len_of_gmt_time_str) ||
(len_of_processed_part != len_of_http_time_format &&
(len_of_processed_part - len_of_ignored_part) !=
len_of_utc_time_format) &&
(len_of_processed_part - len_of_ignored_part) !=
len_of_utc_time_without_punctuation_format) {
return {false, 0};
}
if (day < 1 || day > days_in(month, year)) {
return {false, 0};
}
return faster_mktime(year, month, day, hour, min, sec, day_of_week);
}