* Parse a datetime in yyyy-MM-dd'T'HH:mm:ssZ format * @param str the datetime string * @returns Unix timestamp */
| 138 | * @returns Unix timestamp |
| 139 | */ |
| 140 | inline int64_t parseDateTimeStr(const std::string& str) { |
| 141 | /** |
| 142 | * There is no strptime on Windows. As long as we have to parse a single date format this is not so bad, |
| 143 | * but if multiple formats will have to be supported in the future, it might be worth it to include |
| 144 | * an strptime implementation from some BSD on Windows. |
| 145 | */ |
| 146 | uint32_t year; |
| 147 | uint8_t month; |
| 148 | uint8_t day; |
| 149 | uint8_t hours; |
| 150 | uint8_t minutes; |
| 151 | uint8_t seconds; |
| 152 | int read = 0; |
| 153 | if (sscanf(str.c_str(), "%4u-%2hhu-%2hhuT%2hhu:%2hhu:%2hhuZ%n", &year, &month, &day, &hours, &minutes, &seconds, &read) != 6) { |
| 154 | return -1; |
| 155 | } |
| 156 | // while it is unlikely that read will be < 0, the conditional adds little cost for a little defensiveness. |
| 157 | if (read < 0 || static_cast<size_t>(read) != str.size()) { |
| 158 | return -1; |
| 159 | } |
| 160 | |
| 161 | if (year < 1970U || |
| 162 | month > 12U || |
| 163 | day > 31U || |
| 164 | hours > 23U || |
| 165 | minutes > 59U || |
| 166 | seconds > 60U) { |
| 167 | return -1; |
| 168 | } |
| 169 | |
| 170 | struct tm timeinfo{}; |
| 171 | timeinfo.tm_year = year - 1900; |
| 172 | timeinfo.tm_mon = month - 1; |
| 173 | timeinfo.tm_mday = day; |
| 174 | timeinfo.tm_hour = hours; |
| 175 | timeinfo.tm_min = minutes; |
| 176 | timeinfo.tm_sec = seconds; |
| 177 | timeinfo.tm_isdst = 0; |
| 178 | |
| 179 | return static_cast<int64_t>(mkgmtime(&timeinfo)); |
| 180 | } |
| 181 | |
| 182 | inline bool getDateTimeStr(int64_t unix_timestamp, std::string& date_time_str) { |
| 183 | if (unix_timestamp > (std::numeric_limits<time_t>::max)() || unix_timestamp < (std::numeric_limits<time_t>::lowest)()) { |
no test coverage detected