diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/cctz/src | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/cctz/src')
-rw-r--r-- | contrib/libs/cctz/src/civil_time_detail.cc | 30 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_fixed.cc | 106 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_fixed.h | 10 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_format.cc | 550 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_if.cc | 12 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_if.h | 38 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_impl.cc | 68 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_impl.h | 40 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_info.cc | 602 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_info.h | 38 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_libc.cc | 484 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_libc.h | 14 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_lookup.cc | 192 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_posix.cc | 12 | ||||
-rw-r--r-- | contrib/libs/cctz/src/time_zone_posix.h | 52 | ||||
-rw-r--r-- | contrib/libs/cctz/src/tzfile.h | 32 | ||||
-rw-r--r-- | contrib/libs/cctz/src/zone_info_source.cc | 146 |
17 files changed, 1213 insertions, 1213 deletions
diff --git a/contrib/libs/cctz/src/civil_time_detail.cc b/contrib/libs/cctz/src/civil_time_detail.cc index b6856b8df4..d825298712 100644 --- a/contrib/libs/cctz/src/civil_time_detail.cc +++ b/contrib/libs/cctz/src/civil_time_detail.cc @@ -1,19 +1,19 @@ -// Copyright 2016 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "cctz/civil_time_detail.h" +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "cctz/civil_time_detail.h" + #include <iomanip> #include <ostream> #include <sstream> diff --git a/contrib/libs/cctz/src/time_zone_fixed.cc b/contrib/libs/cctz/src/time_zone_fixed.cc index ce79822ada..6f2f6d6cf5 100644 --- a/contrib/libs/cctz/src/time_zone_fixed.cc +++ b/contrib/libs/cctz/src/time_zone_fixed.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -15,7 +15,7 @@ #include "time_zone_fixed.h" #include <algorithm> -#include <cassert> +#include <cassert> #include <chrono> #include <cstring> #include <string> @@ -25,16 +25,16 @@ namespace cctz { namespace { // The prefix used for the internal names of fixed-offset zones. -const char kFixedZonePrefix[] = "Fixed/UTC"; - -const char kDigits[] = "0123456789"; - -char* Format02d(char* p, int v) { - *p++ = kDigits[(v / 10) % 10]; - *p++ = kDigits[v % 10]; - return p; -} - +const char kFixedZonePrefix[] = "Fixed/UTC"; + +const char kDigits[] = "0123456789"; + +char* Format02d(char* p, int v) { + *p++ = kDigits[(v / 10) % 10]; + *p++ = kDigits[v % 10]; + return p; +} + int Parse02d(const char* p) { if (const char* ap = std::strchr(kDigits, *p)) { int v = static_cast<int>(ap - kDigits); @@ -47,17 +47,17 @@ int Parse02d(const char* p) { } // namespace -bool FixedOffsetFromName(const std::string& name, seconds* offset) { +bool FixedOffsetFromName(const std::string& name, seconds* offset) { if (name.compare(0, std::string::npos, "UTC", 3) == 0) { - *offset = seconds::zero(); + *offset = seconds::zero(); return true; } - const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; - const char* const ep = kFixedZonePrefix + prefix_len; - if (name.size() != prefix_len + 9) // <prefix>+99:99:99 + const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; + const char* const ep = kFixedZonePrefix + prefix_len; + if (name.size() != prefix_len + 9) // <prefix>+99:99:99 return false; - if (!std::equal(kFixedZonePrefix, ep, name.begin())) + if (!std::equal(kFixedZonePrefix, ep, name.begin())) return false; const char* np = name.data() + prefix_len; if (np[0] != '+' && np[0] != '-') @@ -74,57 +74,57 @@ bool FixedOffsetFromName(const std::string& name, seconds* offset) { secs += ((hours * 60) + mins) * 60; if (secs > 24 * 60 * 60) return false; // outside supported offset range - *offset = seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west + *offset = seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west return true; } -std::string FixedOffsetToName(const seconds& offset) { - if (offset == seconds::zero()) return "UTC"; +std::string FixedOffsetToName(const seconds& offset) { + if (offset == seconds::zero()) return "UTC"; if (offset < std::chrono::hours(-24) || offset > std::chrono::hours(24)) { // We don't support fixed-offset zones more than 24 hours // away from UTC to avoid complications in rendering such // offsets and to (somewhat) limit the total number of zones. return "UTC"; } - int offset_seconds = static_cast<int>(offset.count()); - const char sign = (offset_seconds < 0 ? '-' : '+'); - int offset_minutes = offset_seconds / 60; - offset_seconds %= 60; + int offset_seconds = static_cast<int>(offset.count()); + const char sign = (offset_seconds < 0 ? '-' : '+'); + int offset_minutes = offset_seconds / 60; + offset_seconds %= 60; if (sign == '-') { - if (offset_seconds > 0) { - offset_seconds -= 60; - offset_minutes += 1; + if (offset_seconds > 0) { + offset_seconds -= 60; + offset_minutes += 1; } - offset_seconds = -offset_seconds; - offset_minutes = -offset_minutes; + offset_seconds = -offset_seconds; + offset_minutes = -offset_minutes; } - int offset_hours = offset_minutes / 60; - offset_minutes %= 60; - const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; - char buf[prefix_len + sizeof("-24:00:00")]; - char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf); - *ep++ = sign; - ep = Format02d(ep, offset_hours); - *ep++ = ':'; - ep = Format02d(ep, offset_minutes); - *ep++ = ':'; - ep = Format02d(ep, offset_seconds); - *ep++ = '\0'; - assert(ep == buf + sizeof(buf)); + int offset_hours = offset_minutes / 60; + offset_minutes %= 60; + const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; + char buf[prefix_len + sizeof("-24:00:00")]; + char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf); + *ep++ = sign; + ep = Format02d(ep, offset_hours); + *ep++ = ':'; + ep = Format02d(ep, offset_minutes); + *ep++ = ':'; + ep = Format02d(ep, offset_seconds); + *ep++ = '\0'; + assert(ep == buf + sizeof(buf)); return buf; } -std::string FixedOffsetToAbbr(const seconds& offset) { +std::string FixedOffsetToAbbr(const seconds& offset) { std::string abbr = FixedOffsetToName(offset); - const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; - if (abbr.size() == prefix_len + 9) { // <prefix>+99:99:99 - abbr.erase(0, prefix_len); // +99:99:99 - abbr.erase(6, 1); // +99:9999 - abbr.erase(3, 1); // +999999 - if (abbr[5] == '0' && abbr[6] == '0') { // +999900 - abbr.erase(5, 2); // +9999 - if (abbr[3] == '0' && abbr[4] == '0') { // +9900 - abbr.erase(3, 2); // +99 + const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; + if (abbr.size() == prefix_len + 9) { // <prefix>+99:99:99 + abbr.erase(0, prefix_len); // +99:99:99 + abbr.erase(6, 1); // +99:9999 + abbr.erase(3, 1); // +999999 + if (abbr[5] == '0' && abbr[6] == '0') { // +999900 + abbr.erase(5, 2); // +9999 + if (abbr[3] == '0' && abbr[4] == '0') { // +9900 + abbr.erase(3, 2); // +99 } } } diff --git a/contrib/libs/cctz/src/time_zone_fixed.h b/contrib/libs/cctz/src/time_zone_fixed.h index f37226ff46..01210f4788 100644 --- a/contrib/libs/cctz/src/time_zone_fixed.h +++ b/contrib/libs/cctz/src/time_zone_fixed.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,7 @@ #include <string> -#include "cctz/time_zone.h" +#include "cctz/time_zone.h" namespace cctz { @@ -36,9 +36,9 @@ namespace cctz { // Note: FixedOffsetFromName() fails on syntax errors or when the parsed // offset exceeds 24 hours. FixedOffsetToName() and FixedOffsetToAbbr() // both produce "UTC" when the argument offset exceeds 24 hours. -bool FixedOffsetFromName(const std::string& name, seconds* offset); -std::string FixedOffsetToName(const seconds& offset); -std::string FixedOffsetToAbbr(const seconds& offset); +bool FixedOffsetFromName(const std::string& name, seconds* offset); +std::string FixedOffsetToName(const seconds& offset); +std::string FixedOffsetToAbbr(const seconds& offset); } // namespace cctz diff --git a/contrib/libs/cctz/src/time_zone_format.cc b/contrib/libs/cctz/src/time_zone_format.cc index b57371314e..ab3ba55974 100644 --- a/contrib/libs/cctz/src/time_zone_format.cc +++ b/contrib/libs/cctz/src/time_zone_format.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -13,23 +13,23 @@ // limitations under the License. #if !defined(HAS_STRPTIME) -# if !defined(_MSC_VER) && !defined(__MINGW32__) +# if !defined(_MSC_VER) && !defined(__MINGW32__) # define HAS_STRPTIME 1 // assume everyone has strptime() except windows # endif #endif -#if defined(HAS_STRPTIME) && HAS_STRPTIME -# if !defined(_XOPEN_SOURCE) -# define _XOPEN_SOURCE // Definedness suffices for strptime. -# endif -#endif - -#include "cctz/time_zone.h" - -// Include time.h directly since, by C++ standards, ctime doesn't have to -// declare strptime. -#include <time.h> - +#if defined(HAS_STRPTIME) && HAS_STRPTIME +# if !defined(_XOPEN_SOURCE) +# define _XOPEN_SOURCE // Definedness suffices for strptime. +# endif +#endif + +#include "cctz/time_zone.h" + +// Include time.h directly since, by C++ standards, ctime doesn't have to +// declare strptime. +#include <time.h> + #include <cctype> #include <chrono> #include <cstddef> @@ -44,7 +44,7 @@ #include <sstream> #endif -#include "cctz/civil_time.h" +#include "cctz/civil_time.h" #include "time_zone_if.h" namespace cctz { @@ -58,53 +58,53 @@ char* strptime(const char* s, const char* fmt, std::tm* tm) { std::istringstream input(s); input >> std::get_time(tm, fmt); if (input.fail()) return nullptr; - return const_cast<char*>(s) + - (input.eof() ? strlen(s) : static_cast<std::size_t>(input.tellg())); + return const_cast<char*>(s) + + (input.eof() ? strlen(s) : static_cast<std::size_t>(input.tellg())); } #endif -// Convert a cctz::weekday to a tm_wday value (0-6, Sunday = 0). -int ToTmWday(weekday wd) { - switch (wd) { - case weekday::sunday: - return 0; - case weekday::monday: - return 1; - case weekday::tuesday: - return 2; - case weekday::wednesday: - return 3; - case weekday::thursday: - return 4; - case weekday::friday: - return 5; - case weekday::saturday: - return 6; - } - return 0; /*NOTREACHED*/ -} - -// Convert a tm_wday value (0-6, Sunday = 0) to a cctz::weekday. -weekday FromTmWday(int tm_wday) { - switch (tm_wday) { - case 0: - return weekday::sunday; - case 1: - return weekday::monday; - case 2: - return weekday::tuesday; - case 3: - return weekday::wednesday; - case 4: - return weekday::thursday; - case 5: - return weekday::friday; - case 6: - return weekday::saturday; - } - return weekday::sunday; /*NOTREACHED*/ -} - +// Convert a cctz::weekday to a tm_wday value (0-6, Sunday = 0). +int ToTmWday(weekday wd) { + switch (wd) { + case weekday::sunday: + return 0; + case weekday::monday: + return 1; + case weekday::tuesday: + return 2; + case weekday::wednesday: + return 3; + case weekday::thursday: + return 4; + case weekday::friday: + return 5; + case weekday::saturday: + return 6; + } + return 0; /*NOTREACHED*/ +} + +// Convert a tm_wday value (0-6, Sunday = 0) to a cctz::weekday. +weekday FromTmWday(int tm_wday) { + switch (tm_wday) { + case 0: + return weekday::sunday; + case 1: + return weekday::monday; + case 2: + return weekday::tuesday; + case 3: + return weekday::wednesday; + case 4: + return weekday::thursday; + case 5: + return weekday::friday; + case 6: + return weekday::saturday; + } + return weekday::sunday; /*NOTREACHED*/ +} + std::tm ToTM(const time_zone::absolute_lookup& al) { std::tm tm{}; tm.tm_sec = al.cs.second(); @@ -122,19 +122,19 @@ std::tm ToTM(const time_zone::absolute_lookup& al) { tm.tm_year = static_cast<int>(al.cs.year() - 1900); } - tm.tm_wday = ToTmWday(get_weekday(al.cs)); - tm.tm_yday = get_yearday(al.cs) - 1; + tm.tm_wday = ToTmWday(get_weekday(al.cs)); + tm.tm_yday = get_yearday(al.cs) - 1; tm.tm_isdst = al.is_dst ? 1 : 0; return tm; } -// Returns the week of the year [0:53] given a civil day and the day on -// which weeks are defined to start. -int ToWeek(const civil_day& cd, weekday week_start) { - const civil_day d(cd.year() % 400, cd.month(), cd.day()); - return static_cast<int>((d - prev_weekday(civil_year(d), week_start)) / 7); -} - +// Returns the week of the year [0:53] given a civil day and the day on +// which weeks are defined to start. +int ToWeek(const civil_day& cd, weekday week_start) { + const civil_day d(cd.year() % 400, cd.month(), cd.day()); + return static_cast<int>((d - prev_weekday(civil_year(d), week_start)) / 7); +} + const char kDigits[] = "0123456789"; // Formats a 64-bit integer in the given field width. Note that it is up @@ -175,34 +175,34 @@ char* Format02d(char* ep, int v) { } // Formats a UTC offset, like +00:00. -char* FormatOffset(char* ep, int offset, const char* mode) { - // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and - // generate a "negative zero" when we're formatting a zero offset - // as the result of a failed load_time_zone(). +char* FormatOffset(char* ep, int offset, const char* mode) { + // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and + // generate a "negative zero" when we're formatting a zero offset + // as the result of a failed load_time_zone(). char sign = '+'; - if (offset < 0) { - offset = -offset; // bounded by 24h so no overflow + if (offset < 0) { + offset = -offset; // bounded by 24h so no overflow sign = '-'; } - const int seconds = offset % 60; - const int minutes = (offset /= 60) % 60; - const int hours = offset /= 60; - const char sep = mode[0]; - const bool ext = (sep != '\0' && mode[1] == '*'); - const bool ccc = (ext && mode[2] == ':'); - if (ext && (!ccc || seconds != 0)) { - ep = Format02d(ep, seconds); - *--ep = sep; - } else { - // If we're not rendering seconds, sub-minute negative offsets - // should get a positive sign (e.g., offset=-10s => "+00:00"). - if (hours == 0 && minutes == 0) sign = '+'; - } - if (!ccc || minutes != 0 || seconds != 0) { - ep = Format02d(ep, minutes); - if (sep != '\0') *--ep = sep; - } - ep = Format02d(ep, hours); + const int seconds = offset % 60; + const int minutes = (offset /= 60) % 60; + const int hours = offset /= 60; + const char sep = mode[0]; + const bool ext = (sep != '\0' && mode[1] == '*'); + const bool ccc = (ext && mode[2] == ':'); + if (ext && (!ccc || seconds != 0)) { + ep = Format02d(ep, seconds); + *--ep = sep; + } else { + // If we're not rendering seconds, sub-minute negative offsets + // should get a positive sign (e.g., offset=-10s => "+00:00"). + if (hours == 0 && minutes == 0) sign = '+'; + } + if (!ccc || minutes != 0 || seconds != 0) { + ep = Format02d(ep, minutes); + if (sep != '\0') *--ep = sep; + } + ep = Format02d(ep, hours); *--ep = sign; return ep; } @@ -211,7 +211,7 @@ char* FormatOffset(char* ep, int offset, const char* mode) { void FormatTM(std::string* out, const std::string& fmt, const std::tm& tm) { // strftime(3) returns the number of characters placed in the output // array (which may be 0 characters). It also returns 0 to indicate - // an error, like the array wasn't large enough. To accommodate this, + // an error, like the array wasn't large enough. To accommodate this, // the following code grows the buffer size from 2x the format string // length up to 32x. for (std::size_t i = 2; i != 32; i *= 2) { @@ -308,12 +308,12 @@ const std::int_fast64_t kExp10[kDigits10_64 + 1] = { // Uses strftime(3) to format the given Time. The following extended format // specifiers are also supported: // -// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) -// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss) +// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) +// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss) // - %E#S - Seconds with # digits of fractional precision // - %E*S - Seconds with full fractional precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) -// - %ET - The RFC3339 "date-time" separator "T" +// - %ET - The RFC3339 "date-time" separator "T" // // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are // handled internally for performance reasons. strftime(3) is slow due to @@ -326,7 +326,7 @@ const std::int_fast64_t kExp10[kDigits10_64 + 1] = { // not support the tm_gmtoff and tm_zone extensions to std::tm. // // Requires that zero() <= fs < seconds(1). -std::string format(const std::string& format, const time_point<seconds>& tp, +std::string format(const std::string& format, const time_point<seconds>& tp, const detail::femtoseconds& fs, const time_zone& tz) { std::string result; result.reserve(format.size()); // A reasonable guess for the result size. @@ -378,7 +378,7 @@ std::string format(const std::string& format, const time_point<seconds>& tp, if (cur == end || (cur - percent) % 2 == 0) continue; // Simple specifiers that we handle ourselves. - if (strchr("YmdeUuWwHMSzZs%", *cur)) { + if (strchr("YmdeUuWwHMSzZs%", *cur)) { if (cur - 1 != pending) { FormatTM(&result, std::string(pending, cur - 1), tm); } @@ -399,22 +399,22 @@ std::string format(const std::string& format, const time_point<seconds>& tp, if (*cur == 'e' && *bp == '0') *bp = ' '; // for Windows result.append(bp, static_cast<std::size_t>(ep - bp)); break; - case 'U': - bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::sunday)); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; - case 'u': - bp = Format64(ep, 0, tm.tm_wday ? tm.tm_wday : 7); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; - case 'W': - bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::monday)); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; - case 'w': - bp = Format64(ep, 0, tm.tm_wday); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; + case 'U': + bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::sunday)); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; + case 'u': + bp = Format64(ep, 0, tm.tm_wday ? tm.tm_wday : 7); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; + case 'W': + bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::monday)); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; + case 'w': + bp = Format64(ep, 0, tm.tm_wday); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; case 'H': bp = Format02d(ep, al.cs.hour()); result.append(bp, static_cast<std::size_t>(ep - bp)); @@ -428,7 +428,7 @@ std::string format(const std::string& format, const time_point<seconds>& tp, result.append(bp, static_cast<std::size_t>(ep - bp)); break; case 'z': - bp = FormatOffset(ep, al.offset, ""); + bp = FormatOffset(ep, al.offset, ""); result.append(bp, static_cast<std::size_t>(ep - bp)); break; case 'Z': @@ -438,79 +438,79 @@ std::string format(const std::string& format, const time_point<seconds>& tp, bp = Format64(ep, 0, ToUnixSeconds(tp)); result.append(bp, static_cast<std::size_t>(ep - bp)); break; - case '%': - result.push_back('%'); - break; + case '%': + result.push_back('%'); + break; } pending = ++cur; continue; } - // More complex specifiers that we handle ourselves. - if (*cur == ':' && cur + 1 != end) { - if (*(cur + 1) == 'z') { - // Formats %:z. - if (cur - 1 != pending) { - FormatTM(&result, std::string(pending, cur - 1), tm); - } - bp = FormatOffset(ep, al.offset, ":"); - result.append(bp, static_cast<std::size_t>(ep - bp)); - pending = cur += 2; - continue; - } - if (*(cur + 1) == ':' && cur + 2 != end) { - if (*(cur + 2) == 'z') { - // Formats %::z. - if (cur - 1 != pending) { - FormatTM(&result, std::string(pending, cur - 1), tm); - } - bp = FormatOffset(ep, al.offset, ":*"); - result.append(bp, static_cast<std::size_t>(ep - bp)); - pending = cur += 3; - continue; - } - if (*(cur + 2) == ':' && cur + 3 != end) { - if (*(cur + 3) == 'z') { - // Formats %:::z. - if (cur - 1 != pending) { - FormatTM(&result, std::string(pending, cur - 1), tm); - } - bp = FormatOffset(ep, al.offset, ":*:"); - result.append(bp, static_cast<std::size_t>(ep - bp)); - pending = cur += 4; - continue; - } - } - } - } - + // More complex specifiers that we handle ourselves. + if (*cur == ':' && cur + 1 != end) { + if (*(cur + 1) == 'z') { + // Formats %:z. + if (cur - 1 != pending) { + FormatTM(&result, std::string(pending, cur - 1), tm); + } + bp = FormatOffset(ep, al.offset, ":"); + result.append(bp, static_cast<std::size_t>(ep - bp)); + pending = cur += 2; + continue; + } + if (*(cur + 1) == ':' && cur + 2 != end) { + if (*(cur + 2) == 'z') { + // Formats %::z. + if (cur - 1 != pending) { + FormatTM(&result, std::string(pending, cur - 1), tm); + } + bp = FormatOffset(ep, al.offset, ":*"); + result.append(bp, static_cast<std::size_t>(ep - bp)); + pending = cur += 3; + continue; + } + if (*(cur + 2) == ':' && cur + 3 != end) { + if (*(cur + 3) == 'z') { + // Formats %:::z. + if (cur - 1 != pending) { + FormatTM(&result, std::string(pending, cur - 1), tm); + } + bp = FormatOffset(ep, al.offset, ":*:"); + result.append(bp, static_cast<std::size_t>(ep - bp)); + pending = cur += 4; + continue; + } + } + } + } + // Loop if there is no E modifier. if (*cur != 'E' || ++cur == end) continue; // Format our extensions. - if (*cur == 'T') { - // Formats %ET. - if (cur - 2 != pending) { - FormatTM(&result, std::string(pending, cur - 2), tm); - } - result.append("T"); - pending = ++cur; - } else if (*cur == 'z') { + if (*cur == 'T') { + // Formats %ET. + if (cur - 2 != pending) { + FormatTM(&result, std::string(pending, cur - 2), tm); + } + result.append("T"); + pending = ++cur; + } else if (*cur == 'z') { // Formats %Ez. if (cur - 2 != pending) { FormatTM(&result, std::string(pending, cur - 2), tm); } - bp = FormatOffset(ep, al.offset, ":"); + bp = FormatOffset(ep, al.offset, ":"); result.append(bp, static_cast<std::size_t>(ep - bp)); pending = ++cur; - } else if (*cur == '*' && cur + 1 != end && *(cur + 1) == 'z') { - // Formats %E*z. - if (cur - 2 != pending) { - FormatTM(&result, std::string(pending, cur - 2), tm); - } - bp = FormatOffset(ep, al.offset, ":*"); - result.append(bp, static_cast<std::size_t>(ep - bp)); - pending = cur += 2; + } else if (*cur == '*' && cur + 1 != end && *(cur + 1) == 'z') { + // Formats %E*z. + if (cur - 2 != pending) { + FormatTM(&result, std::string(pending, cur - 2), tm); + } + bp = FormatOffset(ep, al.offset, ":*"); + result.append(bp, static_cast<std::size_t>(ep - bp)); + pending = cur += 2; } else if (*cur == '*' && cur + 1 != end && (*(cur + 1) == 'S' || *(cur + 1) == 'f')) { // Formats %E*S or %E*F. @@ -573,32 +573,32 @@ std::string format(const std::string& format, const time_point<seconds>& tp, namespace { -const char* ParseOffset(const char* dp, const char* mode, int* offset) { +const char* ParseOffset(const char* dp, const char* mode, int* offset) { if (dp != nullptr) { - const char first = *dp++; - if (first == '+' || first == '-') { - char sep = mode[0]; + const char first = *dp++; + if (first == '+' || first == '-') { + char sep = mode[0]; int hours = 0; - int minutes = 0; - int seconds = 0; + int minutes = 0; + int seconds = 0; const char* ap = ParseInt(dp, 2, 0, 23, &hours); if (ap != nullptr && ap - dp == 2) { dp = ap; if (sep != '\0' && *ap == sep) ++ap; const char* bp = ParseInt(ap, 2, 0, 59, &minutes); - if (bp != nullptr && bp - ap == 2) { - dp = bp; - if (sep != '\0' && *bp == sep) ++bp; - const char* cp = ParseInt(bp, 2, 0, 59, &seconds); - if (cp != nullptr && cp - bp == 2) dp = cp; - } - *offset = ((hours * 60 + minutes) * 60) + seconds; - if (first == '-') *offset = -*offset; + if (bp != nullptr && bp - ap == 2) { + dp = bp; + if (sep != '\0' && *bp == sep) ++bp; + const char* cp = ParseInt(bp, 2, 0, 59, &seconds); + if (cp != nullptr && cp - bp == 2) dp = cp; + } + *offset = ((hours * 60 + minutes) * 60) + seconds; + if (first == '-') *offset = -*offset; } else { dp = nullptr; } - } else if (first == 'Z' || first == 'z') { // Zulu - *offset = 0; + } else if (first == 'Z' || first == 'z') { // Zulu + *offset = 0; } else { dp = nullptr; } @@ -648,32 +648,32 @@ const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) { return dp; } -// Sets year, tm_mon and tm_mday given the year, week_num, and tm_wday, -// and the day on which weeks are defined to start. Returns false if year -// would need to move outside its bounds. -bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) { - const civil_year y(*year % 400); - civil_day cd = prev_weekday(y, week_start); // week 0 - cd = next_weekday(cd - 1, FromTmWday(tm->tm_wday)) + (week_num * 7); - if (const year_t shift = cd.year() - y.year()) { - if (shift > 0) { - if (*year > std::numeric_limits<year_t>::max() - shift) return false; - } else { - if (*year < std::numeric_limits<year_t>::min() - shift) return false; - } - *year += shift; - } - tm->tm_mon = cd.month() - 1; - tm->tm_mday = cd.day(); - return true; -} - +// Sets year, tm_mon and tm_mday given the year, week_num, and tm_wday, +// and the day on which weeks are defined to start. Returns false if year +// would need to move outside its bounds. +bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) { + const civil_year y(*year % 400); + civil_day cd = prev_weekday(y, week_start); // week 0 + cd = next_weekday(cd - 1, FromTmWday(tm->tm_wday)) + (week_num * 7); + if (const year_t shift = cd.year() - y.year()) { + if (shift > 0) { + if (*year > std::numeric_limits<year_t>::max() - shift) return false; + } else { + if (*year < std::numeric_limits<year_t>::min() - shift) return false; + } + *year += shift; + } + tm->tm_mon = cd.month() - 1; + tm->tm_mday = cd.day(); + return true; +} + } // namespace // Uses strptime(3) to parse the given input. Supports the same extended // format specifiers as format(), although %E#S and %E*S are treated -// identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept -// the same inputs. %ET accepts either 'T' or 't'. +// identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept +// the same inputs. %ET accepts either 'T' or 't'. // // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are // handled internally so that we can normally avoid strptime() altogether @@ -685,7 +685,7 @@ bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) { // We also handle the %z specifier to accommodate platforms that do not // support the tm_gmtoff extension to std::tm. %Z is parsed but ignored. bool parse(const std::string& format, const std::string& input, - const time_zone& tz, time_point<seconds>* sec, + const time_zone& tz, time_point<seconds>* sec, detail::femtoseconds* fs, std::string* err) { // The unparsed input. const char* data = input.c_str(); // NUL terminated @@ -717,8 +717,8 @@ bool parse(const std::string& format, const std::string& input, const char* fmt = format.c_str(); // NUL terminated bool twelve_hour = false; bool afternoon = false; - int week_num = -1; - weekday week_start = weekday::sunday; + int week_num = -1; + weekday week_start = weekday::sunday; bool saw_percent_s = false; std::int_fast64_t percent_s = 0; @@ -757,28 +757,28 @@ bool parse(const std::string& format, const std::string& input, case 'm': data = ParseInt(data, 2, 1, 12, &tm.tm_mon); if (data != nullptr) tm.tm_mon -= 1; - week_num = -1; + week_num = -1; continue; case 'd': - case 'e': + case 'e': data = ParseInt(data, 2, 1, 31, &tm.tm_mday); - week_num = -1; - continue; - case 'U': - data = ParseInt(data, 0, 0, 53, &week_num); - week_start = weekday::sunday; - continue; - case 'W': - data = ParseInt(data, 0, 0, 53, &week_num); - week_start = weekday::monday; - continue; - case 'u': - data = ParseInt(data, 0, 1, 7, &tm.tm_wday); - if (data != nullptr) tm.tm_wday %= 7; - continue; - case 'w': - data = ParseInt(data, 0, 0, 6, &tm.tm_wday); + week_num = -1; continue; + case 'U': + data = ParseInt(data, 0, 0, 53, &week_num); + week_start = weekday::sunday; + continue; + case 'W': + data = ParseInt(data, 0, 0, 53, &week_num); + week_start = weekday::monday; + continue; + case 'u': + data = ParseInt(data, 0, 1, 7, &tm.tm_wday); + if (data != nullptr) tm.tm_wday %= 7; + continue; + case 'w': + data = ParseInt(data, 0, 0, 6, &tm.tm_wday); + continue; case 'H': data = ParseInt(data, 2, 0, 23, &tm.tm_hour); twelve_hour = false; @@ -801,7 +801,7 @@ bool parse(const std::string& format, const std::string& input, twelve_hour = false; break; case 'z': - data = ParseOffset(data, "", &offset); + data = ParseOffset(data, "", &offset); if (data != nullptr) saw_offset = true; continue; case 'Z': // ignored; zone abbreviations are ambiguous @@ -814,36 +814,36 @@ bool parse(const std::string& format, const std::string& input, &percent_s); if (data != nullptr) saw_percent_s = true; continue; - case ':': - if (fmt[0] == 'z' || - (fmt[0] == ':' && - (fmt[1] == 'z' || (fmt[1] == ':' && fmt[2] == 'z')))) { - data = ParseOffset(data, ":", &offset); - if (data != nullptr) saw_offset = true; - fmt += (fmt[0] == 'z') ? 1 : (fmt[1] == 'z') ? 2 : 3; - continue; - } - break; - case '%': - data = (*data == '%' ? data + 1 : nullptr); - continue; + case ':': + if (fmt[0] == 'z' || + (fmt[0] == ':' && + (fmt[1] == 'z' || (fmt[1] == ':' && fmt[2] == 'z')))) { + data = ParseOffset(data, ":", &offset); + if (data != nullptr) saw_offset = true; + fmt += (fmt[0] == 'z') ? 1 : (fmt[1] == 'z') ? 2 : 3; + continue; + } + break; + case '%': + data = (*data == '%' ? data + 1 : nullptr); + continue; case 'E': - if (fmt[0] == 'T') { - if (*data == 'T' || *data == 't') { - ++data; - ++fmt; + if (fmt[0] == 'T') { + if (*data == 'T' || *data == 't') { + ++data; + ++fmt; } else { - data = nullptr; + data = nullptr; } - continue; - } - if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) { - data = ParseOffset(data, ":", &offset); + continue; + } + if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) { + data = ParseOffset(data, ":", &offset); if (data != nullptr) saw_offset = true; - fmt += (fmt[0] == 'z') ? 1 : 2; + fmt += (fmt[0] == 'z') ? 1 : 2; continue; } - if (fmt[0] == '*' && fmt[1] == 'S') { + if (fmt[0] == '*' && fmt[1] == 'S') { data = ParseInt(data, 2, 0, 60, &tm.tm_sec); if (data != nullptr && *data == '.') { data = ParseSubSeconds(data + 1, &subseconds); @@ -851,14 +851,14 @@ bool parse(const std::string& format, const std::string& input, fmt += 2; continue; } - if (fmt[0] == '*' && fmt[1] == 'f') { + if (fmt[0] == '*' && fmt[1] == 'f') { if (data != nullptr && std::isdigit(*data)) { data = ParseSubSeconds(data, &subseconds); } fmt += 2; continue; } - if (fmt[0] == '4' && fmt[1] == 'Y') { + if (fmt[0] == '4' && fmt[1] == 'Y') { const char* bp = data; data = ParseInt(data, 4, year_t{-999}, year_t{9999}, &year); if (data != nullptr) { @@ -908,7 +908,7 @@ bool parse(const std::string& format, const std::string& input, data = ParseTM(data, spec.c_str(), &tm); // If we successfully parsed %p we need to remember whether the result - // was AM or PM so that we can adjust tm_hour before time_zone::lookup(). + // was AM or PM so that we can adjust tm_hour before time_zone::lookup(). // So reparse the input with a known AM hour, and check if it is shifted // to a PM hour. if (spec == "%p" && data != nullptr) { @@ -947,8 +947,8 @@ bool parse(const std::string& format, const std::string& input, return true; } - // If we saw %z, %Ez, or %E*z then we want to interpret the parsed fields - // in UTC and then shift by that offset. Otherwise we want to interpret + // If we saw %z, %Ez, or %E*z then we want to interpret the parsed fields + // in UTC and then shift by that offset. Otherwise we want to interpret // the fields directly in the passed time_zone. time_zone ptz = saw_offset ? utc_time_zone() : tz; @@ -969,14 +969,14 @@ bool parse(const std::string& format, const std::string& input, year += 1900; } - // Compute year, tm.tm_mon and tm.tm_mday if we parsed a week number. - if (week_num != -1) { - if (!FromWeek(week_num, week_start, &year, &tm)) { - if (err != nullptr) *err = "Out-of-range field"; - return false; - } - } - + // Compute year, tm.tm_mon and tm.tm_mday if we parsed a week number. + if (week_num != -1) { + if (!FromWeek(week_num, week_start, &year, &tm)) { + if (err != nullptr) *err = "Out-of-range field"; + return false; + } + } + const int month = tm.tm_mon + 1; civil_second cs(year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); @@ -998,15 +998,15 @@ bool parse(const std::string& format, const std::string& input, const auto tp = ptz.lookup(cs).pre; // Checks for overflow/underflow and returns an error as necessary. - if (tp == time_point<seconds>::max()) { - const auto al = ptz.lookup(time_point<seconds>::max()); + if (tp == time_point<seconds>::max()) { + const auto al = ptz.lookup(time_point<seconds>::max()); if (cs > al.cs) { if (err != nullptr) *err = "Out-of-range field"; return false; } } - if (tp == time_point<seconds>::min()) { - const auto al = ptz.lookup(time_point<seconds>::min()); + if (tp == time_point<seconds>::min()) { + const auto al = ptz.lookup(time_point<seconds>::min()); if (cs < al.cs) { if (err != nullptr) *err = "Out-of-range field"; return false; diff --git a/contrib/libs/cctz/src/time_zone_if.cc b/contrib/libs/cctz/src/time_zone_if.cc index a80dbcd60d..fcf0c1e9f2 100644 --- a/contrib/libs/cctz/src/time_zone_if.cc +++ b/contrib/libs/cctz/src/time_zone_if.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -31,14 +31,14 @@ std::unique_ptr<TimeZoneIf> TimeZoneIf::Load(const std::string& name) { return std::unique_ptr<TimeZoneIf>(tz.release()); } -// Defined out-of-line to avoid emitting a weak vtable in all TUs. -TimeZoneIf::~TimeZoneIf() {} - -time_point<seconds> UnixSecondsToTimePoint(std::int_fast64_t seconds) { +// Defined out-of-line to avoid emitting a weak vtable in all TUs. +TimeZoneIf::~TimeZoneIf() {} + +time_point<seconds> UnixSecondsToTimePoint(std::int_fast64_t seconds) { return FromUnixSeconds(seconds); } -std::int_fast64_t TimePointToUnixSeconds(const time_point<seconds>& tp) { +std::int_fast64_t TimePointToUnixSeconds(const time_point<seconds>& tp) { return ToUnixSeconds(tp); } diff --git a/contrib/libs/cctz/src/time_zone_if.h b/contrib/libs/cctz/src/time_zone_if.h index f925c6c55a..19129cd50c 100644 --- a/contrib/libs/cctz/src/time_zone_if.h +++ b/contrib/libs/cctz/src/time_zone_if.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -20,8 +20,8 @@ #include <memory> #include <string> -#include "cctz/civil_time.h" -#include "cctz/time_zone.h" +#include "cctz/civil_time.h" +#include "cctz/time_zone.h" namespace cctz { @@ -32,35 +32,35 @@ class TimeZoneIf { // A factory function for TimeZoneIf implementations. static std::unique_ptr<TimeZoneIf> Load(const std::string& name); - virtual ~TimeZoneIf(); + virtual ~TimeZoneIf(); virtual time_zone::absolute_lookup BreakTime( - const time_point<seconds>& tp) const = 0; + const time_point<seconds>& tp) const = 0; virtual time_zone::civil_lookup MakeTime( const civil_second& cs) const = 0; - virtual bool NextTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const = 0; - virtual bool PrevTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const = 0; - - virtual std::string Version() const = 0; + virtual bool NextTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const = 0; + virtual bool PrevTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const = 0; + + virtual std::string Version() const = 0; virtual std::string Description() const = 0; protected: TimeZoneIf() {} }; -// Convert between time_point<seconds> and a count of seconds since the -// Unix epoch. We assume that the std::chrono::system_clock and the +// Convert between time_point<seconds> and a count of seconds since the +// Unix epoch. We assume that the std::chrono::system_clock and the // Unix clock are second aligned, but not that they share an epoch. -inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) { - return (tp - std::chrono::time_point_cast<seconds>( - std::chrono::system_clock::from_time_t(0))).count(); +inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) { + return (tp - std::chrono::time_point_cast<seconds>( + std::chrono::system_clock::from_time_t(0))).count(); } -inline time_point<seconds> FromUnixSeconds(std::int_fast64_t t) { - return std::chrono::time_point_cast<seconds>( - std::chrono::system_clock::from_time_t(0)) + seconds(t); +inline time_point<seconds> FromUnixSeconds(std::int_fast64_t t) { + return std::chrono::time_point_cast<seconds>( + std::chrono::system_clock::from_time_t(0)) + seconds(t); } } // namespace cctz diff --git a/contrib/libs/cctz/src/time_zone_impl.cc b/contrib/libs/cctz/src/time_zone_impl.cc index 6e077505c1..d799de39c9 100644 --- a/contrib/libs/cctz/src/time_zone_impl.cc +++ b/contrib/libs/cctz/src/time_zone_impl.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -14,8 +14,8 @@ #include "time_zone_impl.h" -#include <deque> -#include <memory> +#include <deque> +#include <memory> #include <mutex> #include <string> #include <unordered_map> @@ -33,12 +33,12 @@ using TimeZoneImplByName = TimeZoneImplByName* time_zone_map = nullptr; // Mutual exclusion for time_zone_map. -std::mutex& TimeZoneMutex() { - // This mutex is intentionally "leaked" to avoid the static deinitialization - // order fiasco (std::mutex's destructor is not trivial on many platforms). - static std::mutex* time_zone_mutex = new std::mutex; - return *time_zone_mutex; -} +std::mutex& TimeZoneMutex() { + // This mutex is intentionally "leaked" to avoid the static deinitialization + // order fiasco (std::mutex's destructor is not trivial on many platforms). + static std::mutex* time_zone_mutex = new std::mutex; + return *time_zone_mutex; +} } // namespace @@ -47,18 +47,18 @@ time_zone time_zone::Impl::UTC() { } bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { - const Impl* const utc_impl = UTCImpl(); + const Impl* const utc_impl = UTCImpl(); - // Check for UTC (which is never a key in time_zone_map). - auto offset = seconds::zero(); - if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) { + // Check for UTC (which is never a key in time_zone_map). + auto offset = seconds::zero(); + if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) { *tz = time_zone(utc_impl); return true; } - // Check whether the time zone has already been loaded. + // Check whether the time zone has already been loaded. { - std::lock_guard<std::mutex> lock(TimeZoneMutex()); + std::lock_guard<std::mutex> lock(TimeZoneMutex()); if (time_zone_map != nullptr) { TimeZoneImplByName::const_iterator itr = time_zone_map->find(name); if (itr != time_zone_map->end()) { @@ -68,40 +68,40 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { } } - // Load the new time zone (outside the lock). - std::unique_ptr<const Impl> new_impl(new Impl(name)); - - // Add the new time zone to the map. - std::lock_guard<std::mutex> lock(TimeZoneMutex()); + // Load the new time zone (outside the lock). + std::unique_ptr<const Impl> new_impl(new Impl(name)); + + // Add the new time zone to the map. + std::lock_guard<std::mutex> lock(TimeZoneMutex()); if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName; const Impl*& impl = (*time_zone_map)[name]; - if (impl == nullptr) { // this thread won any load race - impl = new_impl->zone_ ? new_impl.release() : utc_impl; + if (impl == nullptr) { // this thread won any load race + impl = new_impl->zone_ ? new_impl.release() : utc_impl; } *tz = time_zone(impl); return impl != utc_impl; } void time_zone::Impl::ClearTimeZoneMapTestOnly() { - std::lock_guard<std::mutex> lock(TimeZoneMutex()); + std::lock_guard<std::mutex> lock(TimeZoneMutex()); if (time_zone_map != nullptr) { - // Existing time_zone::Impl* entries are in the wild, so we can't delete - // them. Instead, we move them to a private container, where they are - // logically unreachable but not "leaked". Future requests will result - // in reloading the data. - static auto* cleared = new std::deque<const time_zone::Impl*>; - for (const auto& element : *time_zone_map) { - cleared->push_back(element.second); - } + // Existing time_zone::Impl* entries are in the wild, so we can't delete + // them. Instead, we move them to a private container, where they are + // logically unreachable but not "leaked". Future requests will result + // in reloading the data. + static auto* cleared = new std::deque<const time_zone::Impl*>; + for (const auto& element : *time_zone_map) { + cleared->push_back(element.second); + } time_zone_map->clear(); } } -time_zone::Impl::Impl(const std::string& name) - : name_(name), zone_(TimeZoneIf::Load(name_)) {} +time_zone::Impl::Impl(const std::string& name) + : name_(name), zone_(TimeZoneIf::Load(name_)) {} const time_zone::Impl* time_zone::Impl::UTCImpl() { - static const Impl* utc_impl = new Impl("UTC"); // never fails + static const Impl* utc_impl = new Impl("UTC"); // never fails return utc_impl; } diff --git a/contrib/libs/cctz/src/time_zone_impl.h b/contrib/libs/cctz/src/time_zone_impl.h index 23fcddb690..0a9a8af36f 100644 --- a/contrib/libs/cctz/src/time_zone_impl.h +++ b/contrib/libs/cctz/src/time_zone_impl.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -18,8 +18,8 @@ #include <memory> #include <string> -#include "cctz/civil_time.h" -#include "cctz/time_zone.h" +#include "cctz/civil_time.h" +#include "cctz/time_zone.h" #include "time_zone_if.h" #include "time_zone_info.h" @@ -40,13 +40,13 @@ class time_zone::Impl { static void ClearTimeZoneMapTestOnly(); // The primary key is the time-zone ID (e.g., "America/New_York"). - const std::string& Name() const { - // TODO: It would nice if the zoneinfo data included the zone name. - return name_; - } + const std::string& Name() const { + // TODO: It would nice if the zoneinfo data included the zone name. + return name_; + } // Breaks a time_point down to civil-time components in this time zone. - time_zone::absolute_lookup BreakTime(const time_point<seconds>& tp) const { + time_zone::absolute_lookup BreakTime(const time_point<seconds>& tp) const { return zone_->BreakTime(tp); } @@ -58,21 +58,21 @@ class time_zone::Impl { } // Finds the time of the next/previous offset change in this time zone. - bool NextTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const { - return zone_->NextTransition(tp, trans); + bool NextTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { + return zone_->NextTransition(tp, trans); } - bool PrevTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const { - return zone_->PrevTransition(tp, trans); + bool PrevTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { + return zone_->PrevTransition(tp, trans); } - // Returns an implementation-defined version string for this time zone. - std::string Version() const { return zone_->Version(); } - - // Returns an implementation-defined description of this time zone. - std::string Description() const { return zone_->Description(); } - + // Returns an implementation-defined version string for this time zone. + std::string Version() const { return zone_->Version(); } + + // Returns an implementation-defined description of this time zone. + std::string Description() const { return zone_->Description(); } + private: explicit Impl(const std::string& name); static const Impl* UTCImpl(); diff --git a/contrib/libs/cctz/src/time_zone_info.cc b/contrib/libs/cctz/src/time_zone_info.cc index 1b3dc15cf1..4f8c242e6c 100644 --- a/contrib/libs/cctz/src/time_zone_info.cc +++ b/contrib/libs/cctz/src/time_zone_info.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -25,7 +25,7 @@ // a grain of salt. // // For more information see tzfile(5), http://www.iana.org/time-zones, or -// https://en.wikipedia.org/wiki/Zoneinfo. +// https://en.wikipedia.org/wiki/Zoneinfo. // // Note that we assume the proleptic Gregorian calendar and 60-second // minutes throughout. @@ -44,7 +44,7 @@ #include <sstream> #include <string> -#include "cctz/civil_time.h" +#include "cctz/civil_time.h" #include "time_zone_fixed.h" #include "time_zone_posix.h" @@ -52,7 +52,7 @@ namespace cctz { namespace { -inline bool IsLeap(year_t year) { +inline bool IsLeap(year_t year) { return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0); } @@ -78,27 +78,27 @@ const std::int_least32_t kSecsPerYear[2] = { 366 * kSecsPerDay, }; -// Convert a cctz::weekday to a POSIX TZ weekday number (0==Sun, ..., 6=Sat). -inline int ToPosixWeekday(weekday wd) { - switch (wd) { - case weekday::sunday: - return 0; - case weekday::monday: - return 1; - case weekday::tuesday: - return 2; - case weekday::wednesday: - return 3; - case weekday::thursday: - return 4; - case weekday::friday: - return 5; - case weekday::saturday: - return 6; - } - return 0; /*NOTREACHED*/ -} - +// Convert a cctz::weekday to a POSIX TZ weekday number (0==Sun, ..., 6=Sat). +inline int ToPosixWeekday(weekday wd) { + switch (wd) { + case weekday::sunday: + return 0; + case weekday::monday: + return 1; + case weekday::tuesday: + return 2; + case weekday::wednesday: + return 3; + case weekday::thursday: + return 4; + case weekday::friday: + return 5; + case weekday::saturday: + return 6; + } + return 0; /*NOTREACHED*/ +} + // Single-byte, unsigned numeric values are encoded directly. inline std::uint_fast8_t Decode8(const char* cp) { return static_cast<std::uint_fast8_t>(*cp) & 0xff; @@ -158,7 +158,7 @@ std::int_fast64_t TransOffset(bool leap_year, int jan1_weekday, return (days * kSecsPerDay) + pt.time.offset; } -inline time_zone::civil_lookup MakeUnique(const time_point<seconds>& tp) { +inline time_zone::civil_lookup MakeUnique(const time_point<seconds>& tp) { time_zone::civil_lookup cl; cl.kind = time_zone::civil_lookup::UNIQUE; cl.pre = cl.trans = cl.post = tp; @@ -189,7 +189,7 @@ inline time_zone::civil_lookup MakeRepeated(const Transition& tr, return cl; } -inline civil_second YearShift(const civil_second& cs, year_t shift) { +inline civil_second YearShift(const civil_second& cs, year_t shift) { return civil_second(cs.year() + shift, cs.month(), cs.day(), cs.hour(), cs.minute(), cs.second()); } @@ -197,20 +197,20 @@ inline civil_second YearShift(const civil_second& cs, year_t shift) { } // namespace // What (no leap-seconds) UTC+seconds zoneinfo would look like. -bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { +bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { transition_types_.resize(1); TransitionType& tt(transition_types_.back()); tt.utc_offset = static_cast<std::int_least32_t>(offset.count()); tt.is_dst = false; tt.abbr_index = 0; - // We temporarily add some redundant, contemporary (2015 through 2025) + // We temporarily add some redundant, contemporary (2015 through 2025) // transitions for performance reasons. See TimeZoneInfo::LocalTime(). // TODO: Fix the performance issue and remove the extra transitions. transitions_.clear(); transitions_.reserve(12); for (const std::int_fast64_t unix_time : { - -(1LL << 59), // a "first half" transition + -(1LL << 59), // a "first half" transition 1420070400LL, // 2015-01-01T00:00:00+00:00 1451606400LL, // 2016-01-01T00:00:00+00:00 1483228800LL, // 2017-01-01T00:00:00+00:00 @@ -218,10 +218,10 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { 1546300800LL, // 2019-01-01T00:00:00+00:00 1577836800LL, // 2020-01-01T00:00:00+00:00 1609459200LL, // 2021-01-01T00:00:00+00:00 - 1640995200LL, // 2022-01-01T00:00:00+00:00 - 1672531200LL, // 2023-01-01T00:00:00+00:00 - 1704067200LL, // 2024-01-01T00:00:00+00:00 - 1735689600LL, // 2025-01-01T00:00:00+00:00 + 1640995200LL, // 2022-01-01T00:00:00+00:00 + 1672531200LL, // 2023-01-01T00:00:00+00:00 + 1704067200LL, // 2024-01-01T00:00:00+00:00 + 1735689600LL, // 2025-01-01T00:00:00+00:00 }) { Transition& tr(*transitions_.emplace(transitions_.end())); tr.unix_time = unix_time; @@ -232,12 +232,12 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { default_transition_type_ = 0; abbreviations_ = FixedOffsetToAbbr(offset); - abbreviations_.append(1, '\0'); + abbreviations_.append(1, '\0'); future_spec_.clear(); // never needed for a fixed-offset zone extended_ = false; - tt.civil_max = LocalTime(seconds::max().count(), tt).cs; - tt.civil_min = LocalTime(seconds::min().count(), tt).cs; + tt.civil_max = LocalTime(seconds::max().count(), tt).cs; + tt.civil_min = LocalTime(seconds::min().count(), tt).cs; transitions_.shrink_to_fit(); return true; @@ -256,8 +256,8 @@ bool TimeZoneInfo::Header::Build(const tzhead& tzh) { leapcnt = static_cast<std::size_t>(v); if ((v = Decode32(tzh.tzh_ttisstdcnt)) < 0) return false; ttisstdcnt = static_cast<std::size_t>(v); - if ((v = Decode32(tzh.tzh_ttisutcnt)) < 0) return false; - ttisutcnt = static_cast<std::size_t>(v); + if ((v = Decode32(tzh.tzh_ttisutcnt)) < 0) return false; + ttisutcnt = static_cast<std::size_t>(v); return true; } @@ -270,7 +270,7 @@ std::size_t TimeZoneInfo::Header::DataLength(std::size_t time_len) const { len += 1 * charcnt; // abbreviations len += (time_len + 4) * leapcnt; // leap-time + TAI-UTC len += 1 * ttisstdcnt; // UTC/local indicators - len += 1 * ttisutcnt; // standard/wall indicators + len += 1 * ttisutcnt; // standard/wall indicators return len; } @@ -282,108 +282,108 @@ bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index, if (tt1_index == tt2_index) return true; const TransitionType& tt1(transition_types_[tt1_index]); const TransitionType& tt2(transition_types_[tt2_index]); - if (tt1.utc_offset != tt2.utc_offset) return false; + if (tt1.utc_offset != tt2.utc_offset) return false; if (tt1.is_dst != tt2.is_dst) return false; if (tt1.abbr_index != tt2.abbr_index) return false; return true; } -// Find/make a transition type with these attributes. -bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, - const std::string& abbr, - std::uint_least8_t* index) { - std::size_t type_index = 0; - std::size_t abbr_index = abbreviations_.size(); - for (; type_index != transition_types_.size(); ++type_index) { - const TransitionType& tt(transition_types_[type_index]); - const char* tt_abbr = &abbreviations_[tt.abbr_index]; - if (tt_abbr == abbr) abbr_index = tt.abbr_index; - if (tt.utc_offset == utc_offset && tt.is_dst == is_dst) { - if (abbr_index == tt.abbr_index) break; // reuse - } - } - if (type_index > 255 || abbr_index > 255) { - // No index space (8 bits) available for a new type or abbreviation. - return false; - } - if (type_index == transition_types_.size()) { - TransitionType& tt(*transition_types_.emplace(transition_types_.end())); - tt.utc_offset = static_cast<std::int_least32_t>(utc_offset); - tt.is_dst = is_dst; - if (abbr_index == abbreviations_.size()) { - abbreviations_.append(abbr); - abbreviations_.append(1, '\0'); - } - tt.abbr_index = static_cast<std::uint_least8_t>(abbr_index); - } - *index = static_cast<std::uint_least8_t>(type_index); - return true; -} - +// Find/make a transition type with these attributes. +bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, + const std::string& abbr, + std::uint_least8_t* index) { + std::size_t type_index = 0; + std::size_t abbr_index = abbreviations_.size(); + for (; type_index != transition_types_.size(); ++type_index) { + const TransitionType& tt(transition_types_[type_index]); + const char* tt_abbr = &abbreviations_[tt.abbr_index]; + if (tt_abbr == abbr) abbr_index = tt.abbr_index; + if (tt.utc_offset == utc_offset && tt.is_dst == is_dst) { + if (abbr_index == tt.abbr_index) break; // reuse + } + } + if (type_index > 255 || abbr_index > 255) { + // No index space (8 bits) available for a new type or abbreviation. + return false; + } + if (type_index == transition_types_.size()) { + TransitionType& tt(*transition_types_.emplace(transition_types_.end())); + tt.utc_offset = static_cast<std::int_least32_t>(utc_offset); + tt.is_dst = is_dst; + if (abbr_index == abbreviations_.size()) { + abbreviations_.append(abbr); + abbreviations_.append(1, '\0'); + } + tt.abbr_index = static_cast<std::uint_least8_t>(abbr_index); + } + *index = static_cast<std::uint_least8_t>(type_index); + return true; +} + // Use the POSIX-TZ-environment-variable-style string to handle times // in years after the last transition stored in the zoneinfo data. -bool TimeZoneInfo::ExtendTransitions() { +bool TimeZoneInfo::ExtendTransitions() { extended_ = false; - if (future_spec_.empty()) return true; // last transition prevails + if (future_spec_.empty()) return true; // last transition prevails PosixTimeZone posix; - if (!ParsePosixSpec(future_spec_, &posix)) return false; + if (!ParsePosixSpec(future_spec_, &posix)) return false; - // Find transition type for the future std specification. - std::uint_least8_t std_ti; - if (!GetTransitionType(posix.std_offset, false, posix.std_abbr, &std_ti)) - return false; + // Find transition type for the future std specification. + std::uint_least8_t std_ti; + if (!GetTransitionType(posix.std_offset, false, posix.std_abbr, &std_ti)) + return false; - if (posix.dst_abbr.empty()) { // std only - // The future specification should match the last transition, and - // that means that handling the future will fall out naturally. - return EquivTransitions(transitions_.back().type_index, std_ti); + if (posix.dst_abbr.empty()) { // std only + // The future specification should match the last transition, and + // that means that handling the future will fall out naturally. + return EquivTransitions(transitions_.back().type_index, std_ti); } - // Find transition type for the future dst specification. - std::uint_least8_t dst_ti; - if (!GetTransitionType(posix.dst_offset, true, posix.dst_abbr, &dst_ti)) - return false; + // Find transition type for the future dst specification. + std::uint_least8_t dst_ti; + if (!GetTransitionType(posix.dst_offset, true, posix.dst_abbr, &dst_ti)) + return false; // Extend the transitions for an additional 400 years using the // future specification. Years beyond those can be handled by // mapping back to a cycle-equivalent year within that range. - // We may need two additional transitions for the current year. - transitions_.reserve(transitions_.size() + 400 * 2 + 2); + // We may need two additional transitions for the current year. + transitions_.reserve(transitions_.size() + 400 * 2 + 2); extended_ = true; - const Transition& last(transitions_.back()); - const std::int_fast64_t last_time = last.unix_time; - const TransitionType& last_tt(transition_types_[last.type_index]); - last_year_ = LocalTime(last_time, last_tt).cs.year(); - bool leap_year = IsLeap(last_year_); - const civil_second jan1(last_year_); - std::int_fast64_t jan1_time = jan1 - civil_second(); - int jan1_weekday = ToPosixWeekday(get_weekday(jan1)); - - Transition dst = {0, dst_ti, civil_second(), civil_second()}; - Transition std = {0, std_ti, civil_second(), civil_second()}; - for (const year_t limit = last_year_ + 400;; ++last_year_) { - auto dst_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_start); - auto std_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_end); - dst.unix_time = jan1_time + dst_trans_off - posix.std_offset; - std.unix_time = jan1_time + std_trans_off - posix.dst_offset; - const auto* ta = dst.unix_time < std.unix_time ? &dst : &std; - const auto* tb = dst.unix_time < std.unix_time ? &std : &dst; - if (last_time < tb->unix_time) { - if (last_time < ta->unix_time) transitions_.push_back(*ta); - transitions_.push_back(*tb); - } - if (last_year_ == limit) break; + const Transition& last(transitions_.back()); + const std::int_fast64_t last_time = last.unix_time; + const TransitionType& last_tt(transition_types_[last.type_index]); + last_year_ = LocalTime(last_time, last_tt).cs.year(); + bool leap_year = IsLeap(last_year_); + const civil_second jan1(last_year_); + std::int_fast64_t jan1_time = jan1 - civil_second(); + int jan1_weekday = ToPosixWeekday(get_weekday(jan1)); + + Transition dst = {0, dst_ti, civil_second(), civil_second()}; + Transition std = {0, std_ti, civil_second(), civil_second()}; + for (const year_t limit = last_year_ + 400;; ++last_year_) { + auto dst_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_start); + auto std_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_end); + dst.unix_time = jan1_time + dst_trans_off - posix.std_offset; + std.unix_time = jan1_time + std_trans_off - posix.dst_offset; + const auto* ta = dst.unix_time < std.unix_time ? &dst : &std; + const auto* tb = dst.unix_time < std.unix_time ? &std : &dst; + if (last_time < tb->unix_time) { + if (last_time < ta->unix_time) transitions_.push_back(*ta); + transitions_.push_back(*tb); + } + if (last_year_ == limit) break; jan1_time += kSecsPerYear[leap_year]; jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7; - leap_year = !leap_year && IsLeap(last_year_ + 1); + leap_year = !leap_year && IsLeap(last_year_ + 1); } - - return true; + + return true; } -bool TimeZoneInfo::Load(ZoneInfoSource* zip) { +bool TimeZoneInfo::Load(ZoneInfoSource* zip) { // Read and validate the header. tzhead tzh; if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) @@ -420,7 +420,7 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { } if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt) return false; - if (hdr.ttisutcnt != 0 && hdr.ttisutcnt != hdr.typecnt) + if (hdr.ttisutcnt != 0 && hdr.ttisutcnt != hdr.typecnt) return false; // Read the data into a local buffer. @@ -431,7 +431,7 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { const char* bp = tbuf.data(); // Decode and validate the transitions. - transitions_.reserve(hdr.timecnt + 2); + transitions_.reserve(hdr.timecnt + 2); transitions_.resize(hdr.timecnt); for (std::size_t i = 0; i != hdr.timecnt; ++i) { transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp); @@ -452,7 +452,7 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { } // Decode and validate the transition types. - transition_types_.reserve(hdr.typecnt + 2); + transition_types_.reserve(hdr.typecnt + 2); transition_types_.resize(hdr.typecnt); for (std::size_t i = 0; i != hdr.typecnt; ++i) { transition_types_[i].utc_offset = @@ -483,7 +483,7 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { } // Copy all the abbreviations. - abbreviations_.reserve(hdr.charcnt + 10); + abbreviations_.reserve(hdr.charcnt + 10); abbreviations_.assign(bp, hdr.charcnt); bp += hdr.charcnt; @@ -493,16 +493,16 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { // that isn't the case here (see "zic -p"). bp += (8 + 4) * hdr.leapcnt; // leap-time + TAI-UTC bp += 1 * hdr.ttisstdcnt; // UTC/local indicators - bp += 1 * hdr.ttisutcnt; // standard/wall indicators + bp += 1 * hdr.ttisutcnt; // standard/wall indicators assert(bp == tbuf.data() + tbuf.size()); future_spec_.clear(); if (tzh.tzh_version[0] != '\0') { // Snarf up the NL-enclosed future POSIX spec. Note // that version '3' files utilize an extended format. - auto get_char = [](ZoneInfoSource* azip) -> int { + auto get_char = [](ZoneInfoSource* azip) -> int { unsigned char ch; // all non-EOF results are positive - return (azip->Read(&ch, 1) == 1) ? ch : EOF; + return (azip->Read(&ch, 1) == 1) ? ch : EOF; }; if (get_char(zip) != '\n') return false; @@ -515,13 +515,13 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { // We don't check for EOF so that we're forwards compatible. - // If we did not find version information during the standard loading - // process (as of tzh_version '3' that is unsupported), then ask the - // ZoneInfoSource for any out-of-bound version string it may be privy to. - if (version_.empty()) { - version_ = zip->Version(); - } - + // If we did not find version information during the standard loading + // process (as of tzh_version '3' that is unsupported), then ask the + // ZoneInfoSource for any out-of-bound version string it may be privy to. + if (version_.empty()) { + version_ = zip->Version(); + } + // Trim redundant transitions. zic may have added these to work around // differences between the glibc and reference implementations (see // zic.c:dontmerge) and the Qt library (see zic.c:WORK_AROUND_QTBUG_53071). @@ -536,31 +536,31 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { transitions_.resize(hdr.timecnt); // Ensure that there is always a transition in the first half of the - // time line (the second half is handled below) so that the signed - // difference between a civil_second and the civil_second of its - // previous transition is always representable, without overflow. + // time line (the second half is handled below) so that the signed + // difference between a civil_second and the civil_second of its + // previous transition is always representable, without overflow. if (transitions_.empty() || transitions_.front().unix_time >= 0) { Transition& tr(*transitions_.emplace(transitions_.begin())); - tr.unix_time = -(1LL << 59); // -18267312070-10-26T17:01:52+00:00 + tr.unix_time = -(1LL << 59); // -18267312070-10-26T17:01:52+00:00 tr.type_index = default_transition_type_; } // Extend the transitions using the future specification. - if (!ExtendTransitions()) return false; - - // Ensure that there is always a transition in the second half of the - // time line (the first half is handled above) so that the signed - // difference between a civil_second and the civil_second of its - // previous transition is always representable, without overflow. - const Transition& last(transitions_.back()); - if (last.unix_time < 0) { - const std::uint_fast8_t type_index = last.type_index; - Transition& tr(*transitions_.emplace(transitions_.end())); - tr.unix_time = 2147483647; // 2038-01-19T03:14:07+00:00 - tr.type_index = type_index; - } - - // Compute the local civil time for each transition and the preceding + if (!ExtendTransitions()) return false; + + // Ensure that there is always a transition in the second half of the + // time line (the first half is handled above) so that the signed + // difference between a civil_second and the civil_second of its + // previous transition is always representable, without overflow. + const Transition& last(transitions_.back()); + if (last.unix_time < 0) { + const std::uint_fast8_t type_index = last.type_index; + Transition& tr(*transitions_.emplace(transitions_.end())); + tr.unix_time = 2147483647; // 2038-01-19T03:14:07+00:00 + tr.type_index = type_index; + } + + // Compute the local civil time for each transition and the preceding // second. These will be used for reverse conversions in MakeTime(). const TransitionType* ttp = &transition_types_[default_transition_type_]; for (std::size_t i = 0; i != transitions_.size(); ++i) { @@ -578,10 +578,10 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { } // Compute the maximum/minimum civil times that can be converted to a - // time_point<seconds> for each of the zone's transition types. + // time_point<seconds> for each of the zone's transition types. for (auto& tt : transition_types_) { - tt.civil_max = LocalTime(seconds::max().count(), tt).cs; - tt.civil_min = LocalTime(seconds::min().count(), tt).cs; + tt.civil_max = LocalTime(seconds::max().count(), tt).cs; + tt.civil_min = LocalTime(seconds::min().count(), tt).cs; } transitions_.shrink_to_fit(); @@ -590,57 +590,57 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { namespace { -// fopen(3) adaptor. -inline FILE* FOpen(const char* path, const char* mode) { -#if defined(_MSC_VER) - FILE* fp; - if (fopen_s(&fp, path, mode) != 0) fp = nullptr; - return fp; -#else - return fopen(path, mode); // TODO: Enable the close-on-exec flag. -#endif -} - +// fopen(3) adaptor. +inline FILE* FOpen(const char* path, const char* mode) { +#if defined(_MSC_VER) + FILE* fp; + if (fopen_s(&fp, path, mode) != 0) fp = nullptr; + return fp; +#else + return fopen(path, mode); // TODO: Enable the close-on-exec flag. +#endif +} + // A stdio(3)-backed implementation of ZoneInfoSource. class FileZoneInfoSource : public ZoneInfoSource { public: static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); std::size_t Read(void* ptr, std::size_t size) override { - size = std::min(size, len_); - std::size_t nread = fread(ptr, 1, size, fp_.get()); - len_ -= nread; - return nread; + size = std::min(size, len_); + std::size_t nread = fread(ptr, 1, size, fp_.get()); + len_ -= nread; + return nread; } int Skip(std::size_t offset) override { - offset = std::min(offset, len_); - int rc = fseek(fp_.get(), static_cast<long>(offset), SEEK_CUR); - if (rc == 0) len_ -= offset; - return rc; - } - std::string Version() const override { - // TODO: It would nice if the zoneinfo data included the tzdb version. - return std::string(); - } - - protected: - explicit FileZoneInfoSource( - FILE* fp, std::size_t len = std::numeric_limits<std::size_t>::max()) - : fp_(fp, fclose), len_(len) {} - + offset = std::min(offset, len_); + int rc = fseek(fp_.get(), static_cast<long>(offset), SEEK_CUR); + if (rc == 0) len_ -= offset; + return rc; + } + std::string Version() const override { + // TODO: It would nice if the zoneinfo data included the tzdb version. + return std::string(); + } + + protected: + explicit FileZoneInfoSource( + FILE* fp, std::size_t len = std::numeric_limits<std::size_t>::max()) + : fp_(fp, fclose), len_(len) {} + private: - std::unique_ptr<FILE, int(*)(FILE*)> fp_; - std::size_t len_; + std::unique_ptr<FILE, int(*)(FILE*)> fp_; + std::size_t len_; }; std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open( const std::string& name) { // Use of the "file:" prefix is intended for testing purposes only. - const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; + const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; // Map the time-zone name to a path name. std::string path; - if (pos == name.size() || name[pos] != '/') { + if (pos == name.size() || name[pos] != '/') { const char* tzdir = "/usr/share/zoneinfo"; char* tzdir_env = nullptr; #if defined(_MSC_VER) @@ -655,76 +655,76 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open( free(tzdir_env); #endif } - path.append(name, pos, std::string::npos); + path.append(name, pos, std::string::npos); // Open the zoneinfo file. - FILE* fp = FOpen(path.c_str(), "rb"); + FILE* fp = FOpen(path.c_str(), "rb"); if (fp == nullptr) return nullptr; - std::size_t length = 0; - if (fseek(fp, 0, SEEK_END) == 0) { - long offset = ftell(fp); - if (offset >= 0) { - length = static_cast<std::size_t>(offset); - } - rewind(fp); - } - return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(fp, length)); -} - -class AndroidZoneInfoSource : public FileZoneInfoSource { - public: - static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); - std::string Version() const override { return version_; } - - private: - explicit AndroidZoneInfoSource(FILE* fp, std::size_t len, const char* vers) - : FileZoneInfoSource(fp, len), version_(vers) {} - std::string version_; -}; - -std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( - const std::string& name) { - // Use of the "file:" prefix is intended for testing purposes only. - const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; - - // See Android's libc/tzcode/bionic.cpp for additional information. - for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", - "/system/usr/share/zoneinfo/tzdata"}) { - std::unique_ptr<FILE, int (*)(FILE*)> fp(FOpen(tzdata, "rb"), fclose); - if (fp.get() == nullptr) continue; - - char hbuf[24]; // covers header.zonetab_offset too - if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue; - if (strncmp(hbuf, "tzdata", 6) != 0) continue; - const char* vers = (hbuf[11] == '\0') ? hbuf + 6 : ""; - const std::int_fast32_t index_offset = Decode32(hbuf + 12); - const std::int_fast32_t data_offset = Decode32(hbuf + 16); - if (index_offset < 0 || data_offset < index_offset) continue; - if (fseek(fp.get(), static_cast<long>(index_offset), SEEK_SET) != 0) - continue; - - char ebuf[52]; // covers entry.unused too - const std::size_t index_size = - static_cast<std::size_t>(data_offset - index_offset); - const std::size_t zonecnt = index_size / sizeof(ebuf); - if (zonecnt * sizeof(ebuf) != index_size) continue; - for (std::size_t i = 0; i != zonecnt; ++i) { - if (fread(ebuf, 1, sizeof(ebuf), fp.get()) != sizeof(ebuf)) break; - const std::int_fast32_t start = data_offset + Decode32(ebuf + 40); - const std::int_fast32_t length = Decode32(ebuf + 44); - if (start < 0 || length < 0) break; - ebuf[40] = '\0'; // ensure zone name is NUL terminated - if (strcmp(name.c_str() + pos, ebuf) == 0) { - if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break; - return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource( - fp.release(), static_cast<std::size_t>(length), vers)); - } - } - } - - return nullptr; + std::size_t length = 0; + if (fseek(fp, 0, SEEK_END) == 0) { + long offset = ftell(fp); + if (offset >= 0) { + length = static_cast<std::size_t>(offset); + } + rewind(fp); + } + return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(fp, length)); } +class AndroidZoneInfoSource : public FileZoneInfoSource { + public: + static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); + std::string Version() const override { return version_; } + + private: + explicit AndroidZoneInfoSource(FILE* fp, std::size_t len, const char* vers) + : FileZoneInfoSource(fp, len), version_(vers) {} + std::string version_; +}; + +std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( + const std::string& name) { + // Use of the "file:" prefix is intended for testing purposes only. + const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; + + // See Android's libc/tzcode/bionic.cpp for additional information. + for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", + "/system/usr/share/zoneinfo/tzdata"}) { + std::unique_ptr<FILE, int (*)(FILE*)> fp(FOpen(tzdata, "rb"), fclose); + if (fp.get() == nullptr) continue; + + char hbuf[24]; // covers header.zonetab_offset too + if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue; + if (strncmp(hbuf, "tzdata", 6) != 0) continue; + const char* vers = (hbuf[11] == '\0') ? hbuf + 6 : ""; + const std::int_fast32_t index_offset = Decode32(hbuf + 12); + const std::int_fast32_t data_offset = Decode32(hbuf + 16); + if (index_offset < 0 || data_offset < index_offset) continue; + if (fseek(fp.get(), static_cast<long>(index_offset), SEEK_SET) != 0) + continue; + + char ebuf[52]; // covers entry.unused too + const std::size_t index_size = + static_cast<std::size_t>(data_offset - index_offset); + const std::size_t zonecnt = index_size / sizeof(ebuf); + if (zonecnt * sizeof(ebuf) != index_size) continue; + for (std::size_t i = 0; i != zonecnt; ++i) { + if (fread(ebuf, 1, sizeof(ebuf), fp.get()) != sizeof(ebuf)) break; + const std::int_fast32_t start = data_offset + Decode32(ebuf + 40); + const std::int_fast32_t length = Decode32(ebuf + 44); + if (start < 0 || length < 0) break; + ebuf[40] = '\0'; // ensure zone name is NUL terminated + if (strcmp(name.c_str() + pos, ebuf) == 0) { + if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break; + return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource( + fp.release(), static_cast<std::size_t>(length), vers)); + } + } + } + + return nullptr; +} + } // namespace bool TimeZoneInfo::Load(const std::string& name) { @@ -732,19 +732,19 @@ bool TimeZoneInfo::Load(const std::string& name) { // zone never fails because the simple, fixed-offset state can be // internally generated. Note that this depends on our choice to not // accept leap-second encoded ("right") zoneinfo. - auto offset = seconds::zero(); + auto offset = seconds::zero(); if (FixedOffsetFromName(name, &offset)) { return ResetToBuiltinUTC(offset); } // Find and use a ZoneInfoSource to load the named zone. auto zip = cctz_extension::zone_info_source_factory( - name, [](const std::string& n) -> std::unique_ptr<ZoneInfoSource> { - if (auto z = FileZoneInfoSource::Open(n)) return z; - if (auto z = AndroidZoneInfoSource::Open(n)) return z; - return nullptr; + name, [](const std::string& n) -> std::unique_ptr<ZoneInfoSource> { + if (auto z = FileZoneInfoSource::Open(n)) return z; + if (auto z = AndroidZoneInfoSource::Open(n)) return z; + return nullptr; }); - return zip != nullptr && Load(zip.get()); + return zip != nullptr && Load(zip.get()); } // BreakTime() translation for a particular transition type. @@ -769,17 +769,17 @@ time_zone::absolute_lookup TimeZoneInfo::LocalTime( // MakeTime() translation with a conversion-preserving +N * 400-year shift. time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs, - year_t c4_shift) const { + year_t c4_shift) const { assert(last_year_ - 400 < cs.year() && cs.year() <= last_year_); time_zone::civil_lookup cl = MakeTime(cs); - if (c4_shift > seconds::max().count() / kSecsPer400Years) { - cl.pre = cl.trans = cl.post = time_point<seconds>::max(); + if (c4_shift > seconds::max().count() / kSecsPer400Years) { + cl.pre = cl.trans = cl.post = time_point<seconds>::max(); } else { - const auto offset = seconds(c4_shift * kSecsPer400Years); - const auto limit = time_point<seconds>::max() - offset; + const auto offset = seconds(c4_shift * kSecsPer400Years); + const auto limit = time_point<seconds>::max() - offset; for (auto* tp : {&cl.pre, &cl.trans, &cl.post}) { if (*tp > limit) { - *tp = time_point<seconds>::max(); + *tp = time_point<seconds>::max(); } else { *tp += offset; } @@ -789,7 +789,7 @@ time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs, } time_zone::absolute_lookup TimeZoneInfo::BreakTime( - const time_point<seconds>& tp) const { + const time_point<seconds>& tp) const { std::int_fast64_t unix_time = ToUnixSeconds(tp); const std::size_t timecnt = transitions_.size(); assert(timecnt != 0); // We always add a transition. @@ -804,8 +804,8 @@ time_zone::absolute_lookup TimeZoneInfo::BreakTime( if (extended_) { const std::int_fast64_t diff = unix_time - transitions_[timecnt - 1].unix_time; - const year_t shift = diff / kSecsPer400Years + 1; - const auto d = seconds(shift * kSecsPer400Years); + const year_t shift = diff / kSecsPer400Years + 1; + const auto d = seconds(shift * kSecsPer400Years); time_zone::absolute_lookup al = BreakTime(tp - d); al.cs = YearShift(al.cs, shift * 400); return al; @@ -864,7 +864,7 @@ time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const { if (tr->prev_civil_sec >= cs) { // Before first transition, so use the default offset. const TransitionType& tt(transition_types_[default_transition_type_]); - if (cs < tt.civil_min) return MakeUnique(time_point<seconds>::min()); + if (cs < tt.civil_min) return MakeUnique(time_point<seconds>::min()); return MakeUnique(cs - (civil_second() + tt.utc_offset)); } // tr->prev_civil_sec < cs < tr->civil_sec @@ -877,11 +877,11 @@ time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const { // future_spec_, shift back to a supported year using the 400-year // cycle of calendaric equivalence and then compensate accordingly. if (extended_ && cs.year() > last_year_) { - const year_t shift = (cs.year() - last_year_ - 1) / 400 + 1; + const year_t shift = (cs.year() - last_year_ - 1) / 400 + 1; return TimeLocal(YearShift(cs, shift * -400), shift); } const TransitionType& tt(transition_types_[tr->type_index]); - if (cs > tt.civil_max) return MakeUnique(time_point<seconds>::max()); + if (cs > tt.civil_max) return MakeUnique(time_point<seconds>::max()); return MakeUnique(tr->unix_time + (cs - tr->civil_sec)); } // tr->civil_sec <= cs <= tr->prev_civil_sec @@ -902,10 +902,10 @@ time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const { return MakeUnique(tr->unix_time + (cs - tr->civil_sec)); } -std::string TimeZoneInfo::Version() const { - return version_; -} - +std::string TimeZoneInfo::Version() const { + return version_; +} + std::string TimeZoneInfo::Description() const { std::ostringstream oss; oss << "#trans=" << transitions_.size(); @@ -914,64 +914,64 @@ std::string TimeZoneInfo::Description() const { return oss.str(); } -bool TimeZoneInfo::NextTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const { +bool TimeZoneInfo::NextTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { if (transitions_.empty()) return false; const Transition* begin = &transitions_[0]; const Transition* end = begin + transitions_.size(); if (begin->unix_time <= -(1LL << 59)) { - // Do not report the BIG_BANG found in some zoneinfo data as it is - // really a sentinel, not a transition. See pre-2018f tz/zic.c. + // Do not report the BIG_BANG found in some zoneinfo data as it is + // really a sentinel, not a transition. See pre-2018f tz/zic.c. ++begin; } - std::int_fast64_t unix_time = ToUnixSeconds(tp); - const Transition target = {unix_time, 0, civil_second(), civil_second()}; + std::int_fast64_t unix_time = ToUnixSeconds(tp); + const Transition target = {unix_time, 0, civil_second(), civil_second()}; const Transition* tr = std::upper_bound(begin, end, target, Transition::ByUnixTime()); - for (; tr != end; ++tr) { // skip no-op transitions - std::uint_fast8_t prev_type_index = - (tr == begin) ? default_transition_type_ : tr[-1].type_index; - if (!EquivTransitions(prev_type_index, tr[0].type_index)) break; + for (; tr != end; ++tr) { // skip no-op transitions + std::uint_fast8_t prev_type_index = + (tr == begin) ? default_transition_type_ : tr[-1].type_index; + if (!EquivTransitions(prev_type_index, tr[0].type_index)) break; } // When tr == end we return false, ignoring future_spec_. if (tr == end) return false; - trans->from = tr->prev_civil_sec + 1; - trans->to = tr->civil_sec; + trans->from = tr->prev_civil_sec + 1; + trans->to = tr->civil_sec; return true; } -bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const { +bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { if (transitions_.empty()) return false; const Transition* begin = &transitions_[0]; const Transition* end = begin + transitions_.size(); if (begin->unix_time <= -(1LL << 59)) { - // Do not report the BIG_BANG found in some zoneinfo data as it is - // really a sentinel, not a transition. See pre-2018f tz/zic.c. + // Do not report the BIG_BANG found in some zoneinfo data as it is + // really a sentinel, not a transition. See pre-2018f tz/zic.c. ++begin; } - std::int_fast64_t unix_time = ToUnixSeconds(tp); - if (FromUnixSeconds(unix_time) != tp) { + std::int_fast64_t unix_time = ToUnixSeconds(tp); + if (FromUnixSeconds(unix_time) != tp) { if (unix_time == std::numeric_limits<std::int_fast64_t>::max()) { if (end == begin) return false; // Ignore future_spec_. - trans->from = (--end)->prev_civil_sec + 1; - trans->to = end->civil_sec; + trans->from = (--end)->prev_civil_sec + 1; + trans->to = end->civil_sec; return true; } unix_time += 1; // ceils } - const Transition target = {unix_time, 0, civil_second(), civil_second()}; + const Transition target = {unix_time, 0, civil_second(), civil_second()}; const Transition* tr = std::lower_bound(begin, end, target, Transition::ByUnixTime()); - for (; tr != begin; --tr) { // skip no-op transitions - std::uint_fast8_t prev_type_index = - (tr - 1 == begin) ? default_transition_type_ : tr[-2].type_index; - if (!EquivTransitions(prev_type_index, tr[-1].type_index)) break; + for (; tr != begin; --tr) { // skip no-op transitions + std::uint_fast8_t prev_type_index = + (tr - 1 == begin) ? default_transition_type_ : tr[-2].type_index; + if (!EquivTransitions(prev_type_index, tr[-1].type_index)) break; } // When tr == end we return the "last" transition, ignoring future_spec_. if (tr == begin) return false; - trans->from = (--tr)->prev_civil_sec + 1; - trans->to = tr->civil_sec; + trans->from = (--tr)->prev_civil_sec + 1; + trans->to = tr->civil_sec; return true; } diff --git a/contrib/libs/cctz/src/time_zone_info.h b/contrib/libs/cctz/src/time_zone_info.h index 431dc5b71b..c8d1c789f9 100644 --- a/contrib/libs/cctz/src/time_zone_info.h +++ b/contrib/libs/cctz/src/time_zone_info.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -21,9 +21,9 @@ #include <string> #include <vector> -#include "cctz/civil_time.h" -#include "cctz/time_zone.h" -#include "cctz/zone_info_source.h" +#include "cctz/civil_time.h" +#include "cctz/time_zone.h" +#include "cctz/zone_info_source.h" #include "time_zone_if.h" #include "tzfile.h" @@ -69,14 +69,14 @@ class TimeZoneInfo : public TimeZoneIf { // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( - const time_point<seconds>& tp) const override; + const time_point<seconds>& tp) const override; time_zone::civil_lookup MakeTime( const civil_second& cs) const override; - bool NextTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const override; - bool PrevTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const override; - std::string Version() const override; + bool NextTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const override; + bool PrevTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const override; + std::string Version() const override; std::string Description() const override; private: @@ -86,20 +86,20 @@ class TimeZoneInfo : public TimeZoneIf { std::size_t charcnt; // zone abbreviation characters std::size_t leapcnt; // leap seconds (we expect none) std::size_t ttisstdcnt; // UTC/local indicators (unused) - std::size_t ttisutcnt; // standard/wall indicators (unused) + std::size_t ttisutcnt; // standard/wall indicators (unused) bool Build(const tzhead& tzh); std::size_t DataLength(std::size_t time_len) const; }; - bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, - const std::string& abbr, std::uint_least8_t* index); + bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, + const std::string& abbr, std::uint_least8_t* index); bool EquivTransitions(std::uint_fast8_t tt1_index, std::uint_fast8_t tt2_index) const; - bool ExtendTransitions(); + bool ExtendTransitions(); - bool ResetToBuiltinUTC(const seconds& offset); - bool Load(ZoneInfoSource* zip); + bool ResetToBuiltinUTC(const seconds& offset); + bool Load(ZoneInfoSource* zip); // Helpers for BreakTime() and MakeTime(). time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, @@ -107,17 +107,17 @@ class TimeZoneInfo : public TimeZoneIf { time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, const Transition& tr) const; time_zone::civil_lookup TimeLocal(const civil_second& cs, - year_t c4_shift) const; + year_t c4_shift) const; std::vector<Transition> transitions_; // ordered by unix_time and civil_sec std::vector<TransitionType> transition_types_; // distinct transition types std::uint_fast8_t default_transition_type_; // for before first transition std::string abbreviations_; // all the NUL-terminated abbreviations - std::string version_; // the tzdata version if available + std::string version_; // the tzdata version if available std::string future_spec_; // for after the last zic transition bool extended_; // future_spec_ was used to generate transitions - year_t last_year_; // the final year of the generated transitions + year_t last_year_; // the final year of the generated transitions // We remember the transitions found during the last BreakTime() and // MakeTime() calls. If the next request is for the same transition we diff --git a/contrib/libs/cctz/src/time_zone_libc.cc b/contrib/libs/cctz/src/time_zone_libc.cc index f185b957b6..43affa984a 100644 --- a/contrib/libs/cctz/src/time_zone_libc.cc +++ b/contrib/libs/cctz/src/time_zone_libc.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -13,299 +13,299 @@ // limitations under the License. #if defined(_WIN32) || defined(_WIN64) -#define _CRT_SECURE_NO_WARNINGS 1 +#define _CRT_SECURE_NO_WARNINGS 1 #endif #include "time_zone_libc.h" #include <chrono> #include <ctime> -#include <limits> +#include <limits> #include <utility> -#include "cctz/civil_time.h" -#include "cctz/time_zone.h" - -#if defined(_AIX) -extern "C" { - extern long altzone; -} -#endif +#include "cctz/civil_time.h" +#include "cctz/time_zone.h" +#if defined(_AIX) +extern "C" { + extern long altzone; +} +#endif + namespace cctz { namespace { #if defined(_WIN32) || defined(_WIN64) // Uses the globals: '_timezone', '_dstbias' and '_tzname'. -auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + _dstbias) { +auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + _dstbias) { const bool is_dst = tm.tm_isdst > 0; - return _timezone + (is_dst ? _dstbias : 0); + return _timezone + (is_dst ? _dstbias : 0); } -auto tm_zone(const std::tm& tm) -> decltype(_tzname[0]) { - const bool is_dst = tm.tm_isdst > 0; - return _tzname[is_dst]; -} -#elif defined(__sun) || defined(_AIX) +auto tm_zone(const std::tm& tm) -> decltype(_tzname[0]) { + const bool is_dst = tm.tm_isdst > 0; + return _tzname[is_dst]; +} +#elif defined(__sun) || defined(_AIX) // Uses the globals: 'timezone', 'altzone' and 'tzname'. -auto tm_gmtoff(const std::tm& tm) -> decltype(timezone) { - const bool is_dst = tm.tm_isdst > 0; - return is_dst ? altzone : timezone; -} -auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) { +auto tm_gmtoff(const std::tm& tm) -> decltype(timezone) { const bool is_dst = tm.tm_isdst > 0; - return tzname[is_dst]; + return is_dst ? altzone : timezone; } -#elif defined(__native_client__) || defined(__myriad2__) || \ - defined(__EMSCRIPTEN__) +auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) { + const bool is_dst = tm.tm_isdst > 0; + return tzname[is_dst]; +} +#elif defined(__native_client__) || defined(__myriad2__) || \ + defined(__EMSCRIPTEN__) // Uses the globals: 'timezone' and 'tzname'. -auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) { +auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) { const bool is_dst = tm.tm_isdst > 0; - return _timezone + (is_dst ? 60 * 60 : 0); -} -auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) { - const bool is_dst = tm.tm_isdst > 0; - return tzname[is_dst]; -} -#else -// Adapt to different spellings of the struct std::tm extension fields. -#if defined(tm_gmtoff) -auto tm_gmtoff(const std::tm& tm) -> decltype(tm.tm_gmtoff) { - return tm.tm_gmtoff; -} -#elif defined(__tm_gmtoff) -auto tm_gmtoff(const std::tm& tm) -> decltype(tm.__tm_gmtoff) { - return tm.__tm_gmtoff; -} -#else -template <typename T> -auto tm_gmtoff(const T& tm) -> decltype(tm.tm_gmtoff) { - return tm.tm_gmtoff; -} -template <typename T> -auto tm_gmtoff(const T& tm) -> decltype(tm.__tm_gmtoff) { - return tm.__tm_gmtoff; -} -#endif // tm_gmtoff -#if defined(tm_zone) -auto tm_zone(const std::tm& tm) -> decltype(tm.tm_zone) { - return tm.tm_zone; -} -#elif defined(__tm_zone) -auto tm_zone(const std::tm& tm) -> decltype(tm.__tm_zone) { - return tm.__tm_zone; + return _timezone + (is_dst ? 60 * 60 : 0); } +auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) { + const bool is_dst = tm.tm_isdst > 0; + return tzname[is_dst]; +} #else +// Adapt to different spellings of the struct std::tm extension fields. +#if defined(tm_gmtoff) +auto tm_gmtoff(const std::tm& tm) -> decltype(tm.tm_gmtoff) { + return tm.tm_gmtoff; +} +#elif defined(__tm_gmtoff) +auto tm_gmtoff(const std::tm& tm) -> decltype(tm.__tm_gmtoff) { + return tm.__tm_gmtoff; +} +#else template <typename T> -auto tm_zone(const T& tm) -> decltype(tm.tm_zone) { - return tm.tm_zone; +auto tm_gmtoff(const T& tm) -> decltype(tm.tm_gmtoff) { + return tm.tm_gmtoff; } template <typename T> -auto tm_zone(const T& tm) -> decltype(tm.__tm_zone) { - return tm.__tm_zone; +auto tm_gmtoff(const T& tm) -> decltype(tm.__tm_gmtoff) { + return tm.__tm_gmtoff; } -#endif // tm_zone -#endif - -inline std::tm* gm_time(const std::time_t *timep, std::tm *result) { -#if defined(_WIN32) || defined(_WIN64) - return gmtime_s(result, timep) ? nullptr : result; -#else - return gmtime_r(timep, result); +#endif // tm_gmtoff +#if defined(tm_zone) +auto tm_zone(const std::tm& tm) -> decltype(tm.tm_zone) { + return tm.tm_zone; +} +#elif defined(__tm_zone) +auto tm_zone(const std::tm& tm) -> decltype(tm.__tm_zone) { + return tm.__tm_zone; +} +#else +template <typename T> +auto tm_zone(const T& tm) -> decltype(tm.tm_zone) { + return tm.tm_zone; +} +template <typename T> +auto tm_zone(const T& tm) -> decltype(tm.__tm_zone) { + return tm.__tm_zone; +} +#endif // tm_zone #endif -} - -inline std::tm* local_time(const std::time_t *timep, std::tm *result) { -#if defined(_WIN32) || defined(_WIN64) - return localtime_s(result, timep) ? nullptr : result; -#else - return localtime_r(timep, result); -#endif -} - -// Converts a civil second and "dst" flag into a time_t and UTC offset. -// Returns false if time_t cannot represent the requested civil second. -// Caller must have already checked that cs.year() will fit into a tm_year. -bool make_time(const civil_second& cs, int is_dst, std::time_t* t, int* off) { - std::tm tm; - tm.tm_year = static_cast<int>(cs.year() - year_t{1900}); - tm.tm_mon = cs.month() - 1; - tm.tm_mday = cs.day(); - tm.tm_hour = cs.hour(); - tm.tm_min = cs.minute(); - tm.tm_sec = cs.second(); - tm.tm_isdst = is_dst; - *t = std::mktime(&tm); - if (*t == std::time_t{-1}) { - std::tm tm2; - const std::tm* tmp = local_time(t, &tm2); - if (tmp == nullptr || tmp->tm_year != tm.tm_year || - tmp->tm_mon != tm.tm_mon || tmp->tm_mday != tm.tm_mday || - tmp->tm_hour != tm.tm_hour || tmp->tm_min != tm.tm_min || - tmp->tm_sec != tm.tm_sec) { - // A true error (not just one second before the epoch). - return false; - } - } - *off = static_cast<int>(tm_gmtoff(tm)); - return true; -} - -// Find the least time_t in [lo:hi] where local time matches offset, given: -// (1) lo doesn't match, (2) hi does, and (3) there is only one transition. -std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) { - std::tm tm; - while (lo + 1 != hi) { - const std::time_t mid = lo + (hi - lo) / 2; - std::tm* tmp = local_time(&mid, &tm); - if (tmp != nullptr) { - if (tm_gmtoff(*tmp) == offset) { - hi = mid; - } else { - lo = mid; - } - } else { - // If std::tm cannot hold some result we resort to a linear search, - // ignoring all failed conversions. Slow, but never really happens. - while (++lo != hi) { - tmp = local_time(&lo, &tm); - if (tmp != nullptr) { - if (tm_gmtoff(*tmp) == offset) break; - } - } - return lo; - } - } - return hi; -} +inline std::tm* gm_time(const std::time_t *timep, std::tm *result) { +#if defined(_WIN32) || defined(_WIN64) + return gmtime_s(result, timep) ? nullptr : result; +#else + return gmtime_r(timep, result); +#endif +} + +inline std::tm* local_time(const std::time_t *timep, std::tm *result) { +#if defined(_WIN32) || defined(_WIN64) + return localtime_s(result, timep) ? nullptr : result; +#else + return localtime_r(timep, result); +#endif +} + +// Converts a civil second and "dst" flag into a time_t and UTC offset. +// Returns false if time_t cannot represent the requested civil second. +// Caller must have already checked that cs.year() will fit into a tm_year. +bool make_time(const civil_second& cs, int is_dst, std::time_t* t, int* off) { + std::tm tm; + tm.tm_year = static_cast<int>(cs.year() - year_t{1900}); + tm.tm_mon = cs.month() - 1; + tm.tm_mday = cs.day(); + tm.tm_hour = cs.hour(); + tm.tm_min = cs.minute(); + tm.tm_sec = cs.second(); + tm.tm_isdst = is_dst; + *t = std::mktime(&tm); + if (*t == std::time_t{-1}) { + std::tm tm2; + const std::tm* tmp = local_time(t, &tm2); + if (tmp == nullptr || tmp->tm_year != tm.tm_year || + tmp->tm_mon != tm.tm_mon || tmp->tm_mday != tm.tm_mday || + tmp->tm_hour != tm.tm_hour || tmp->tm_min != tm.tm_min || + tmp->tm_sec != tm.tm_sec) { + // A true error (not just one second before the epoch). + return false; + } + } + *off = static_cast<int>(tm_gmtoff(tm)); + return true; +} + +// Find the least time_t in [lo:hi] where local time matches offset, given: +// (1) lo doesn't match, (2) hi does, and (3) there is only one transition. +std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) { + std::tm tm; + while (lo + 1 != hi) { + const std::time_t mid = lo + (hi - lo) / 2; + std::tm* tmp = local_time(&mid, &tm); + if (tmp != nullptr) { + if (tm_gmtoff(*tmp) == offset) { + hi = mid; + } else { + lo = mid; + } + } else { + // If std::tm cannot hold some result we resort to a linear search, + // ignoring all failed conversions. Slow, but never really happens. + while (++lo != hi) { + tmp = local_time(&lo, &tm); + if (tmp != nullptr) { + if (tm_gmtoff(*tmp) == offset) break; + } + } + return lo; + } + } + return hi; +} + } // namespace TimeZoneLibC::TimeZoneLibC(const std::string& name) : local_(name == "localtime") {} time_zone::absolute_lookup TimeZoneLibC::BreakTime( - const time_point<seconds>& tp) const { + const time_point<seconds>& tp) const { time_zone::absolute_lookup al; - al.offset = 0; - al.is_dst = false; - al.abbr = "-00"; - - const std::int_fast64_t s = ToUnixSeconds(tp); - - // If std::time_t cannot hold the input we saturate the output. - if (s < std::numeric_limits<std::time_t>::min()) { - al.cs = civil_second::min(); - return al; - } - if (s > std::numeric_limits<std::time_t>::max()) { - al.cs = civil_second::max(); - return al; - } - - const std::time_t t = static_cast<std::time_t>(s); + al.offset = 0; + al.is_dst = false; + al.abbr = "-00"; + + const std::int_fast64_t s = ToUnixSeconds(tp); + + // If std::time_t cannot hold the input we saturate the output. + if (s < std::numeric_limits<std::time_t>::min()) { + al.cs = civil_second::min(); + return al; + } + if (s > std::numeric_limits<std::time_t>::max()) { + al.cs = civil_second::max(); + return al; + } + + const std::time_t t = static_cast<std::time_t>(s); std::tm tm; - std::tm* tmp = local_ ? local_time(&t, &tm) : gm_time(&t, &tm); - - // If std::tm cannot hold the result we saturate the output. - if (tmp == nullptr) { - al.cs = (s < 0) ? civil_second::min() : civil_second::max(); - return al; + std::tm* tmp = local_ ? local_time(&t, &tm) : gm_time(&t, &tm); + + // If std::tm cannot hold the result we saturate the output. + if (tmp == nullptr) { + al.cs = (s < 0) ? civil_second::min() : civil_second::max(); + return al; } - - const year_t year = tmp->tm_year + year_t{1900}; - al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - al.offset = static_cast<int>(tm_gmtoff(*tmp)); - al.abbr = local_ ? tm_zone(*tmp) : "UTC"; // as expected by cctz - al.is_dst = tmp->tm_isdst > 0; + + const year_t year = tmp->tm_year + year_t{1900}; + al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + al.offset = static_cast<int>(tm_gmtoff(*tmp)); + al.abbr = local_ ? tm_zone(*tmp) : "UTC"; // as expected by cctz + al.is_dst = tmp->tm_isdst > 0; return al; } time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const { - if (!local_) { - // If time_point<seconds> cannot hold the result we saturate. - static const civil_second min_tp_cs = - civil_second() + ToUnixSeconds(time_point<seconds>::min()); - static const civil_second max_tp_cs = - civil_second() + ToUnixSeconds(time_point<seconds>::max()); - const time_point<seconds> tp = - (cs < min_tp_cs) - ? time_point<seconds>::min() - : (cs > max_tp_cs) ? time_point<seconds>::max() - : FromUnixSeconds(cs - civil_second()); - return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; - } - - // If tm_year cannot hold the requested year we saturate the result. - if (cs.year() < 0) { - if (cs.year() < std::numeric_limits<int>::min() + year_t{1900}) { - const time_point<seconds> tp = time_point<seconds>::min(); - return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; - } + if (!local_) { + // If time_point<seconds> cannot hold the result we saturate. + static const civil_second min_tp_cs = + civil_second() + ToUnixSeconds(time_point<seconds>::min()); + static const civil_second max_tp_cs = + civil_second() + ToUnixSeconds(time_point<seconds>::max()); + const time_point<seconds> tp = + (cs < min_tp_cs) + ? time_point<seconds>::min() + : (cs > max_tp_cs) ? time_point<seconds>::max() + : FromUnixSeconds(cs - civil_second()); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + + // If tm_year cannot hold the requested year we saturate the result. + if (cs.year() < 0) { + if (cs.year() < std::numeric_limits<int>::min() + year_t{1900}) { + const time_point<seconds> tp = time_point<seconds>::min(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } } else { - if (cs.year() - year_t{1900} > std::numeric_limits<int>::max()) { - const time_point<seconds> tp = time_point<seconds>::max(); - return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; - } + if (cs.year() - year_t{1900} > std::numeric_limits<int>::max()) { + const time_point<seconds> tp = time_point<seconds>::max(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } } - // We probe with "is_dst" values of 0 and 1 to try to distinguish unique - // civil seconds from skipped or repeated ones. This is not always possible - // however, as the "dst" flag does not change over some offset transitions. - // We are also subject to the vagaries of mktime() implementations. - std::time_t t0, t1; - int offset0, offset1; - if (make_time(cs, 0, &t0, &offset0) && make_time(cs, 1, &t1, &offset1)) { - if (t0 == t1) { - // The civil time was singular (pre == trans == post). - const time_point<seconds> tp = FromUnixSeconds(t0); - return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; - } - - if (t0 > t1) { - std::swap(t0, t1); - std::swap(offset0, offset1); - } - const std::time_t tt = find_trans(t0, t1, offset1); - const time_point<seconds> trans = FromUnixSeconds(tt); - - if (offset0 < offset1) { - // The civil time did not exist (pre >= trans > post). - const time_point<seconds> pre = FromUnixSeconds(t1); - const time_point<seconds> post = FromUnixSeconds(t0); - return {time_zone::civil_lookup::SKIPPED, pre, trans, post}; - } - - // The civil time was ambiguous (pre < trans <= post). - const time_point<seconds> pre = FromUnixSeconds(t0); - const time_point<seconds> post = FromUnixSeconds(t1); - return {time_zone::civil_lookup::REPEATED, pre, trans, post}; - } - - // make_time() failed somehow so we saturate the result. - const time_point<seconds> tp = (cs < civil_second()) - ? time_point<seconds>::min() - : time_point<seconds>::max(); - return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + // We probe with "is_dst" values of 0 and 1 to try to distinguish unique + // civil seconds from skipped or repeated ones. This is not always possible + // however, as the "dst" flag does not change over some offset transitions. + // We are also subject to the vagaries of mktime() implementations. + std::time_t t0, t1; + int offset0, offset1; + if (make_time(cs, 0, &t0, &offset0) && make_time(cs, 1, &t1, &offset1)) { + if (t0 == t1) { + // The civil time was singular (pre == trans == post). + const time_point<seconds> tp = FromUnixSeconds(t0); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + + if (t0 > t1) { + std::swap(t0, t1); + std::swap(offset0, offset1); + } + const std::time_t tt = find_trans(t0, t1, offset1); + const time_point<seconds> trans = FromUnixSeconds(tt); + + if (offset0 < offset1) { + // The civil time did not exist (pre >= trans > post). + const time_point<seconds> pre = FromUnixSeconds(t1); + const time_point<seconds> post = FromUnixSeconds(t0); + return {time_zone::civil_lookup::SKIPPED, pre, trans, post}; + } + + // The civil time was ambiguous (pre < trans <= post). + const time_point<seconds> pre = FromUnixSeconds(t0); + const time_point<seconds> post = FromUnixSeconds(t1); + return {time_zone::civil_lookup::REPEATED, pre, trans, post}; + } + + // make_time() failed somehow so we saturate the result. + const time_point<seconds> tp = (cs < civil_second()) + ? time_point<seconds>::min() + : time_point<seconds>::max(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; } -bool TimeZoneLibC::NextTransition(const time_point<seconds>&, - time_zone::civil_transition*) const { +bool TimeZoneLibC::NextTransition(const time_point<seconds>&, + time_zone::civil_transition*) const { return false; } -bool TimeZoneLibC::PrevTransition(const time_point<seconds>&, - time_zone::civil_transition*) const { +bool TimeZoneLibC::PrevTransition(const time_point<seconds>&, + time_zone::civil_transition*) const { return false; } -std::string TimeZoneLibC::Version() const { - return std::string(); // unknown -} - -std::string TimeZoneLibC::Description() const { - return local_ ? "localtime" : "UTC"; -} - +std::string TimeZoneLibC::Version() const { + return std::string(); // unknown +} + +std::string TimeZoneLibC::Description() const { + return local_ ? "localtime" : "UTC"; +} + } // namespace cctz diff --git a/contrib/libs/cctz/src/time_zone_libc.h b/contrib/libs/cctz/src/time_zone_libc.h index 4cfe6dae31..7723c4289b 100644 --- a/contrib/libs/cctz/src/time_zone_libc.h +++ b/contrib/libs/cctz/src/time_zone_libc.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -30,14 +30,14 @@ class TimeZoneLibC : public TimeZoneIf { // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( - const time_point<seconds>& tp) const override; + const time_point<seconds>& tp) const override; time_zone::civil_lookup MakeTime( const civil_second& cs) const override; - bool NextTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const override; - bool PrevTransition(const time_point<seconds>& tp, - time_zone::civil_transition* trans) const override; - std::string Version() const override; + bool NextTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const override; + bool PrevTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const override; + std::string Version() const override; std::string Description() const override; private: diff --git a/contrib/libs/cctz/src/time_zone_lookup.cc b/contrib/libs/cctz/src/time_zone_lookup.cc index 92eb2ae763..b1c7f922d1 100644 --- a/contrib/libs/cctz/src/time_zone_lookup.cc +++ b/contrib/libs/cctz/src/time_zone_lookup.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -12,20 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "cctz/time_zone.h" - -#if defined(__ANDROID__) -#include <sys/system_properties.h> -#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 -#include <dlfcn.h> -#endif -#endif - -#if defined(__APPLE__) -#include <CoreFoundation/CFTimeZone.h> -#include <vector> -#endif - +#include "cctz/time_zone.h" + +#if defined(__ANDROID__) +#include <sys/system_properties.h> +#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 +#include <dlfcn.h> +#endif +#endif + +#if defined(__APPLE__) +#include <CoreFoundation/CFTimeZone.h> +#include <vector> +#endif + #include <cstdlib> #include <cstring> #include <string> @@ -35,75 +35,75 @@ namespace cctz { -#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21 -namespace { -// Android 'L' removes __system_property_get() from the NDK, however -// it is still a hidden symbol in libc so we use dlsym() to access it. -// See Chromium's base/sys_info_android.cc for a similar example. - -using property_get_func = int (*)(const char*, char*); - -property_get_func LoadSystemPropertyGet() { - int flag = RTLD_LAZY | RTLD_GLOBAL; -#if defined(RTLD_NOLOAD) - flag |= RTLD_NOLOAD; // libc.so should already be resident -#endif - if (void* handle = dlopen("libc.so", flag)) { - void* sym = dlsym(handle, "__system_property_get"); - dlclose(handle); - return reinterpret_cast<property_get_func>(sym); - } - return nullptr; -} - -int __system_property_get(const char* name, char* value) { - static property_get_func system_property_get = LoadSystemPropertyGet(); - return system_property_get ? system_property_get(name, value) : -1; -} - -} // namespace -#endif - +#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21 +namespace { +// Android 'L' removes __system_property_get() from the NDK, however +// it is still a hidden symbol in libc so we use dlsym() to access it. +// See Chromium's base/sys_info_android.cc for a similar example. + +using property_get_func = int (*)(const char*, char*); + +property_get_func LoadSystemPropertyGet() { + int flag = RTLD_LAZY | RTLD_GLOBAL; +#if defined(RTLD_NOLOAD) + flag |= RTLD_NOLOAD; // libc.so should already be resident +#endif + if (void* handle = dlopen("libc.so", flag)) { + void* sym = dlsym(handle, "__system_property_get"); + dlclose(handle); + return reinterpret_cast<property_get_func>(sym); + } + return nullptr; +} + +int __system_property_get(const char* name, char* value) { + static property_get_func system_property_get = LoadSystemPropertyGet(); + return system_property_get ? system_property_get(name, value) : -1; +} + +} // namespace +#endif + std::string time_zone::name() const { - return effective_impl().Name(); + return effective_impl().Name(); } time_zone::absolute_lookup time_zone::lookup( - const time_point<seconds>& tp) const { - return effective_impl().BreakTime(tp); + const time_point<seconds>& tp) const { + return effective_impl().BreakTime(tp); } time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const { - return effective_impl().MakeTime(cs); -} - -bool time_zone::next_transition(const time_point<seconds>& tp, - civil_transition* trans) const { - return effective_impl().NextTransition(tp, trans); -} - -bool time_zone::prev_transition(const time_point<seconds>& tp, - civil_transition* trans) const { - return effective_impl().PrevTransition(tp, trans); -} - -std::string time_zone::version() const { - return effective_impl().Version(); + return effective_impl().MakeTime(cs); } -std::string time_zone::description() const { - return effective_impl().Description(); -} - -const time_zone::Impl& time_zone::effective_impl() const { - if (impl_ == nullptr) { - // Dereferencing an implicit-UTC time_zone is expected to be - // rare, so we don't mind paying a small synchronization cost. - return *time_zone::Impl::UTC().impl_; - } - return *impl_; +bool time_zone::next_transition(const time_point<seconds>& tp, + civil_transition* trans) const { + return effective_impl().NextTransition(tp, trans); } +bool time_zone::prev_transition(const time_point<seconds>& tp, + civil_transition* trans) const { + return effective_impl().PrevTransition(tp, trans); +} + +std::string time_zone::version() const { + return effective_impl().Version(); +} + +std::string time_zone::description() const { + return effective_impl().Description(); +} + +const time_zone::Impl& time_zone::effective_impl() const { + if (impl_ == nullptr) { + // Dereferencing an implicit-UTC time_zone is expected to be + // rare, so we don't mind paying a small synchronization cost. + return *time_zone::Impl::UTC().impl_; + } + return *impl_; +} + bool load_time_zone(const std::string& name, time_zone* tz) { return time_zone::Impl::LoadTimeZone(name, tz); } @@ -112,7 +112,7 @@ time_zone utc_time_zone() { return time_zone::Impl::UTC(); // avoid name lookup } -time_zone fixed_time_zone(const seconds& offset) { +time_zone fixed_time_zone(const seconds& offset) { time_zone tz; load_time_zone(FixedOffsetToName(offset), &tz); return tz; @@ -120,25 +120,25 @@ time_zone fixed_time_zone(const seconds& offset) { time_zone local_time_zone() { const char* zone = ":localtime"; -#if defined(__ANDROID__) - char sysprop[PROP_VALUE_MAX]; - if (__system_property_get("persist.sys.timezone", sysprop) > 0) { - zone = sysprop; - } -#endif -#if defined(__APPLE__) - std::vector<char> buffer; - CFTimeZoneRef tz_default = CFTimeZoneCopyDefault(); - if (CFStringRef tz_name = CFTimeZoneGetName(tz_default)) { - CFStringEncoding encoding = kCFStringEncodingUTF8; - CFIndex length = CFStringGetLength(tz_name); - buffer.resize(CFStringGetMaximumSizeForEncoding(length, encoding) + 1); - if (CFStringGetCString(tz_name, &buffer[0], buffer.size(), encoding)) { - zone = &buffer[0]; - } - } - CFRelease(tz_default); -#endif +#if defined(__ANDROID__) + char sysprop[PROP_VALUE_MAX]; + if (__system_property_get("persist.sys.timezone", sysprop) > 0) { + zone = sysprop; + } +#endif +#if defined(__APPLE__) + std::vector<char> buffer; + CFTimeZoneRef tz_default = CFTimeZoneCopyDefault(); + if (CFStringRef tz_name = CFTimeZoneGetName(tz_default)) { + CFStringEncoding encoding = kCFStringEncodingUTF8; + CFIndex length = CFStringGetLength(tz_name); + buffer.resize(CFStringGetMaximumSizeForEncoding(length, encoding) + 1); + if (CFStringGetCString(tz_name, &buffer[0], buffer.size(), encoding)) { + zone = &buffer[0]; + } + } + CFRelease(tz_default); +#endif // Allow ${TZ} to override to default zone. char* tz_env = nullptr; @@ -174,9 +174,9 @@ time_zone local_time_zone() { time_zone tz; load_time_zone(name, &tz); // Falls back to UTC. - // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and - // arrange for %z to generate "-0000" when we don't know the local - // offset because the load_time_zone() failed and we're using UTC. + // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and + // arrange for %z to generate "-0000" when we don't know the local + // offset because the load_time_zone() failed and we're using UTC. return tz; } diff --git a/contrib/libs/cctz/src/time_zone_posix.cc b/contrib/libs/cctz/src/time_zone_posix.cc index 847db17cbc..88790aa0a0 100644 --- a/contrib/libs/cctz/src/time_zone_posix.cc +++ b/contrib/libs/cctz/src/time_zone_posix.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -98,9 +98,9 @@ const char* ParseDateTime(const char* p, PosixTransition* res) { int weekday = 0; if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) { res->date.fmt = PosixTransition::M; - res->date.m.month = static_cast<std::int_fast8_t>(month); - res->date.m.week = static_cast<std::int_fast8_t>(week); - res->date.m.weekday = static_cast<std::int_fast8_t>(weekday); + res->date.m.month = static_cast<std::int_fast8_t>(month); + res->date.m.week = static_cast<std::int_fast8_t>(week); + res->date.m.weekday = static_cast<std::int_fast8_t>(weekday); } } } @@ -108,13 +108,13 @@ const char* ParseDateTime(const char* p, PosixTransition* res) { int day = 0; if ((p = ParseInt(p + 1, 1, 365, &day)) != nullptr) { res->date.fmt = PosixTransition::J; - res->date.j.day = static_cast<std::int_fast16_t>(day); + res->date.j.day = static_cast<std::int_fast16_t>(day); } } else { int day = 0; if ((p = ParseInt(p, 0, 365, &day)) != nullptr) { res->date.fmt = PosixTransition::N; - res->date.n.day = static_cast<std::int_fast16_t>(day); + res->date.n.day = static_cast<std::int_fast16_t>(day); } } } diff --git a/contrib/libs/cctz/src/time_zone_posix.h b/contrib/libs/cctz/src/time_zone_posix.h index aea93efdff..ccf9f48e47 100644 --- a/contrib/libs/cctz/src/time_zone_posix.h +++ b/contrib/libs/cctz/src/time_zone_posix.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// https://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -66,35 +66,35 @@ namespace cctz { // it would take us to another day, and perhaps week, or even month. struct PosixTransition { enum DateFormat { J, N, M }; - - struct Date { - struct NonLeapDay { - std::int_fast16_t day; // day of non-leap year [1:365] - }; - struct Day { - std::int_fast16_t day; // day of year [0:365] - }; - struct MonthWeekWeekday { - std::int_fast8_t month; // month of year [1:12] - std::int_fast8_t week; // week of month [1:5] (5==last) - std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat - }; - + + struct Date { + struct NonLeapDay { + std::int_fast16_t day; // day of non-leap year [1:365] + }; + struct Day { + std::int_fast16_t day; // day of year [0:365] + }; + struct MonthWeekWeekday { + std::int_fast8_t month; // month of year [1:12] + std::int_fast8_t week; // week of month [1:5] (5==last) + std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat + }; + DateFormat fmt; - + union { - NonLeapDay j; - Day n; - MonthWeekWeekday m; + NonLeapDay j; + Day n; + MonthWeekWeekday m; }; - }; - - struct Time { + }; + + struct Time { std::int_fast32_t offset; // seconds before/after 00:00:00 - }; - - Date date; - Time time; + }; + + Date date; + Time time; }; // The entirety of a POSIX-string specified time-zone rule. The standard diff --git a/contrib/libs/cctz/src/tzfile.h b/contrib/libs/cctz/src/tzfile.h index ee91104443..06fb33f953 100644 --- a/contrib/libs/cctz/src/tzfile.h +++ b/contrib/libs/cctz/src/tzfile.h @@ -1,5 +1,5 @@ -/* Layout and location of TZif files. */ - +/* Layout and location of TZif files. */ + #ifndef TZFILE_H #define TZFILE_H @@ -22,20 +22,20 @@ */ #ifndef TZDIR -#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ +#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ #endif /* !defined TZDIR */ #ifndef TZDEFAULT -#define TZDEFAULT "/etc/localtime" +#define TZDEFAULT "/etc/localtime" #endif /* !defined TZDEFAULT */ #ifndef TZDEFRULES #define TZDEFRULES "posixrules" #endif /* !defined TZDEFRULES */ - -/* See Internet RFC 8536 for more details about the following format. */ - + +/* See Internet RFC 8536 for more details about the following format. */ + /* ** Each file begins with. . . */ @@ -46,7 +46,7 @@ struct tzhead { char tzh_magic[4]; /* TZ_MAGIC */ char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ char tzh_reserved[15]; /* reserved; must be zero */ - char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_leapcnt[4]; /* coded number of leap seconds */ char tzh_timecnt[4]; /* coded number of transition times */ @@ -69,15 +69,15 @@ struct tzhead { ** one (char [4]) total correction after above ** tzh_ttisstdcnt (char)s indexed by type; if 1, transition ** time is standard time, if 0, -** transition time is local (wall clock) -** time; if absent, transition times are +** transition time is local (wall clock) +** time; if absent, transition times are ** assumed to be local time -** tzh_ttisutcnt (char)s indexed by type; if 1, transition -** time is UT, if 0, transition time is -** local time; if absent, transition -** times are assumed to be local time. -** When this is 1, the corresponding -** std/wall indicator must also be 1. +** tzh_ttisutcnt (char)s indexed by type; if 1, transition +** time is UT, if 0, transition time is +** local time; if absent, transition +** times are assumed to be local time. +** When this is 1, the corresponding +** std/wall indicator must also be 1. */ /* diff --git a/contrib/libs/cctz/src/zone_info_source.cc b/contrib/libs/cctz/src/zone_info_source.cc index e2491da757..e29799c665 100644 --- a/contrib/libs/cctz/src/zone_info_source.cc +++ b/contrib/libs/cctz/src/zone_info_source.cc @@ -1,73 +1,73 @@ -// Copyright 2016 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "cctz/zone_info_source.h" - -namespace cctz { - -// Defined out-of-line to avoid emitting a weak vtable in all TUs. -ZoneInfoSource::~ZoneInfoSource() {} -std::string ZoneInfoSource::Version() const { return std::string(); } - -} // namespace cctz - -namespace cctz_extension { - -namespace { - -// A default for cctz_extension::zone_info_source_factory, which simply -// defers to the fallback factory. -std::unique_ptr<cctz::ZoneInfoSource> DefaultFactory( - const std::string& name, - const std::function<std::unique_ptr<cctz::ZoneInfoSource>( - const std::string& name)>& fallback_factory) { - return fallback_factory(name); -} - -} // namespace - -// A "weak" definition for cctz_extension::zone_info_source_factory. -// The user may override this with their own "strong" definition (see -// zone_info_source.h). -#if !defined(__has_attribute) -#define __has_attribute(x) 0 -#endif -// MinGW is GCC on Windows, so while it asserts __has_attribute(weak), the -// Windows linker cannot handle that. Nor does the MinGW compiler know how to -// pass "#pragma comment(linker, ...)" to the Windows linker. -#if (__has_attribute(weak) || defined(__GNUC__)) && !defined(__MINGW32__) && !defined(_MSC_VER) -ZoneInfoSourceFactory zone_info_source_factory - __attribute__((weak)) = DefaultFactory; -#elif defined(_MSC_VER) && !defined(__MINGW32__) -extern ZoneInfoSourceFactory zone_info_source_factory; -extern ZoneInfoSourceFactory default_factory; -ZoneInfoSourceFactory default_factory = DefaultFactory; -#if defined(_M_IX86) -#pragma comment( \ - linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA") -#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM) || \ - defined(_M_ARM64) -#pragma comment( \ - linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@34@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@23@@Z@34@@ZEA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@34@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@23@@Z@34@@ZEA") -#else -#error Unsupported MSVC platform -#endif // _M_<PLATFORM> -#else -// Make it a "strong" definition if we have no other choice. -ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory; -#endif - -} // namespace cctz_extension +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "cctz/zone_info_source.h" + +namespace cctz { + +// Defined out-of-line to avoid emitting a weak vtable in all TUs. +ZoneInfoSource::~ZoneInfoSource() {} +std::string ZoneInfoSource::Version() const { return std::string(); } + +} // namespace cctz + +namespace cctz_extension { + +namespace { + +// A default for cctz_extension::zone_info_source_factory, which simply +// defers to the fallback factory. +std::unique_ptr<cctz::ZoneInfoSource> DefaultFactory( + const std::string& name, + const std::function<std::unique_ptr<cctz::ZoneInfoSource>( + const std::string& name)>& fallback_factory) { + return fallback_factory(name); +} + +} // namespace + +// A "weak" definition for cctz_extension::zone_info_source_factory. +// The user may override this with their own "strong" definition (see +// zone_info_source.h). +#if !defined(__has_attribute) +#define __has_attribute(x) 0 +#endif +// MinGW is GCC on Windows, so while it asserts __has_attribute(weak), the +// Windows linker cannot handle that. Nor does the MinGW compiler know how to +// pass "#pragma comment(linker, ...)" to the Windows linker. +#if (__has_attribute(weak) || defined(__GNUC__)) && !defined(__MINGW32__) && !defined(_MSC_VER) +ZoneInfoSourceFactory zone_info_source_factory + __attribute__((weak)) = DefaultFactory; +#elif defined(_MSC_VER) && !defined(__MINGW32__) +extern ZoneInfoSourceFactory zone_info_source_factory; +extern ZoneInfoSourceFactory default_factory; +ZoneInfoSourceFactory default_factory = DefaultFactory; +#if defined(_M_IX86) +#pragma comment( \ + linker, \ + "/alternatename:?zone_info_source_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA") +#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM) || \ + defined(_M_ARM64) +#pragma comment( \ + linker, \ + "/alternatename:?zone_info_source_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@34@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@23@@Z@34@@ZEA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@34@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@__y1@std@@@__y1@std@@AEBV?$basic_string@DU?$char_traits@D@__y1@std@@V?$allocator@D@23@@23@@Z@34@@ZEA") +#else +#error Unsupported MSVC platform +#endif // _M_<PLATFORM> +#else +// Make it a "strong" definition if we have no other choice. +ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory; +#endif + +} // namespace cctz_extension |