String format is "YYYY-MM-DD hh:mm:ss.microseconds" (seconds and microseconds are optional). ISO 8601
| 500 | // String format is "YYYY-MM-DD hh:mm:ss.microseconds" (seconds and microseconds |
| 501 | // are optional). ISO 8601 |
| 502 | bool tryParseTimestampString( |
| 503 | const char* buf, |
| 504 | size_t len, |
| 505 | size_t& pos, |
| 506 | Timestamp& result) { |
| 507 | int64_t daysSinceEpoch = 0; |
| 508 | int64_t microsSinceMidnight = 0; |
| 509 | if (tryParseDateString( |
| 510 | buf, |
| 511 | len, |
| 512 | pos, |
| 513 | daysSinceEpoch, |
| 514 | ParseMode::kNonStrict | ParseMode::kNonStandardCast) != |
| 515 | DateParseResult::kSuccess) { |
| 516 | return false; |
| 517 | } |
| 518 | |
| 519 | if (pos == len) { |
| 520 | // No time: only a date. |
| 521 | result = fromDatetime(daysSinceEpoch, 0); |
| 522 | return true; |
| 523 | } |
| 524 | |
| 525 | if (buf[pos] == ' ' || buf[pos] == 'T') { |
| 526 | pos++; |
| 527 | } |
| 528 | |
| 529 | // Try to parse a time field. |
| 530 | size_t timePos = 0; |
| 531 | if (!tryParseTimeString( |
| 532 | buf + pos, |
| 533 | len - pos, |
| 534 | timePos, |
| 535 | microsSinceMidnight, |
| 536 | ParseMode::kNonStrict | ParseMode::kNonStandardCast)) { |
| 537 | // The rest of the string is not a valid time, but it could be relevant to |
| 538 | // the caller (e.g. it could be a time zone), return the date we parsed |
| 539 | // and let them decide what to do with the rest. |
| 540 | result = fromDatetime(daysSinceEpoch, 0); |
| 541 | return true; |
| 542 | } |
| 543 | pos += timePos; |
| 544 | result = fromDatetime(daysSinceEpoch, microsSinceMidnight); |
| 545 | return true; |
| 546 | } |
| 547 | |
| 548 | bool tryParseUTCOffsetString( |
| 549 | const char* buf, |
no test coverage detected