| 1028 | if (pos < len) { |
| 1029 | size_t timezonePos = pos; |
| 1030 | while (timezonePos < len && !characterIsSpace(str[timezonePos])) { |
| 1031 | timezonePos++; |
| 1032 | } |
| 1033 | std::string_view timezone(str + pos, timezonePos - pos); |
| 1034 | |
| 1035 | if (timezone.size() > 3) { |
| 1036 | auto opPos = findFirstPlusOrMinus(timezone); |
| 1037 | if (opPos > 0 && opPos != std::string_view::npos) { |
| 1038 | std::set<std::string_view> targets = { |
| 1039 | "UTC", "UCT", "GMT0", "GMT", "UT"}; |
| 1040 | if (matchSubstring(timezone, 0, opPos, targets)) { |
| 1041 | timezone = timezone.substr(opPos); |
| 1042 | } else { |
| 1043 | return std::nullopt; |
| 1044 | } |
| 1045 | } |
| 1046 | } |
| 1047 | |
| 1048 | if ((timezoneID = tz::getTimeZoneID(timezone, false)) == -1) { |
| 1049 | return std::nullopt; |
| 1050 | } |
| 1051 | |
| 1052 | // Skip any spaces at the end. |
| 1053 | pos = timezonePos; |
| 1054 | skipSpaces(str, len, pos); |
| 1055 | |
| 1056 | if (pos < len) { |
| 1057 | return std::nullopt; |
| 1058 | } |
| 1059 | } |
| 1060 | return std::make_pair(resultTimestamp, timezoneID); |
| 1061 | } |
| 1062 | |
| 1063 | namespace { |
| 1064 | CivilDate civilFromDaysSinceEpoch(int64_t daysSinceEpoch) { |
| 1065 | // Algorithm derived from Howard Hinnant's civil calendar conversions. |
| 1066 | // https://howardhinnant.github.io/date_algorithms.html |
| 1067 | // Copyright (c) 2015, 2016 Howard Hinnant |
| 1068 | // |
| 1069 | // This code is licensed under the MIT license. |
| 1070 | // https://github.com/HowardHinnant/date |
| 1071 | int64_t z = daysSinceEpoch + 719468; |
| 1072 | const int64_t era = (z >= 0 ? z : z - 146096) / 146097; |
| 1073 | const uint32_t doe = static_cast<uint32_t>(z - era * 146097); |
| 1074 | const uint32_t yoe = |
| 1075 | (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] |
| 1076 | int64_t y = static_cast<int64_t>(yoe) + era * 400; |
| 1077 | const uint32_t doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] |
| 1078 | const uint32_t mp = (5 * doy + 2) / 153; // [0, 11] |
| 1079 | const uint32_t day = doy - (153 * mp + 2) / 5 + 1; // [1, 31] |
| 1080 | const uint32_t month = mp + (mp < 10 ? 3 : -9); // [1, 12] |
| 1081 | y += (month <= 2); |
| 1082 | return { |
| 1083 | static_cast<int32_t>(y), |
nothing calls this directly
no test coverage detected