| 193 | } |
| 194 | |
| 195 | std::string LocalDateTimeString() { |
| 196 | // Write the local time in RFC3339 format yyyy-mm-ddTHH:MM:SS+/-HH:MM. |
| 197 | typedef std::chrono::system_clock Clock; |
| 198 | std::time_t now = Clock::to_time_t(Clock::now()); |
| 199 | const std::size_t kTzOffsetLen = 6; |
| 200 | const std::size_t kTimestampLen = 19; |
| 201 | |
| 202 | std::size_t tz_len; |
| 203 | std::size_t timestamp_len; |
| 204 | long int offset_minutes; |
| 205 | char tz_offset_sign = '+'; |
| 206 | // tz_offset is set in one of three ways: |
| 207 | // * strftime with %z - This either returns empty or the ISO 8601 time. The |
| 208 | // maximum length an |
| 209 | // ISO 8601 string can be is 7 (e.g. -03:30, plus trailing zero). |
| 210 | // * snprintf with %c%02li:%02li - The maximum length is 41 (one for %c, up to |
| 211 | // 19 for %02li, |
| 212 | // one for :, up to 19 %02li, plus trailing zero). |
| 213 | // * A fixed string of "-00:00". The maximum length is 7 (-00:00, plus |
| 214 | // trailing zero). |
| 215 | // |
| 216 | // Thus, the maximum size this needs to be is 41. |
| 217 | char tz_offset[41]; |
| 218 | // Long enough buffer to avoid format-overflow warnings |
| 219 | char storage[128]; |
| 220 | |
| 221 | #if defined(BENCHMARK_OS_WINDOWS) |
| 222 | std::tm* timeinfo_p = ::localtime(&now); |
| 223 | #else |
| 224 | std::tm timeinfo; |
| 225 | std::tm* timeinfo_p = &timeinfo; |
| 226 | ::localtime_r(&now, &timeinfo); |
| 227 | #endif |
| 228 | |
| 229 | tz_len = std::strftime(tz_offset, sizeof(tz_offset), "%z", timeinfo_p); |
| 230 | |
| 231 | if (tz_len < kTzOffsetLen && tz_len > 1) { |
| 232 | // Timezone offset was written. strftime writes offset as +HHMM or -HHMM, |
| 233 | // RFC3339 specifies an offset as +HH:MM or -HH:MM. To convert, we parse |
| 234 | // the offset as an integer, then reprint it to a string. |
| 235 | |
| 236 | offset_minutes = ::strtol(tz_offset, NULL, 10); |
| 237 | if (offset_minutes < 0) { |
| 238 | offset_minutes *= -1; |
| 239 | tz_offset_sign = '-'; |
| 240 | } |
| 241 | |
| 242 | tz_len = |
| 243 | ::snprintf(tz_offset, sizeof(tz_offset), "%c%02li:%02li", |
| 244 | tz_offset_sign, offset_minutes / 100, offset_minutes % 100); |
| 245 | BM_CHECK(tz_len == kTzOffsetLen); |
| 246 | ((void)tz_len); // Prevent unused variable warning in optimized build. |
| 247 | } else { |
| 248 | // Unknown offset. RFC3339 specifies that unknown local offsets should be |
| 249 | // written as UTC time with -00:00 timezone. |
| 250 | #if defined(BENCHMARK_OS_WINDOWS) |
| 251 | // Potential race condition if another thread calls localtime or gmtime. |
| 252 | timeinfo_p = ::gmtime(&now); |
no outgoing calls
no test coverage detected