aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cctz/src
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/cctz/src
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-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.cc30
-rw-r--r--contrib/libs/cctz/src/time_zone_fixed.cc106
-rw-r--r--contrib/libs/cctz/src/time_zone_fixed.h10
-rw-r--r--contrib/libs/cctz/src/time_zone_format.cc550
-rw-r--r--contrib/libs/cctz/src/time_zone_if.cc12
-rw-r--r--contrib/libs/cctz/src/time_zone_if.h38
-rw-r--r--contrib/libs/cctz/src/time_zone_impl.cc68
-rw-r--r--contrib/libs/cctz/src/time_zone_impl.h40
-rw-r--r--contrib/libs/cctz/src/time_zone_info.cc602
-rw-r--r--contrib/libs/cctz/src/time_zone_info.h38
-rw-r--r--contrib/libs/cctz/src/time_zone_libc.cc484
-rw-r--r--contrib/libs/cctz/src/time_zone_libc.h14
-rw-r--r--contrib/libs/cctz/src/time_zone_lookup.cc192
-rw-r--r--contrib/libs/cctz/src/time_zone_posix.cc12
-rw-r--r--contrib/libs/cctz/src/time_zone_posix.h52
-rw-r--r--contrib/libs/cctz/src/tzfile.h32
-rw-r--r--contrib/libs/cctz/src/zone_info_source.cc146
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