diff options
Diffstat (limited to 'absl/time')
647 files changed, 4328 insertions, 1778 deletions
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index e793da87..4d9c01c4 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel @@ -27,15 +27,16 @@ licenses(["notice"]) # Apache 2.0 cc_library( name = "time", srcs = [ + "civil_time.cc", "clock.cc", "duration.cc", "format.cc", - "internal/get_current_time_ios.inc", + "internal/get_current_time_chrono.inc", "internal/get_current_time_posix.inc", - "internal/get_current_time_windows.inc", "time.cc", ], hdrs = [ + "civil_time.h", "clock.h", "time.h", ], @@ -73,10 +74,10 @@ cc_library( cc_test( name = "time_test", srcs = [ + "civil_time_test.cc", "clock_test.cc", "duration_test.cc", "format_test.cc", - "time_norm_test.cc", "time_test.cc", "time_zone_test.cc", ], @@ -95,6 +96,7 @@ cc_test( cc_test( name = "time_benchmark", srcs = [ + "civil_time_benchmark.cc", "clock_benchmark.cc", "duration_benchmark.cc", "format_benchmark.cc", @@ -108,6 +110,7 @@ cc_test( ":test_util", ":time", "//absl/base", + "//absl/hash", "@com_github_google_benchmark//:benchmark_main", ], ) diff --git a/absl/time/CMakeLists.txt b/absl/time/CMakeLists.txt index 06272364..53216cda 100644 --- a/absl/time/CMakeLists.txt +++ b/absl/time/CMakeLists.txt @@ -15,6 +15,7 @@ # list(APPEND TIME_PUBLIC_HEADERS + "civil_time.h" "clock.h" "time.h" ) @@ -29,6 +30,7 @@ list(APPEND TIME_INTERNAL_HEADERS ) list(APPEND TIME_SRC + "civil_time.cc" "time.cc" "clock.cc" "duration.cc" @@ -74,11 +76,11 @@ absl_library( # test time_test list(APPEND TIME_TEST_SRC + "civil_time_test.cc" "time_test.cc" "clock_test.cc" "duration_test.cc" "format_test.cc" - "time_norm_test.cc" "time_test.cc" "time_zone_test.cc" "internal/test_util.cc" diff --git a/absl/time/civil_time.cc b/absl/time/civil_time.cc new file mode 100644 index 00000000..c6fa5469 --- /dev/null +++ b/absl/time/civil_time.cc @@ -0,0 +1,90 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// http://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 "absl/time/civil_time.h" + +#include <cstdlib> +#include <string> + +#include "absl/strings/str_cat.h" +#include "absl/time/time.h" + +namespace absl { +inline namespace lts_2018_12_18 { + +namespace { + +// Since a civil time has a larger year range than absl::Time (64-bit years vs +// 64-bit seconds, respectively) we normalize years to roughly +/- 400 years +// around the year 2400, which will produce an equivalent year in a range that +// absl::Time can handle. +inline civil_year_t NormalizeYear(civil_year_t year) { + return 2400 + year % 400; +} + +// Formats the given CivilSecond according to the given format. +std::string FormatYearAnd(string_view fmt, CivilSecond cs) { + const CivilSecond ncs(NormalizeYear(cs.year()), cs.month(), cs.day(), + cs.hour(), cs.minute(), cs.second()); + const TimeZone utc = UTCTimeZone(); + // TODO(absl-team): Avoid conversion of fmt std::string. + return StrCat(cs.year(), FormatTime(std::string(fmt), FromCivil(ncs, utc), utc)); +} + +} // namespace + +std::string FormatCivilTime(CivilSecond c) { + return FormatYearAnd("-%m-%dT%H:%M:%S", c); +} +std::string FormatCivilTime(CivilMinute c) { + return FormatYearAnd("-%m-%dT%H:%M", c); +} +std::string FormatCivilTime(CivilHour c) { + return FormatYearAnd("-%m-%dT%H", c); +} +std::string FormatCivilTime(CivilDay c) { + return FormatYearAnd("-%m-%d", c); +} +std::string FormatCivilTime(CivilMonth c) { + return FormatYearAnd("-%m", c); +} +std::string FormatCivilTime(CivilYear c) { + return FormatYearAnd("", c); +} + +namespace time_internal { + +std::ostream& operator<<(std::ostream& os, CivilYear y) { + return os << FormatCivilTime(y); +} +std::ostream& operator<<(std::ostream& os, CivilMonth m) { + return os << FormatCivilTime(m); +} +std::ostream& operator<<(std::ostream& os, CivilDay d) { + return os << FormatCivilTime(d); +} +std::ostream& operator<<(std::ostream& os, CivilHour h) { + return os << FormatCivilTime(h); +} +std::ostream& operator<<(std::ostream& os, CivilMinute m) { + return os << FormatCivilTime(m); +} +std::ostream& operator<<(std::ostream& os, CivilSecond s) { + return os << FormatCivilTime(s); +} + +} // namespace time_internal + +} // inline namespace lts_2018_12_18 +} // namespace absl diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h new file mode 100644 index 00000000..f6cc3ff8 --- /dev/null +++ b/absl/time/civil_time.h @@ -0,0 +1,488 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// http://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. +// +// ----------------------------------------------------------------------------- +// File: civil_time.h +// ----------------------------------------------------------------------------- +// +// This header file defines abstractions for computing with "civil time". +// The term "civil time" refers to the legally recognized human-scale time +// that is represented by the six fields `YYYY-MM-DD hh:mm:ss`. A "date" +// is perhaps the most common example of a civil time (represented here as +// an `absl::CivilDay`). +// +// Modern-day civil time follows the Gregorian Calendar and is a +// time-zone-independent concept: a civil time of "2015-06-01 12:00:00", for +// example, is not tied to a time zone. Put another way, a civil time does not +// map to a unique point in time; a civil time must be mapped to an absolute +// time *through* a time zone. +// +// Because a civil time is what most people think of as "time," it is common to +// map absolute times to civil times to present to users. +// +// Time zones define the relationship between absolute and civil times. Given an +// absolute or civil time and a time zone, you can compute the other time: +// +// Civil Time = F(Absolute Time, Time Zone) +// Absolute Time = G(Civil Time, Time Zone) +// +// The Abseil time library allows you to construct such civil times from +// absolute times; consult time.h for such functionality. +// +// This library provides six classes for constructing civil-time objects, and +// provides several helper functions for rounding, iterating, and performing +// arithmetic on civil-time objects, while avoiding complications like +// daylight-saving time (DST): +// +// * `absl::CivilSecond` +// * `absl::CivilMinute` +// * `absl::CivilHour` +// * `absl::CivilDay` +// * `absl::CivilMonth` +// * `absl::CivilYear` +// +// Example: +// +// // Construct a civil-time object for a specific day +// const absl::CivilDay cd(1969, 07, 20); +// +// // Construct a civil-time object for a specific second +// const absl::CivilSecond cd(2018, 8, 1, 12, 0, 1); +// +// Note: In C++14 and later, this library is usable in a constexpr context. +// +// Example: +// +// // Valid in C++14 +// constexpr absl::CivilDay cd(1969, 07, 20); +// + +#ifndef ABSL_TIME_CIVIL_TIME_H_ +#define ABSL_TIME_CIVIL_TIME_H_ + +#include <string> + +#include "absl/strings/string_view.h" +#include "absl/time/internal/cctz/include/cctz/civil_time.h" + +namespace absl { +inline namespace lts_2018_12_18 { + +namespace time_internal { +struct second_tag : cctz::detail::second_tag {}; +struct minute_tag : second_tag, cctz::detail::minute_tag {}; +struct hour_tag : minute_tag, cctz::detail::hour_tag {}; +struct day_tag : hour_tag, cctz::detail::day_tag {}; +struct month_tag : day_tag, cctz::detail::month_tag {}; +struct year_tag : month_tag, cctz::detail::year_tag {}; +} // namespace time_internal + +// ----------------------------------------------------------------------------- +// CivilSecond, CivilMinute, CivilHour, CivilDay, CivilMonth, CivilYear +// ----------------------------------------------------------------------------- +// +// Each of these civil-time types is a simple value type with the same +// interface for construction and the same six accessors for each of the civil +// time fields (year, month, day, hour, minute, and second, aka YMDHMS). These +// classes differ only in their alignment, which is indicated by the type name +// and specifies the field on which arithmetic operates. +// +// CONSTRUCTION +// +// Each of the civil-time types can be constructed in two ways: by directly +// passing to the constructor up to six integers representing the YMDHMS fields, +// or by copying the YMDHMS fields from a differently aligned civil-time type. +// Omitted fields are assigned their minimum valid value. Hours, minutes, and +// seconds will be set to 0, month and day will be set to 1. Since there is no +// minimum year, the default is 1970. +// +// Examples: +// +// absl::CivilDay default_value; // 1970-01-01 00:00:00 +// +// absl::CivilDay a(2015, 2, 3); // 2015-02-03 00:00:00 +// absl::CivilDay b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00 +// absl::CivilDay c(2015); // 2015-01-01 00:00:00 +// +// absl::CivilSecond ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06 +// absl::CivilMinute mm(ss); // 2015-02-03 04:05:00 +// absl::CivilHour hh(mm); // 2015-02-03 04:00:00 +// absl::CivilDay d(hh); // 2015-02-03 00:00:00 +// absl::CivilMonth m(d); // 2015-02-01 00:00:00 +// absl::CivilYear y(m); // 2015-01-01 00:00:00 +// +// m = absl::CivilMonth(y); // 2015-01-01 00:00:00 +// d = absl::CivilDay(m); // 2015-01-01 00:00:00 +// hh = absl::CivilHour(d); // 2015-01-01 00:00:00 +// mm = absl::CivilMinute(hh); // 2015-01-01 00:00:00 +// ss = absl::CivilSecond(mm); // 2015-01-01 00:00:00 +// +// Each civil-time class is aligned to the civil-time field indicated in the +// class's name after normalization. Alignment is performed by setting all the +// inferior fields to their minimum valid value (as described above). The +// following are examples of how each of the six types would align the fields +// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the +// string format used here is not important; it's just a shorthand way of +// showing the six YMDHMS fields.) +// +// absl::CivilSecond : 2015-11-22 12:34:56 +// absl::CivilMinute : 2015-11-22 12:34:00 +// absl::CivilHour : 2015-11-22 12:00:00 +// absl::CivilDay : 2015-11-22 00:00:00 +// absl::CivilMonth : 2015-11-01 00:00:00 +// absl::CivilYear : 2015-01-01 00:00:00 +// +// Each civil-time type performs arithmetic on the field to which it is +// aligned. This means that adding 1 to an absl::CivilDay increments the day +// field (normalizing as necessary), and subtracting 7 from an absl::CivilMonth +// operates on the month field (normalizing as necessary). All arithmetic +// produces a valid civil time. Difference requires two similarly aligned +// civil-time objects and returns the scalar answer in units of the objects' +// alignment. For example, the difference between two absl::CivilHour objects +// will give an answer in units of civil hours. +// +// ALIGNMENT CONVERSION +// +// The alignment of a civil-time object cannot change, but the object may be +// used to construct a new object with a different alignment. This is referred +// to as "realigning". When realigning to a type with the same or more +// precision (e.g., absl::CivilDay -> absl::CivilSecond), the conversion may be +// performed implicitly since no information is lost. However, if information +// could be discarded (e.g., CivilSecond -> CivilDay), the conversion must +// be explicit at the call site. +// +// Examples: +// +// void UseDay(absl::CivilDay day); +// +// absl::CivilSecond cs; +// UseDay(cs); // Won't compile because data may be discarded +// UseDay(absl::CivilDay(cs)); // OK: explicit conversion +// +// absl::CivilDay cd; +// UseDay(cd); // OK: no conversion needed +// +// absl::CivilMonth cm; +// UseDay(cm); // OK: implicit conversion to absl::CivilDay +// +// NORMALIZATION +// +// Normalization takes invalid values and adjusts them to produce valid values. +// Within the civil-time library, integer arguments passed to the Civil* +// constructors may be out-of-range, in which case they are normalized by +// carrying overflow into a field of courser granularity to produce valid +// civil-time objects. This normalization enables natural arithmetic on +// constructor arguments without worrying about the field's range. +// +// Examples: +// +// // Out-of-range; normalized to 2016-11-01 +// absl::CivilDay d(2016, 10, 32); +// // Out-of-range, negative: normalized to 2016-10-30T23 +// absl::CivilHour h1(2016, 10, 31, -1); +// // Normalization is cumulative: normalized to 2016-10-30T23 +// absl::CivilHour h2(2016, 10, 32, -25); +// +// Note: If normalization is undesired, you can signal an error by comparing +// the constructor arguments to the normalized values returned by the YMDHMS +// properties. +// +// COMPARISON +// +// Comparison between civil-time objects considers all six YMDHMS fields, +// regardless of the type's alignment. Comparison between differently aligned +// civil-time types is allowed. +// +// Examples: +// +// absl::CivilDay feb_3(2015, 2, 3); // 2015-02-03 00:00:00 +// absl::CivilDay mar_4(2015, 3, 4); // 2015-03-04 00:00:00 +// // feb_3 < mar_4 +// // absl::CivilYear(feb_3) == absl::CivilYear(mar_4) +// +// absl::CivilSecond feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00 +// // feb_3 < feb_3_noon +// // feb_3 == absl::CivilDay(feb_3_noon) +// +// // Iterates all the days of February 2015. +// for (absl::CivilDay d(2015, 2, 1); d < absl::CivilMonth(2015, 3); ++d) { +// // ... +// } +// +// ARITHMETIC +// +// Civil-time types support natural arithmetic operators such as addition, +// subtraction, and difference. Arithmetic operates on the civil-time field +// indicated in the type's name. Difference operators require arguments with +// the same alignment and return the answer in units of the alignment. +// +// Example: +// +// absl::CivilDay a(2015, 2, 3); +// ++a; // 2015-02-04 00:00:00 +// --a; // 2015-02-03 00:00:00 +// absl::CivilDay b = a + 1; // 2015-02-04 00:00:00 +// absl::CivilDay c = 1 + b; // 2015-02-05 00:00:00 +// int n = c - a; // n = 2 (civil days) +// int m = c - absl::CivilMonth(c); // Won't compile: different types. +// +// ACCESSORS +// +// Each civil-time type has accessors for all six of the civil-time fields: +// year, month, day, hour, minute, and second. +// +// civil_year_t year() +// int month() +// int day() +// int hour() +// int minute() +// int second() +// +// Recall that fields inferior to the type's aligment will be set to their +// minimum valid value. +// +// Example: +// +// absl::CivilDay d(2015, 6, 28); +// // d.year() == 2015 +// // d.month() == 6 +// // d.day() == 28 +// // d.hour() == 0 +// // d.minute() == 0 +// // d.second() == 0 +// +// CASE STUDY: Adding a month to January 31. +// +// One of the classic questions that arises when considering a civil time +// library (or a date library or a date/time library) is this: +// "What is the result of adding a month to January 31?" +// This is an interesting question because it is unclear what is meant by a +// "month", and several different answers are possible, depending on context: +// +// 1. March 3 (or 2 if a leap year), if "add a month" means to add a month to +// the current month, and adjust the date to overflow the extra days into +// March. In this case the result of "February 31" would be normalized as +// within the civil-time library. +// 2. February 28 (or 29 if a leap year), if "add a month" means to add a +// month, and adjust the date while holding the resulting month constant. +// In this case, the result of "February 31" would be truncated to the last +// day in February. +// 3. An error. The caller may get some error, an exception, an invalid date +// object, or perhaps return `false`. This may make sense because there is +// no single unambiguously correct answer to the question. +// +// Practically speaking, any answer that is not what the programmer intended +// is the wrong answer. +// +// The Abseil time library avoids this problem by making it impossible to +// ask ambiguous questions. All civil-time objects are aligned to a particular +// civil-field boundary (such as aligned to a year, month, day, hour, minute, +// or second), and arithmetic operates on the field to which the object is +// aligned. This means that in order to "add a month" the object must first be +// aligned to a month boundary, which is equivalent to the first day of that +// month. +// +// Of course, there are ways to compute an answer the question at hand using +// this Abseil time library, but they require the programmer to be explicit +// about the answer they expect. To illustrate, let's see how to compute all +// three of the above possible answers to the question of "Jan 31 plus 1 +// month": +// +// Example: +// +// const absl::CivilDay d(2015, 1, 31); +// +// // Answer 1: +// // Add 1 to the month field in the constructor, and rely on normalization. +// const auto normalized = absl::CivilDay(d.year(), d.month() + 1, d.day()); +// // normalized == 2015-03-03 (aka Feb 31) +// +// // Answer 2: +// // Add 1 to month field, capping to the end of next month. +// const auto next_month = absl::CivilMonth(d) + 1; +// const auto last_day_of_next_month = absl::CivilDay(next_month + 1) - 1; +// const auto capped = std::min(normalized, last_day_of_next_month); +// // capped == 2015-02-28 +// +// // Answer 3: +// // Signal an error if the normalized answer is not in next month. +// if (absl::CivilMonth(normalized) != next_month) { +// // error, month overflow +// } +// +using CivilSecond = + time_internal::cctz::detail::civil_time<time_internal::second_tag>; +using CivilMinute = + time_internal::cctz::detail::civil_time<time_internal::minute_tag>; +using CivilHour = + time_internal::cctz::detail::civil_time<time_internal::hour_tag>; +using CivilDay = + time_internal::cctz::detail::civil_time<time_internal::day_tag>; +using CivilMonth = + time_internal::cctz::detail::civil_time<time_internal::month_tag>; +using CivilYear = + time_internal::cctz::detail::civil_time<time_internal::year_tag>; + +// civil_year_t +// +// Type alias of a civil-time year value. This type is guaranteed to (at least) +// support any year value supported by `time_t`. +// +// Example: +// +// absl::CivilSecond cs = ...; +// absl::civil_year_t y = cs.year(); +// cs = absl::CivilSecond(y, 1, 1, 0, 0, 0); // CivilSecond(CivilYear(cs)) +// +using civil_year_t = time_internal::cctz::year_t; + +// civil_diff_t +// +// Type alias of the difference between two civil-time values. +// This type is used to indicate arguments that are not +// normalized (such as parameters to the civil-time constructors), the results +// of civil-time subtraction, or the operand to civil-time addition. +// +// Example: +// +// absl::civil_diff_t n_sec = cs1 - cs2; // cs1 == cs2 + n_sec; +// +using civil_diff_t = time_internal::cctz::diff_t; + +// Weekday::monday, Weekday::tuesday, Weekday::wednesday, Weekday::thursday, +// Weekday::friday, Weekday::saturday, Weekday::sunday +// +// The Weekday enum class represents the civil-time concept of a "weekday" with +// members for all days of the week. +// +// absl::Weekday wd = absl::Weekday::thursday; +// +using Weekday = time_internal::cctz::weekday; + +// GetWeekday() +// +// Returns the absl::Weekday for the given absl::CivilDay. +// +// Example: +// +// absl::CivilDay a(2015, 8, 13); +// absl::Weekday wd = absl::GetWeekday(a); // wd == absl::Weekday::thursday +// +inline Weekday GetWeekday(CivilDay cd) { + return time_internal::cctz::get_weekday(cd); +} + +// NextWeekday() +// PrevWeekday() +// +// Returns the absl::CivilDay that strictly follows or precedes a given +// absl::CivilDay, and that falls on the given absl::Weekday. +// +// Example, given the following month: +// +// August 2015 +// Su Mo Tu We Th Fr Sa +// 1 +// 2 3 4 5 6 7 8 +// 9 10 11 12 13 14 15 +// 16 17 18 19 20 21 22 +// 23 24 25 26 27 28 29 +// 30 31 +// +// absl::CivilDay a(2015, 8, 13); +// // absl::GetWeekday(a) == absl::Weekday::thursday +// absl::CivilDay b = absl::NextWeekday(a, absl::Weekday::thursday); +// // b = 2015-08-20 +// absl::CivilDay c = absl::PrevWeekday(a, absl::Weekday::thursday); +// // c = 2015-08-06 +// +// absl::CivilDay d = ... +// // Gets the following Thursday if d is not already Thursday +// absl::CivilDay thurs1 = absl::PrevWeekday(d, absl::Weekday::thursday) + 7; +// // Gets the previous Thursday if d is not already Thursday +// absl::CivilDay thurs2 = absl::NextWeekday(d, absl::Weekday::thursday) - 7; +// +inline CivilDay NextWeekday(CivilDay cd, Weekday wd) { + return CivilDay(time_internal::cctz::next_weekday(cd, wd)); +} +inline CivilDay PrevWeekday(CivilDay cd, Weekday wd) { + return CivilDay(time_internal::cctz::prev_weekday(cd, wd)); +} + +// GetYearDay() +// +// Returns the day-of-year for the given absl::CivilDay. +// +// Example: +// +// absl::CivilDay a(2015, 1, 1); +// int yd_jan_1 = absl::GetYearDay(a); // yd_jan_1 = 1 +// absl::CivilDay b(2015, 12, 31); +// int yd_dec_31 = absl::GetYearDay(b); // yd_dec_31 = 365 +// +inline int GetYearDay(CivilDay cd) { + return time_internal::cctz::get_yearday(cd); +} + +// FormatCivilTime() +// +// Formats the given civil-time value into a string value of the following +// format: +// +// Type | Format +// --------------------------------- +// CivilSecond | YYYY-MM-DDTHH:MM:SS +// CivilMinute | YYYY-MM-DDTHH:MM +// CivilHour | YYYY-MM-DDTHH +// CivilDay | YYYY-MM-DD +// CivilMonth | YYYY-MM +// CivilYear | YYYY +// +// Example: +// +// absl::CivilDay d = absl::CivilDay(1969, 7, 20); +// string day_string = absl::FormatCivilTime(d); // "1969-07-20" +// +std::string FormatCivilTime(CivilSecond c); +std::string FormatCivilTime(CivilMinute c); +std::string FormatCivilTime(CivilHour c); +std::string FormatCivilTime(CivilDay c); +std::string FormatCivilTime(CivilMonth c); +std::string FormatCivilTime(CivilYear c); + +namespace time_internal { // For functions found via ADL on civil-time tags. + +// Streaming Operators +// +// Each civil-time type may be sent to an output stream using operator<<(). +// The result matches the string produced by `FormatCivilTime()`. +// +// Example: +// +// absl::CivilDay d = absl::CivilDay("1969-07-20"); +// std::cout << "Date is: " << d << "\n"; +// +std::ostream& operator<<(std::ostream& os, CivilYear y); +std::ostream& operator<<(std::ostream& os, CivilMonth m); +std::ostream& operator<<(std::ostream& os, CivilDay d); +std::ostream& operator<<(std::ostream& os, CivilHour h); +std::ostream& operator<<(std::ostream& os, CivilMinute m); +std::ostream& operator<<(std::ostream& os, CivilSecond s); + +} // namespace time_internal + +} // inline namespace lts_2018_12_18 +} // namespace absl + +#endif // ABSL_TIME_CIVIL_TIME_H_ diff --git a/absl/time/civil_time_benchmark.cc b/absl/time/civil_time_benchmark.cc new file mode 100644 index 00000000..f30f636d --- /dev/null +++ b/absl/time/civil_time_benchmark.cc @@ -0,0 +1,107 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// http://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 "absl/time/civil_time.h" + +#include <numeric> +#include <vector> + +#include "absl/hash/hash.h" +#include "benchmark/benchmark.h" + +namespace { + +// Run on (12 X 3492 MHz CPUs); 2018-11-05T13:44:29.814239103-08:00 +// CPU: Intel Haswell with HyperThreading (6 cores) dL1:32KB dL2:256KB dL3:15MB +// Benchmark Time(ns) CPU(ns) Iterations +// ---------------------------------------------------------------- +// BM_Difference_Days 14.5 14.5 48531105 +// BM_Step_Days 12.6 12.6 54876006 +// BM_Format 587 587 1000000 +// BM_Parse 692 692 1000000 +// BM_RoundTripFormatParse 1309 1309 532075 +// BM_CivilYearAbslHash 0.710 0.710 976400000 +// BM_CivilMonthAbslHash 1.13 1.13 619500000 +// BM_CivilDayAbslHash 1.70 1.70 426000000 +// BM_CivilHourAbslHash 2.45 2.45 287600000 +// BM_CivilMinuteAbslHash 3.21 3.21 226200000 +// BM_CivilSecondAbslHash 4.10 4.10 171800000 + +void BM_Difference_Days(benchmark::State& state) { + const absl::CivilDay c(2014, 8, 22); + const absl::CivilDay epoch(1970, 1, 1); + while (state.KeepRunning()) { + const absl::civil_diff_t n = c - epoch; + benchmark::DoNotOptimize(n); + } +} +BENCHMARK(BM_Difference_Days); + +void BM_Step_Days(benchmark::State& state) { + const absl::CivilDay kStart(2014, 8, 22); + absl::CivilDay c = kStart; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(++c); + } +} +BENCHMARK(BM_Step_Days); + +void BM_Format(benchmark::State& state) { + const absl::CivilSecond c(2014, 1, 2, 3, 4, 5); + while (state.KeepRunning()) { + const std::string s = absl::FormatCivilTime(c); + benchmark::DoNotOptimize(s); + } +} +BENCHMARK(BM_Format); + +template <typename T> +void BM_CivilTimeAbslHash(benchmark::State& state) { + const int kSize = 100000; + std::vector<T> civil_times(kSize); + std::iota(civil_times.begin(), civil_times.end(), T(2018)); + + absl::Hash<T> absl_hasher; + while (state.KeepRunningBatch(kSize)) { + for (const T civil_time : civil_times) { + benchmark::DoNotOptimize(absl_hasher(civil_time)); + } + } +} +void BM_CivilYearAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilYear>(state); +} +void BM_CivilMonthAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilMonth>(state); +} +void BM_CivilDayAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilDay>(state); +} +void BM_CivilHourAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilHour>(state); +} +void BM_CivilMinuteAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilMinute>(state); +} +void BM_CivilSecondAbslHash(benchmark::State& state) { + BM_CivilTimeAbslHash<absl::CivilSecond>(state); +} +BENCHMARK(BM_CivilYearAbslHash); +BENCHMARK(BM_CivilMonthAbslHash); +BENCHMARK(BM_CivilDayAbslHash); +BENCHMARK(BM_CivilHourAbslHash); +BENCHMARK(BM_CivilMinuteAbslHash); +BENCHMARK(BM_CivilSecondAbslHash); + +} // namespace diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc new file mode 100644 index 00000000..dc83d7a9 --- /dev/null +++ b/absl/time/civil_time_test.cc @@ -0,0 +1,1073 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// http://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 "absl/time/civil_time.h" + +#include <limits> +#include <sstream> +#include <type_traits> + +#include "absl/base/macros.h" +#include "gtest/gtest.h" + +namespace { + +TEST(CivilTime, DefaultConstruction) { + absl::CivilSecond ss; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss)); + + absl::CivilMinute mm; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm)); + + absl::CivilHour hh; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh)); + + absl::CivilDay d; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d)); + + absl::CivilMonth m; + EXPECT_EQ("1970-01", absl::FormatCivilTime(m)); + + absl::CivilYear y; + EXPECT_EQ("1970", absl::FormatCivilTime(y)); +} + +TEST(CivilTime, StructMember) { + struct S { + absl::CivilDay day; + }; + S s = {}; + EXPECT_EQ(absl::CivilDay{}, s.day); +} + +TEST(CivilTime, FieldsConstruction) { + EXPECT_EQ("2015-01-02T03:04:05", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02T03:04:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02T03:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02T00:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1, 2))); + EXPECT_EQ("2015-01-01T00:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015, 1))); + EXPECT_EQ("2015-01-01T00:00:00", + absl::FormatCivilTime(absl::CivilSecond(2015))); + + EXPECT_EQ("2015-01-02T03:04", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02T03:04", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02T03:00", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02T00:00", + absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2))); + EXPECT_EQ("2015-01-01T00:00", + absl::FormatCivilTime(absl::CivilMinute(2015, 1))); + EXPECT_EQ("2015-01-01T00:00", + absl::FormatCivilTime(absl::CivilMinute(2015))); + + EXPECT_EQ("2015-01-02T03", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02T03", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02T03", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02T00", + absl::FormatCivilTime(absl::CivilHour(2015, 1, 2))); + EXPECT_EQ("2015-01-01T00", + absl::FormatCivilTime(absl::CivilHour(2015, 1))); + EXPECT_EQ("2015-01-01T00", + absl::FormatCivilTime(absl::CivilHour(2015))); + + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02", + absl::FormatCivilTime(absl::CivilDay(2015, 1, 2))); + EXPECT_EQ("2015-01-01", + absl::FormatCivilTime(absl::CivilDay(2015, 1))); + EXPECT_EQ("2015-01-01", + absl::FormatCivilTime(absl::CivilDay(2015))); + + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015, 1))); + EXPECT_EQ("2015-01", + absl::FormatCivilTime(absl::CivilMonth(2015))); + + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4, 5))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1, 2))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015, 1))); + EXPECT_EQ("2015", + absl::FormatCivilTime(absl::CivilYear(2015))); +} + +TEST(CivilTime, FieldsConstructionLimits) { + const int kIntMax = std::numeric_limits<int>::max(); + EXPECT_EQ("2038-01-19T03:14:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, 0, kIntMax))); + EXPECT_EQ("6121-02-11T05:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, kIntMax, kIntMax))); + EXPECT_EQ("251104-11-20T12:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, kIntMax, kIntMax, kIntMax))); + EXPECT_EQ("6130715-05-30T12:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, kIntMax, kIntMax, kIntMax, kIntMax))); + EXPECT_EQ("185087685-11-26T12:21:07", + absl::FormatCivilTime(absl::CivilSecond( + 1970, kIntMax, kIntMax, kIntMax, kIntMax, kIntMax))); + + const int kIntMin = std::numeric_limits<int>::min(); + EXPECT_EQ("1901-12-13T20:45:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, 0, kIntMin))); + EXPECT_EQ("-2182-11-20T18:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, kIntMin, kIntMin))); + EXPECT_EQ("-247165-02-11T10:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, kIntMin, kIntMin, kIntMin))); + EXPECT_EQ("-6126776-08-01T10:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, kIntMin, kIntMin, kIntMin, kIntMin))); + EXPECT_EQ("-185083747-10-31T10:37:52", + absl::FormatCivilTime(absl::CivilSecond( + 1970, kIntMin, kIntMin, kIntMin, kIntMin, kIntMin))); +} + +TEST(CivilTime, RangeLimits) { + const absl::civil_year_t kYearMax = + std::numeric_limits<absl::civil_year_t>::max(); + EXPECT_EQ(absl::CivilYear(kYearMax), + absl::CivilYear::max()); + EXPECT_EQ(absl::CivilMonth(kYearMax, 12), + absl::CivilMonth::max()); + EXPECT_EQ(absl::CivilDay(kYearMax, 12, 31), + absl::CivilDay::max()); + EXPECT_EQ(absl::CivilHour(kYearMax, 12, 31, 23), + absl::CivilHour::max()); + EXPECT_EQ(absl::CivilMinute(kYearMax, 12, 31, 23, 59), + absl::CivilMinute::max()); + EXPECT_EQ(absl::CivilSecond(kYearMax, 12, 31, 23, 59, 59), + absl::CivilSecond::max()); + + const absl::civil_year_t kYearMin = + std::numeric_limits<absl::civil_year_t>::min(); + EXPECT_EQ(absl::CivilYear(kYearMin), + absl::CivilYear::min()); + EXPECT_EQ(absl::CivilMonth(kYearMin, 1), + absl::CivilMonth::min()); + EXPECT_EQ(absl::CivilDay(kYearMin, 1, 1), + absl::CivilDay::min()); + EXPECT_EQ(absl::CivilHour(kYearMin, 1, 1, 0), + absl::CivilHour::min()); + EXPECT_EQ(absl::CivilMinute(kYearMin, 1, 1, 0, 0), + absl::CivilMinute::min()); + EXPECT_EQ(absl::CivilSecond(kYearMin, 1, 1, 0, 0, 0), + absl::CivilSecond::min()); +} + +TEST(CivilTime, ImplicitCrossAlignment) { + absl::CivilYear year(2015); + absl::CivilMonth month = year; + absl::CivilDay day = month; + absl::CivilHour hour = day; + absl::CivilMinute minute = hour; + absl::CivilSecond second = minute; + + second = year; + EXPECT_EQ(second, year); + second = month; + EXPECT_EQ(second, month); + second = day; + EXPECT_EQ(second, day); + second = hour; + EXPECT_EQ(second, hour); + second = minute; + EXPECT_EQ(second, minute); + + minute = year; + EXPECT_EQ(minute, year); + minute = month; + EXPECT_EQ(minute, month); + minute = day; + EXPECT_EQ(minute, day); + minute = hour; + EXPECT_EQ(minute, hour); + + hour = year; + EXPECT_EQ(hour, year); + hour = month; + EXPECT_EQ(hour, month); + hour = day; + EXPECT_EQ(hour, day); + + day = year; + EXPECT_EQ(day, year); + day = month; + EXPECT_EQ(day, month); + + month = year; + EXPECT_EQ(month, year); + + // Ensures unsafe conversions are not allowed. + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilMinute>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilHour>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilDay>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilSecond, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilHour>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilDay>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilMinute, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilHour, absl::CivilDay>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilHour, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilHour, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilDay, absl::CivilMonth>::value)); + EXPECT_FALSE( + (std::is_convertible<absl::CivilDay, absl::CivilYear>::value)); + + EXPECT_FALSE( + (std::is_convertible<absl::CivilMonth, absl::CivilYear>::value)); +} + +TEST(CivilTime, ExplicitCrossAlignment) { + // + // Assign from smaller units -> larger units + // + + absl::CivilSecond second(2015, 1, 2, 3, 4, 5); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second)); + + absl::CivilMinute minute(second); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute)); + + absl::CivilHour hour(minute); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour)); + + absl::CivilDay day(hour); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day)); + + absl::CivilMonth month(day); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month)); + + absl::CivilYear year(month); + EXPECT_EQ("2015", absl::FormatCivilTime(year)); + + // + // Now assign from larger units -> smaller units + // + + month = absl::CivilMonth(year); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month)); + + day = absl::CivilDay(month); + EXPECT_EQ("2015-01-01", absl::FormatCivilTime(day)); + + hour = absl::CivilHour(day); + EXPECT_EQ("2015-01-01T00", absl::FormatCivilTime(hour)); + + minute = absl::CivilMinute(hour); + EXPECT_EQ("2015-01-01T00:00", absl::FormatCivilTime(minute)); + + second = absl::CivilSecond(minute); + EXPECT_EQ("2015-01-01T00:00:00", absl::FormatCivilTime(second)); +} + +// Metafunction to test whether difference is allowed between two types. +template <typename T1, typename T2> +struct HasDiff { + template <typename U1, typename U2> + static std::false_type test(...); + template <typename U1, typename U2> + static std::true_type test(decltype(std::declval<U1>() - std::declval<U2>())); + static constexpr bool value = decltype(test<T1, T2>(0))::value; +}; + +TEST(CivilTime, DisallowCrossAlignedDifference) { + // Difference is allowed between types with the same alignment. + static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value, ""); + static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value, ""); + static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value, ""); + static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value, ""); + static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value, ""); + static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value, ""); + + // Difference is disallowed between types with different alignments. + static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value, ""); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value, ""); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value, ""); + static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value, ""); + static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value, ""); + + static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value, ""); +} + +TEST(CivilTime, ValueSemantics) { + const absl::CivilHour a(2015, 1, 2, 3); + const absl::CivilHour b = a; + const absl::CivilHour c(b); + absl::CivilHour d; + d = c; + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(d)); +} + +TEST(CivilTime, Relational) { + // Tests that the alignment unit is ignored in comparison. + const absl::CivilYear year(2014); + const absl::CivilMonth month(year); + EXPECT_EQ(year, month); + +#define TEST_RELATIONAL(OLDER, YOUNGER) \ + do { \ + EXPECT_FALSE(OLDER < OLDER); \ + EXPECT_FALSE(OLDER > OLDER); \ + EXPECT_TRUE(OLDER >= OLDER); \ + EXPECT_TRUE(OLDER <= OLDER); \ + EXPECT_FALSE(YOUNGER < YOUNGER); \ + EXPECT_FALSE(YOUNGER > YOUNGER); \ + EXPECT_TRUE(YOUNGER >= YOUNGER); \ + EXPECT_TRUE(YOUNGER <= YOUNGER); \ + EXPECT_EQ(OLDER, OLDER); \ + EXPECT_NE(OLDER, YOUNGER); \ + EXPECT_LT(OLDER, YOUNGER); \ + EXPECT_LE(OLDER, YOUNGER); \ + EXPECT_GT(YOUNGER, OLDER); \ + EXPECT_GE(YOUNGER, OLDER); \ + } while (0) + + // Alignment is ignored in comparison (verified above), so CivilSecond is + // used to test comparison in all field positions. + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2015, 1, 1, 0, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2014, 2, 1, 0, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2014, 1, 2, 0, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 0, 0, 0), + absl::CivilSecond(2014, 1, 1, 1, 0, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 0, 0), + absl::CivilSecond(2014, 1, 1, 1, 1, 0)); + TEST_RELATIONAL(absl::CivilSecond(2014, 1, 1, 1, 1, 0), + absl::CivilSecond(2014, 1, 1, 1, 1, 1)); + + // Tests the relational operators of two different civil-time types. + TEST_RELATIONAL(absl::CivilDay(2014, 1, 1), + absl::CivilMinute(2014, 1, 1, 1, 1)); + TEST_RELATIONAL(absl::CivilDay(2014, 1, 1), + absl::CivilMonth(2014, 2)); + +#undef TEST_RELATIONAL +} + +TEST(CivilTime, Arithmetic) { + absl::CivilSecond second(2015, 1, 2, 3, 4, 5); + EXPECT_EQ("2015-01-02T03:04:06", absl::FormatCivilTime(second += 1)); + EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second + 1)); + EXPECT_EQ("2015-01-02T03:04:08", absl::FormatCivilTime(2 + second)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second - 1)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second -= 1)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(second++)); + EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(++second)); + EXPECT_EQ("2015-01-02T03:04:07", absl::FormatCivilTime(second--)); + EXPECT_EQ("2015-01-02T03:04:05", absl::FormatCivilTime(--second)); + + absl::CivilMinute minute(2015, 1, 2, 3, 4); + EXPECT_EQ("2015-01-02T03:05", absl::FormatCivilTime(minute += 1)); + EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute + 1)); + EXPECT_EQ("2015-01-02T03:07", absl::FormatCivilTime(2 + minute)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute - 1)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute -= 1)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(minute++)); + EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(++minute)); + EXPECT_EQ("2015-01-02T03:06", absl::FormatCivilTime(minute--)); + EXPECT_EQ("2015-01-02T03:04", absl::FormatCivilTime(--minute)); + + absl::CivilHour hour(2015, 1, 2, 3); + EXPECT_EQ("2015-01-02T04", absl::FormatCivilTime(hour += 1)); + EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour + 1)); + EXPECT_EQ("2015-01-02T06", absl::FormatCivilTime(2 + hour)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour - 1)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour -= 1)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(hour++)); + EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(++hour)); + EXPECT_EQ("2015-01-02T05", absl::FormatCivilTime(hour--)); + EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(--hour)); + + absl::CivilDay day(2015, 1, 2); + EXPECT_EQ("2015-01-03", absl::FormatCivilTime(day += 1)); + EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day + 1)); + EXPECT_EQ("2015-01-05", absl::FormatCivilTime(2 + day)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day - 1)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day -= 1)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(day++)); + EXPECT_EQ("2015-01-04", absl::FormatCivilTime(++day)); + EXPECT_EQ("2015-01-04", absl::FormatCivilTime(day--)); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(--day)); + + absl::CivilMonth month(2015, 1); + EXPECT_EQ("2015-02", absl::FormatCivilTime(month += 1)); + EXPECT_EQ("2015-03", absl::FormatCivilTime(month + 1)); + EXPECT_EQ("2015-04", absl::FormatCivilTime(2 + month)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month - 1)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month -= 1)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(month++)); + EXPECT_EQ("2015-03", absl::FormatCivilTime(++month)); + EXPECT_EQ("2015-03", absl::FormatCivilTime(month--)); + EXPECT_EQ("2015-01", absl::FormatCivilTime(--month)); + + absl::CivilYear year(2015); + EXPECT_EQ("2016", absl::FormatCivilTime(year += 1)); + EXPECT_EQ("2017", absl::FormatCivilTime(year + 1)); + EXPECT_EQ("2018", absl::FormatCivilTime(2 + year)); + EXPECT_EQ("2015", absl::FormatCivilTime(year - 1)); + EXPECT_EQ("2015", absl::FormatCivilTime(year -= 1)); + EXPECT_EQ("2015", absl::FormatCivilTime(year++)); + EXPECT_EQ("2017", absl::FormatCivilTime(++year)); + EXPECT_EQ("2017", absl::FormatCivilTime(year--)); + EXPECT_EQ("2015", absl::FormatCivilTime(--year)); +} + +TEST(CivilTime, ArithmeticLimits) { + const int kIntMax = std::numeric_limits<int>::max(); + const int kIntMin = std::numeric_limits<int>::min(); + + absl::CivilSecond second(1970, 1, 1, 0, 0, 0); + second += kIntMax; + EXPECT_EQ("2038-01-19T03:14:07", absl::FormatCivilTime(second)); + second -= kIntMax; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second)); + second += kIntMin; + EXPECT_EQ("1901-12-13T20:45:52", absl::FormatCivilTime(second)); + second -= kIntMin; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(second)); + + absl::CivilMinute minute(1970, 1, 1, 0, 0); + minute += kIntMax; + EXPECT_EQ("6053-01-23T02:07", absl::FormatCivilTime(minute)); + minute -= kIntMax; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute)); + minute += kIntMin; + EXPECT_EQ("-2114-12-08T21:52", absl::FormatCivilTime(minute)); + minute -= kIntMin; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(minute)); + + absl::CivilHour hour(1970, 1, 1, 0); + hour += kIntMax; + EXPECT_EQ("246953-10-09T07", absl::FormatCivilTime(hour)); + hour -= kIntMax; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour)); + hour += kIntMin; + EXPECT_EQ("-243014-03-24T16", absl::FormatCivilTime(hour)); + hour -= kIntMin; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hour)); + + absl::CivilDay day(1970, 1, 1); + day += kIntMax; + EXPECT_EQ("5881580-07-11", absl::FormatCivilTime(day)); + day -= kIntMax; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day)); + day += kIntMin; + EXPECT_EQ("-5877641-06-23", absl::FormatCivilTime(day)); + day -= kIntMin; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(day)); + + absl::CivilMonth month(1970, 1); + month += kIntMax; + EXPECT_EQ("178958940-08", absl::FormatCivilTime(month)); + month -= kIntMax; + EXPECT_EQ("1970-01", absl::FormatCivilTime(month)); + month += kIntMin; + EXPECT_EQ("-178955001-05", absl::FormatCivilTime(month)); + month -= kIntMin; + EXPECT_EQ("1970-01", absl::FormatCivilTime(month)); + + absl::CivilYear year(0); + year += kIntMax; + EXPECT_EQ("2147483647", absl::FormatCivilTime(year)); + year -= kIntMax; + EXPECT_EQ("0", absl::FormatCivilTime(year)); + year += kIntMin; + EXPECT_EQ("-2147483648", absl::FormatCivilTime(year)); + year -= kIntMin; + EXPECT_EQ("0", absl::FormatCivilTime(year)); +} + +TEST(CivilTime, Difference) { + absl::CivilSecond second(2015, 1, 2, 3, 4, 5); + EXPECT_EQ(0, second - second); + EXPECT_EQ(10, (second + 10) - second); + EXPECT_EQ(-10, (second - 10) - second); + + absl::CivilMinute minute(2015, 1, 2, 3, 4); + EXPECT_EQ(0, minute - minute); + EXPECT_EQ(10, (minute + 10) - minute); + EXPECT_EQ(-10, (minute - 10) - minute); + + absl::CivilHour hour(2015, 1, 2, 3); + EXPECT_EQ(0, hour - hour); + EXPECT_EQ(10, (hour + 10) - hour); + EXPECT_EQ(-10, (hour - 10) - hour); + + absl::CivilDay day(2015, 1, 2); + EXPECT_EQ(0, day - day); + EXPECT_EQ(10, (day + 10) - day); + EXPECT_EQ(-10, (day - 10) - day); + + absl::CivilMonth month(2015, 1); + EXPECT_EQ(0, month - month); + EXPECT_EQ(10, (month + 10) - month); + EXPECT_EQ(-10, (month - 10) - month); + + absl::CivilYear year(2015); + EXPECT_EQ(0, year - year); + EXPECT_EQ(10, (year + 10) - year); + EXPECT_EQ(-10, (year - 10) - year); +} + +TEST(CivilTime, DifferenceLimits) { + const absl::civil_diff_t kDiffMax = + std::numeric_limits<absl::civil_diff_t>::max(); + const absl::civil_diff_t kDiffMin = + std::numeric_limits<absl::civil_diff_t>::min(); + + // Check day arithmetic at the end of the year range. + const absl::CivilDay max_day(kDiffMax, 12, 31); + EXPECT_EQ(1, max_day - (max_day - 1)); + EXPECT_EQ(-1, (max_day - 1) - max_day); + + // Check day arithmetic at the start of the year range. + const absl::CivilDay min_day(kDiffMin, 1, 1); + EXPECT_EQ(1, (min_day + 1) - min_day); + EXPECT_EQ(-1, min_day - (min_day + 1)); + + // Check the limits of the return value. + const absl::CivilDay d1(1970, 1, 1); + const absl::CivilDay d2(25252734927768524, 7, 27); + EXPECT_EQ(kDiffMax, d2 - d1); + EXPECT_EQ(kDiffMin, d1 - (d2 + 1)); +} + +TEST(CivilTime, Properties) { + absl::CivilSecond ss(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, ss.year()); + EXPECT_EQ(2, ss.month()); + EXPECT_EQ(3, ss.day()); + EXPECT_EQ(4, ss.hour()); + EXPECT_EQ(5, ss.minute()); + EXPECT_EQ(6, ss.second()); + + absl::CivilMinute mm(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, mm.year()); + EXPECT_EQ(2, mm.month()); + EXPECT_EQ(3, mm.day()); + EXPECT_EQ(4, mm.hour()); + EXPECT_EQ(5, mm.minute()); + EXPECT_EQ(0, mm.second()); + + absl::CivilHour hh(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, hh.year()); + EXPECT_EQ(2, hh.month()); + EXPECT_EQ(3, hh.day()); + EXPECT_EQ(4, hh.hour()); + EXPECT_EQ(0, hh.minute()); + EXPECT_EQ(0, hh.second()); + + absl::CivilDay d(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, d.year()); + EXPECT_EQ(2, d.month()); + EXPECT_EQ(3, d.day()); + EXPECT_EQ(0, d.hour()); + EXPECT_EQ(0, d.minute()); + EXPECT_EQ(0, d.second()); + + absl::CivilMonth m(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, m.year()); + EXPECT_EQ(2, m.month()); + EXPECT_EQ(1, m.day()); + EXPECT_EQ(0, m.hour()); + EXPECT_EQ(0, m.minute()); + EXPECT_EQ(0, m.second()); + + absl::CivilYear y(2015, 2, 3, 4, 5, 6); + EXPECT_EQ(2015, y.year()); + EXPECT_EQ(1, y.month()); + EXPECT_EQ(1, y.day()); + EXPECT_EQ(0, y.hour()); + EXPECT_EQ(0, y.minute()); + EXPECT_EQ(0, y.second()); +} + +TEST(CivilTime, Format) { + absl::CivilSecond ss; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss)); + + absl::CivilMinute mm; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm)); + + absl::CivilHour hh; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh)); + + absl::CivilDay d; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d)); + + absl::CivilMonth m; + EXPECT_EQ("1970-01", absl::FormatCivilTime(m)); + + absl::CivilYear y; + EXPECT_EQ("1970", absl::FormatCivilTime(y)); +} + +TEST(CivilTime, FormatAndParseLenient) { + absl::CivilSecond ss; + EXPECT_EQ("1970-01-01T00:00:00", absl::FormatCivilTime(ss)); + + absl::CivilMinute mm; + EXPECT_EQ("1970-01-01T00:00", absl::FormatCivilTime(mm)); + + absl::CivilHour hh; + EXPECT_EQ("1970-01-01T00", absl::FormatCivilTime(hh)); + + absl::CivilDay d; + EXPECT_EQ("1970-01-01", absl::FormatCivilTime(d)); + + absl::CivilMonth m; + EXPECT_EQ("1970-01", absl::FormatCivilTime(m)); + + absl::CivilYear y; + EXPECT_EQ("1970", absl::FormatCivilTime(y)); +} + +TEST(CivilTime, OutputStream) { + absl::CivilSecond cs(2016, 2, 3, 4, 5, 6); + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilYear(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016.................X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilMonth(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02..............X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilDay(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03...........X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilHour(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03T04........X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilMinute(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03T04:05.....X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::CivilSecond(cs); + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..2016-02-03T04:05:06..X..", ss.str()); + } + { + std::stringstream ss; + ss << std::left << std::setfill('.'); + ss << std::setw(3) << 'X'; + ss << std::setw(21) << absl::Weekday::wednesday; + ss << std::setw(3) << 'X'; + EXPECT_EQ("X..Wednesday............X..", ss.str()); + } +} + +TEST(CivilTime, Weekday) { + absl::CivilDay d(1970, 1, 1); + EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(d)) << d; + + // We used to get this wrong for years < -30. + d = absl::CivilDay(-31, 12, 24); + EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(d)) << d; +} + +TEST(CivilTime, NextPrevWeekday) { + // Jan 1, 1970 was a Thursday. + const absl::CivilDay thursday(1970, 1, 1); + + // Thursday -> Thursday + absl::CivilDay d = absl::NextWeekday(thursday, absl::Weekday::thursday); + EXPECT_EQ(7, d - thursday) << d; + EXPECT_EQ(d - 14, absl::PrevWeekday(thursday, absl::Weekday::thursday)); + + // Thursday -> Friday + d = absl::NextWeekday(thursday, absl::Weekday::friday); + EXPECT_EQ(1, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::friday)); + + // Thursday -> Saturday + d = absl::NextWeekday(thursday, absl::Weekday::saturday); + EXPECT_EQ(2, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::saturday)); + + // Thursday -> Sunday + d = absl::NextWeekday(thursday, absl::Weekday::sunday); + EXPECT_EQ(3, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::sunday)); + + // Thursday -> Monday + d = absl::NextWeekday(thursday, absl::Weekday::monday); + EXPECT_EQ(4, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::monday)); + + // Thursday -> Tuesday + d = absl::NextWeekday(thursday, absl::Weekday::tuesday); + EXPECT_EQ(5, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::tuesday)); + + // Thursday -> Wednesday + d = absl::NextWeekday(thursday, absl::Weekday::wednesday); + EXPECT_EQ(6, d - thursday) << d; + EXPECT_EQ(d - 7, absl::PrevWeekday(thursday, absl::Weekday::wednesday)); +} + +// NOTE: Run this with --copt=-ftrapv to detect overflow problems. +TEST(CivilTime, DifferenceWithHugeYear) { + absl::CivilDay d1(9223372036854775807, 1, 1); + absl::CivilDay d2(9223372036854775807, 12, 31); + EXPECT_EQ(364, d2 - d1); + + d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1); + d2 = absl::CivilDay(-9223372036854775807 - 1, 12, 31); + EXPECT_EQ(365, d2 - d1); + + // Check the limits of the return value at the end of the year range. + d1 = absl::CivilDay(9223372036854775807, 1, 1); + d2 = absl::CivilDay(9198119301927009252, 6, 6); + EXPECT_EQ(9223372036854775807, d1 - d2); + d2 = d2 - 1; + EXPECT_EQ(-9223372036854775807 - 1, d2 - d1); + + // Check the limits of the return value at the start of the year range. + d1 = absl::CivilDay(-9223372036854775807 - 1, 1, 1); + d2 = absl::CivilDay(-9198119301927009254, 7, 28); + EXPECT_EQ(9223372036854775807, d2 - d1); + d2 = d2 + 1; + EXPECT_EQ(-9223372036854775807 - 1, d1 - d2); + + // Check the limits of the return value from either side of year 0. + d1 = absl::CivilDay(-12626367463883278, 9, 3); + d2 = absl::CivilDay(12626367463883277, 3, 28); + EXPECT_EQ(9223372036854775807, d2 - d1); + d2 = d2 + 1; + EXPECT_EQ(-9223372036854775807 - 1, d1 - d2); +} + +// NOTE: Run this with --copt=-ftrapv to detect overflow problems. +TEST(CivilTime, DifferenceNoIntermediateOverflow) { + // The difference up to the minute field would be below the minimum + // int64_t, but the 52 extra seconds brings us back to the minimum. + absl::CivilSecond s1(-292277022657, 1, 27, 8, 29 - 1, 52); + absl::CivilSecond s2(1970, 1, 1, 0, 0 - 1, 0); + EXPECT_EQ(-9223372036854775807 - 1, s1 - s2); + + // The difference up to the minute field would be above the maximum + // int64_t, but the -53 extra seconds brings us back to the maximum. + s1 = absl::CivilSecond(292277026596, 12, 4, 15, 30, 7 - 7); + s2 = absl::CivilSecond(1970, 1, 1, 0, 0, 0 - 7); + EXPECT_EQ(9223372036854775807, s1 - s2); +} + +TEST(CivilTime, NormalizeSimpleOverflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 59 + 1); + EXPECT_EQ("2013-11-15T16:33:00", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 59 + 1, 14); + EXPECT_EQ("2013-11-15T17:00:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 23 + 1, 32, 14); + EXPECT_EQ("2013-11-16T00:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 30 + 1, 16, 32, 14); + EXPECT_EQ("2013-12-01T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 12 + 1, 15, 16, 32, 14); + EXPECT_EQ("2014-01-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeSimpleUnderflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 0 - 1); + EXPECT_EQ("2013-11-15T16:31:59", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 0 - 1, 14); + EXPECT_EQ("2013-11-15T15:59:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 0 - 1, 32, 14); + EXPECT_EQ("2013-11-14T23:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 1 - 1, 16, 32, 14); + EXPECT_EQ("2013-10-31T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 1 - 1, 15, 16, 32, 14); + EXPECT_EQ("2012-12-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeMultipleOverflow) { + absl::CivilSecond cs(2013, 12, 31, 23, 59, 59 + 1); + EXPECT_EQ("2014-01-01T00:00:00", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeMultipleUnderflow) { + absl::CivilSecond cs(2014, 1, 1, 0, 0, 0 - 1); + EXPECT_EQ("2013-12-31T23:59:59", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeOverflowLimits) { + absl::CivilSecond cs; + + const int kintmax = std::numeric_limits<int>::max(); + cs = absl::CivilSecond(0, kintmax, kintmax, kintmax, kintmax, kintmax); + EXPECT_EQ("185085715-11-27T12:21:07", absl::FormatCivilTime(cs)); + + const int kintmin = std::numeric_limits<int>::min(); + cs = absl::CivilSecond(0, kintmin, kintmin, kintmin, kintmin, kintmin); + EXPECT_EQ("-185085717-10-31T10:37:52", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeComplexOverflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 + 123456789); + EXPECT_EQ("2017-10-14T14:05:23", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 32 + 1234567, 14); + EXPECT_EQ("2016-03-22T00:39:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16 + 123456, 32, 14); + EXPECT_EQ("2027-12-16T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15 + 1234, 16, 32, 14); + EXPECT_EQ("2017-04-02T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 + 123, 15, 16, 32, 14); + EXPECT_EQ("2024-02-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeComplexUnderflow) { + absl::CivilSecond cs; + cs = absl::CivilSecond(1999, 3, 0, 0, 0, 0); // year 400 + EXPECT_EQ("1999-02-28T00:00:00", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 32, 14 - 123456789); + EXPECT_EQ("2009-12-17T18:59:05", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16, 32 - 1234567, 14); + EXPECT_EQ("2011-07-12T08:25:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15, 16 - 123456, 32, 14); + EXPECT_EQ("1999-10-16T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11, 15 - 1234, 16, 32, 14); + EXPECT_EQ("2010-06-30T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 - 123, 15, 16, 32, 14); + EXPECT_EQ("2003-08-15T16:32:14", absl::FormatCivilTime(cs)); +} + +TEST(CivilTime, NormalizeMishmash) { + absl::CivilSecond cs; + cs = absl::CivilSecond(2013, 11 - 123, 15 + 1234, 16 - 123456, 32 + 1234567, + 14 - 123456789); + EXPECT_EQ("1991-05-09T03:06:05", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 + 123, 15 - 1234, 16 + 123456, 32 - 1234567, + 14 + 123456789); + EXPECT_EQ("2036-05-24T05:58:23", absl::FormatCivilTime(cs)); + + cs = absl::CivilSecond(2013, 11, -146097 + 1, 16, 32, 14); + EXPECT_EQ("1613-11-01T16:32:14", absl::FormatCivilTime(cs)); + cs = absl::CivilSecond(2013, 11 + 400 * 12, -146097 + 1, 16, 32, 14); + EXPECT_EQ("2013-11-01T16:32:14", absl::FormatCivilTime(cs)); +} + +// Convert all the days from 1970-1-1 to 1970-1-146097 (aka 2369-12-31) +// and check that they normalize to the expected time. 146097 days span +// the 400-year Gregorian cycle used during normalization. +TEST(CivilTime, NormalizeAllTheDays) { + absl::CivilDay expected(1970, 1, 1); + for (int day = 1; day <= 146097; ++day) { + absl::CivilSecond cs(1970, 1, day, 0, 0, 0); + EXPECT_EQ(expected, cs); + ++expected; + } +} + +TEST(CivilTime, NormalizeWithHugeYear) { + absl::CivilMonth c(9223372036854775807, 1); + EXPECT_EQ("9223372036854775807-01", absl::FormatCivilTime(c)); + c = c - 1; // Causes normalization + EXPECT_EQ("9223372036854775806-12", absl::FormatCivilTime(c)); + + c = absl::CivilMonth(-9223372036854775807 - 1, 1); + EXPECT_EQ("-9223372036854775808-01", absl::FormatCivilTime(c)); + c = c + 12; // Causes normalization + EXPECT_EQ("-9223372036854775807-01", absl::FormatCivilTime(c)); +} + +TEST(CivilTime, LeapYears) { + const absl::CivilSecond s1(2013, 2, 28 + 1, 0, 0, 0); + EXPECT_EQ("2013-03-01T00:00:00", absl::FormatCivilTime(s1)); + + const absl::CivilSecond s2(2012, 2, 28 + 1, 0, 0, 0); + EXPECT_EQ("2012-02-29T00:00:00", absl::FormatCivilTime(s2)); + + const absl::CivilSecond s3(1900, 2, 28 + 1, 0, 0, 0); + EXPECT_EQ("1900-03-01T00:00:00", absl::FormatCivilTime(s3)); + + const struct { + int year; + int days; + struct { + int month; + int day; + } leap_day; // The date of the day after Feb 28. + } kLeapYearTable[]{ + {1900, 365, {3, 1}}, + {1999, 365, {3, 1}}, + {2000, 366, {2, 29}}, // leap year + {2001, 365, {3, 1}}, + {2002, 365, {3, 1}}, + {2003, 365, {3, 1}}, + {2004, 366, {2, 29}}, // leap year + {2005, 365, {3, 1}}, + {2006, 365, {3, 1}}, + {2007, 365, {3, 1}}, + {2008, 366, {2, 29}}, // leap year + {2009, 365, {3, 1}}, + {2100, 365, {3, 1}}, + }; + + for (int i = 0; i < ABSL_ARRAYSIZE(kLeapYearTable); ++i) { + const int y = kLeapYearTable[i].year; + const int m = kLeapYearTable[i].leap_day.month; + const int d = kLeapYearTable[i].leap_day.day; + const int n = kLeapYearTable[i].days; + + // Tests incrementing through the leap day. + const absl::CivilDay feb28(y, 2, 28); + const absl::CivilDay next_day = feb28 + 1; + EXPECT_EQ(m, next_day.month()); + EXPECT_EQ(d, next_day.day()); + + // Tests difference in days of leap years. + const absl::CivilYear year(feb28); + const absl::CivilYear next_year = year + 1; + EXPECT_EQ(n, absl::CivilDay(next_year) - absl::CivilDay(year)); + } +} + +TEST(CivilTime, FirstThursdayInMonth) { + const absl::CivilDay nov1(2014, 11, 1); + const absl::CivilDay thursday = + absl::PrevWeekday(nov1, absl::Weekday::thursday) + 7; + EXPECT_EQ("2014-11-06", absl::FormatCivilTime(thursday)); + + // Bonus: Date of Thanksgiving in the United States + // Rule: Fourth Thursday of November + const absl::CivilDay thanksgiving = thursday + 7 * 3; + EXPECT_EQ("2014-11-27", absl::FormatCivilTime(thanksgiving)); +} + +TEST(CivilTime, DocumentationExample) { + absl::CivilSecond second(2015, 6, 28, 1, 2, 3); // 2015-06-28 01:02:03 + absl::CivilMinute minute(second); // 2015-06-28 01:02:00 + absl::CivilDay day(minute); // 2015-06-28 00:00:00 + + second -= 1; // 2015-06-28 01:02:02 + --second; // 2015-06-28 01:02:01 + EXPECT_EQ(minute, second - 1); // Comparison between types + EXPECT_LT(minute, second); + + // int diff = second - minute; // ERROR: Mixed types, won't compile + + absl::CivilDay june_1(2015, 6, 1); // Pass fields to c'tor. + int diff = day - june_1; // Num days between 'day' and June 1 + EXPECT_EQ(27, diff); + + // Fields smaller than alignment are floored to their minimum value. + absl::CivilDay day_floor(2015, 1, 2, 9, 9, 9); + EXPECT_EQ(0, day_floor.hour()); // 09:09:09 is floored + EXPECT_EQ(absl::CivilDay(2015, 1, 2), day_floor); + + // Unspecified fields default to their minium value + absl::CivilDay day_default(2015); // Defaults to Jan 1 + EXPECT_EQ(absl::CivilDay(2015, 1, 1), day_default); + + // Iterates all the days of June. + absl::CivilMonth june(day); // CivilDay -> CivilMonth + absl::CivilMonth july = june + 1; + for (absl::CivilDay day = june_1; day < july; ++day) { + // ... + } +} + +} // namespace diff --git a/absl/time/clock.cc b/absl/time/clock.cc index 3b1e8739..2915d78b 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -34,7 +34,7 @@ #include "absl/base/thread_annotations.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { Time Now() { // TODO(bww): Get a timespec instead so we don't have to divide. int64_t n = absl::GetCurrentTimeNanos(); @@ -44,7 +44,7 @@ Time Now() { } return time_internal::FromUnixDuration(absl::Nanoseconds(n)); } -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl // Decide if we should use the fast GetCurrentTimeNanos() algorithm @@ -59,10 +59,8 @@ Time Now() { #endif #endif -#if defined(__APPLE__) -#include "absl/time/internal/get_current_time_ios.inc" -#elif defined(_WIN32) -#include "absl/time/internal/get_current_time_windows.inc" +#if defined(__APPLE__) || defined(_WIN32) +#include "absl/time/internal/get_current_time_chrono.inc" #else #include "absl/time/internal/get_current_time_posix.inc" #endif @@ -75,11 +73,11 @@ Time Now() { #if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { int64_t GetCurrentTimeNanos() { return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); } -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #else // Use the cyclecounter-based implementation below. @@ -97,7 +95,7 @@ static int64_t stats_slow_paths; static int64_t stats_fast_slow_paths; namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { // This is a friend wrapper around UnscaledCycleClock::Now() // (needed to access UnscaledCycleClock). @@ -522,12 +520,12 @@ static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns, return estimated_base_ns; } -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace { // Returns the maximum duration that SleepOnce() can sleep for. @@ -555,7 +553,7 @@ void SleepOnce(absl::Duration to_sleep) { } } // namespace -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl extern "C" { diff --git a/absl/time/clock.h b/absl/time/clock.h index 15f587c5..b2941126 100644 --- a/absl/time/clock.h +++ b/absl/time/clock.h @@ -26,7 +26,7 @@ #include "absl/time/time.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { // Now() // @@ -50,7 +50,7 @@ int64_t GetCurrentTimeNanos(); // * Returns immediately when passed a nonpositive duration. void SleepFor(absl::Duration duration); -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl // ----------------------------------------------------------------------------- diff --git a/absl/time/clock_test.cc b/absl/time/clock_test.cc index f143c036..707166d0 100644 --- a/absl/time/clock_test.cc +++ b/absl/time/clock_test.cc @@ -35,36 +35,84 @@ TEST(Time, Now) { EXPECT_GE(after, now); } -TEST(SleepForTest, BasicSanity) { - absl::Duration sleep_time = absl::Milliseconds(2500); - absl::Time start = absl::Now(); - absl::SleepFor(sleep_time); - absl::Time end = absl::Now(); - EXPECT_LE(sleep_time - absl::Milliseconds(100), end - start); - EXPECT_GE(sleep_time + absl::Milliseconds(200), end - start); -} +enum class AlarmPolicy { kWithoutAlarm, kWithAlarm }; -#ifdef ABSL_HAVE_ALARM -// Helper for test SleepFor. +#if defined(ABSL_HAVE_ALARM) bool alarm_handler_invoked = false; + void AlarmHandler(int signo) { ASSERT_EQ(signo, SIGALRM); alarm_handler_invoked = true; } +#endif + +// Does SleepFor(d) take between lower_bound and upper_bound at least +// once between now and (now + timeout)? If requested (and supported), +// add an alarm for the middle of the sleep period and expect it to fire. +bool SleepForBounded(absl::Duration d, absl::Duration lower_bound, + absl::Duration upper_bound, absl::Duration timeout, + AlarmPolicy alarm_policy, int* attempts) { + const absl::Time deadline = absl::Now() + timeout; + while (absl::Now() < deadline) { +#if defined(ABSL_HAVE_ALARM) + sig_t old_alarm = SIG_DFL; + if (alarm_policy == AlarmPolicy::kWithAlarm) { + alarm_handler_invoked = false; + old_alarm = signal(SIGALRM, AlarmHandler); + alarm(absl::ToInt64Seconds(d / 2)); + } +#else + EXPECT_EQ(alarm_policy, AlarmPolicy::kWithoutAlarm); +#endif + ++*attempts; + absl::Time start = absl::Now(); + absl::SleepFor(d); + absl::Duration actual = absl::Now() - start; +#if defined(ABSL_HAVE_ALARM) + if (alarm_policy == AlarmPolicy::kWithAlarm) { + signal(SIGALRM, old_alarm); + if (!alarm_handler_invoked) continue; + } +#endif + if (lower_bound <= actual && actual <= upper_bound) { + return true; // yes, the SleepFor() was correctly bounded + } + } + return false; +} -TEST(SleepForTest, AlarmSupport) { - alarm_handler_invoked = false; - sig_t old_alarm = signal(SIGALRM, AlarmHandler); - alarm(2); - absl::Duration sleep_time = absl::Milliseconds(3500); - absl::Time start = absl::Now(); - absl::SleepFor(sleep_time); - absl::Time end = absl::Now(); - EXPECT_TRUE(alarm_handler_invoked); - EXPECT_LE(sleep_time - absl::Milliseconds(100), end - start); - EXPECT_GE(sleep_time + absl::Milliseconds(200), end - start); - signal(SIGALRM, old_alarm); +testing::AssertionResult AssertSleepForBounded(absl::Duration d, + absl::Duration early, + absl::Duration late, + absl::Duration timeout, + AlarmPolicy alarm_policy) { + const absl::Duration lower_bound = d - early; + const absl::Duration upper_bound = d + late; + int attempts = 0; + if (SleepForBounded(d, lower_bound, upper_bound, timeout, alarm_policy, + &attempts)) { + return testing::AssertionSuccess(); + } + return testing::AssertionFailure() + << "SleepFor(" << d << ") did not return within [" << lower_bound + << ":" << upper_bound << "] in " << attempts << " attempt" + << (attempts == 1 ? "" : "s") << " over " << timeout + << (alarm_policy == AlarmPolicy::kWithAlarm ? " with" : " without") + << " an alarm"; +} + +// Tests that SleepFor() returns neither too early nor too late. +TEST(SleepFor, Bounded) { + const absl::Duration d = absl::Milliseconds(2500); + const absl::Duration early = absl::Milliseconds(100); + const absl::Duration late = absl::Milliseconds(300); + const absl::Duration timeout = 48 * d; + EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, + AlarmPolicy::kWithoutAlarm)); +#if defined(ABSL_HAVE_ALARM) + EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, + AlarmPolicy::kWithAlarm)); +#endif } -#endif // ABSL_HAVE_ALARM } // namespace diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 2271f7da..04669709 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -67,7 +67,7 @@ #include "absl/time/time.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace { @@ -79,10 +79,16 @@ constexpr int64_t kint64min = std::numeric_limits<int64_t>::min(); // Can't use std::isinfinite() because it doesn't exist on windows. inline bool IsFinite(double d) { + if (std::isnan(d)) return false; return d != std::numeric_limits<double>::infinity() && d != -std::numeric_limits<double>::infinity(); } +inline bool IsValidDivisor(double d) { + if (std::isnan(d)) return false; + return d != 0.0; +} + // Can't use std::round() because it is only available in C++11. // Note that we ignore the possibility of floating-point over/underflow. template <typename Double> @@ -456,7 +462,7 @@ Duration& Duration::operator/=(int64_t r) { } Duration& Duration::operator/=(double r) { - if (time_internal::IsInfiniteDuration(*this) || r == 0.0) { + if (time_internal::IsInfiniteDuration(*this) || !IsValidDivisor(r)) { const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0); return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); } @@ -667,7 +673,7 @@ std::chrono::hours ToChronoHours(Duration d) { } // -// To/From std::string formatting. +// To/From string formatting. // namespace { @@ -745,7 +751,7 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { } // namespace // From Go's doc at http://golang.org/pkg/time/#Duration.String -// [FormatDuration] returns a std::string representing the duration in the +// [FormatDuration] returns a string representing the duration in the // form "72h3m0.5s". Leading zero units are omitted. As a special // case, durations less than one second format use a smaller unit // (milli-, micro-, or nanoseconds) to ensure that the leading digit @@ -788,8 +794,8 @@ std::string FormatDuration(Duration d) { namespace { // A helper for ParseDuration() that parses a leading number from the given -// std::string and stores the result in *int_part/*frac_part/*frac_scale. The -// given std::string pointer is modified to point to the first unconsumed char. +// string and stores the result in *int_part/*frac_part/*frac_scale. The +// given string pointer is modified to point to the first unconsumed char. bool ConsumeDurationNumber(const char** dpp, int64_t* int_part, int64_t* frac_part, int64_t* frac_scale) { *int_part = 0; @@ -817,8 +823,8 @@ bool ConsumeDurationNumber(const char** dpp, int64_t* int_part, } // A helper for ParseDuration() that parses a leading unit designator (e.g., -// ns, us, ms, s, m, h) from the given std::string and stores the resulting unit -// in "*unit". The given std::string pointer is modified to point to the first +// ns, us, ms, s, m, h) from the given string and stores the resulting unit +// in "*unit". The given string pointer is modified to point to the first // unconsumed char. bool ConsumeDurationUnit(const char** start, Duration* unit) { const char *s = *start; @@ -851,7 +857,7 @@ bool ConsumeDurationUnit(const char** start, Duration* unit) { } // namespace // From Go's doc at http://golang.org/pkg/time/#ParseDuration -// [ParseDuration] parses a duration std::string. A duration std::string is +// [ParseDuration] parses a duration string. A duration string is // a possibly signed sequence of decimal numbers, each with optional // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" "ms", "s", "m", "h". @@ -896,14 +902,11 @@ bool ParseDuration(const std::string& dur_string, Duration* d) { *d = dur; return true; } - bool ParseFlag(const std::string& text, Duration* dst, std::string* ) { return ParseDuration(text, dst); } -std::string UnparseFlag(Duration d) { - return FormatDuration(d); -} +std::string UnparseFlag(Duration d) { return FormatDuration(d); } -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/duration_benchmark.cc b/absl/time/duration_benchmark.cc index 54f89a1f..d5657bd5 100644 --- a/absl/time/duration_benchmark.cc +++ b/absl/time/duration_benchmark.cc @@ -27,47 +27,113 @@ namespace { // void BM_Duration_Factory_Nanoseconds(benchmark::State& state) { + int64_t i = 0; while (state.KeepRunning()) { - benchmark::DoNotOptimize(absl::Nanoseconds(1)); + benchmark::DoNotOptimize(absl::Nanoseconds(i)); + i += 314159; } } BENCHMARK(BM_Duration_Factory_Nanoseconds); void BM_Duration_Factory_Microseconds(benchmark::State& state) { + int64_t i = 0; while (state.KeepRunning()) { - benchmark::DoNotOptimize(absl::Microseconds(1)); + benchmark::DoNotOptimize(absl::Microseconds(i)); + i += 314; } } BENCHMARK(BM_Duration_Factory_Microseconds); void BM_Duration_Factory_Milliseconds(benchmark::State& state) { + int64_t i = 0; while (state.KeepRunning()) { - benchmark::DoNotOptimize(absl::Milliseconds(1)); + benchmark::DoNotOptimize(absl::Milliseconds(i)); + i += 1; } } BENCHMARK(BM_Duration_Factory_Milliseconds); void BM_Duration_Factory_Seconds(benchmark::State& state) { + int64_t i = 0; while (state.KeepRunning()) { - benchmark::DoNotOptimize(absl::Seconds(1)); + benchmark::DoNotOptimize(absl::Seconds(i)); + i += 1; } } BENCHMARK(BM_Duration_Factory_Seconds); void BM_Duration_Factory_Minutes(benchmark::State& state) { + int64_t i = 0; while (state.KeepRunning()) { - benchmark::DoNotOptimize(absl::Minutes(1)); + benchmark::DoNotOptimize(absl::Minutes(i)); + i += 1; } } BENCHMARK(BM_Duration_Factory_Minutes); void BM_Duration_Factory_Hours(benchmark::State& state) { + int64_t i = 0; while (state.KeepRunning()) { - benchmark::DoNotOptimize(absl::Hours(1)); + benchmark::DoNotOptimize(absl::Hours(i)); + i += 1; } } BENCHMARK(BM_Duration_Factory_Hours); +void BM_Duration_Factory_DoubleNanoseconds(benchmark::State& state) { + double d = 1; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Nanoseconds(d)); + d = d * 1.00000001 + 1; + } +} +BENCHMARK(BM_Duration_Factory_DoubleNanoseconds); + +void BM_Duration_Factory_DoubleMicroseconds(benchmark::State& state) { + double d = 1e-3; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Microseconds(d)); + d = d * 1.00000001 + 1e-3; + } +} +BENCHMARK(BM_Duration_Factory_DoubleMicroseconds); + +void BM_Duration_Factory_DoubleMilliseconds(benchmark::State& state) { + double d = 1e-6; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Milliseconds(d)); + d = d * 1.00000001 + 1e-6; + } +} +BENCHMARK(BM_Duration_Factory_DoubleMilliseconds); + +void BM_Duration_Factory_DoubleSeconds(benchmark::State& state) { + double d = 1e-9; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Seconds(d)); + d = d * 1.00000001 + 1e-9; + } +} +BENCHMARK(BM_Duration_Factory_DoubleSeconds); + +void BM_Duration_Factory_DoubleMinutes(benchmark::State& state) { + double d = 1e-9; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Minutes(d)); + d = d * 1.00000001 + 1e-9; + } +} +BENCHMARK(BM_Duration_Factory_DoubleMinutes); + +void BM_Duration_Factory_DoubleHours(benchmark::State& state) { + double d = 1e-9; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Hours(d)); + d = d * 1.00000001 + 1e-9; + } +} +BENCHMARK(BM_Duration_Factory_DoubleHours); + // // Arithmetic // diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 704684ed..61f3c5c0 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc @@ -16,7 +16,9 @@ #include <cmath> #include <cstdint> #include <ctime> +#include <iomanip> #include <limits> +#include <random> #include <string> #include "gmock/gmock.h" @@ -54,6 +56,17 @@ MATCHER_P(TimevalMatcher, tv, "") { return false; } +TEST(Duration, ConstExpr) { + constexpr absl::Duration d0 = absl::ZeroDuration(); + static_assert(d0 == absl::ZeroDuration(), "ZeroDuration()"); + constexpr absl::Duration d1 = absl::Seconds(1); + static_assert(d1 == absl::Seconds(1), "Seconds(1)"); + static_assert(d1 != absl::ZeroDuration(), "Seconds(1)"); + constexpr absl::Duration d2 = absl::InfiniteDuration(); + static_assert(d2 == absl::InfiniteDuration(), "InfiniteDuration()"); + static_assert(d2 != absl::ZeroDuration(), "InfiniteDuration()"); +} + TEST(Duration, ValueSemantics) { // If this compiles, the test passes. constexpr absl::Duration a; // Default construction @@ -105,22 +118,22 @@ TEST(Duration, Factories) { } TEST(Duration, ToConversion) { -#define TEST_DURATION_CONVERSION(UNIT) \ - do { \ - const absl::Duration d = absl::UNIT(1.5); \ - const absl::Duration z = absl::ZeroDuration(); \ - const absl::Duration inf = absl::InfiniteDuration(); \ - const double dbl_inf = std::numeric_limits<double>::infinity(); \ - EXPECT_EQ(kint64min, absl::ToInt64##UNIT(-inf)); \ - EXPECT_EQ(-1, absl::ToInt64##UNIT(-d)); \ - EXPECT_EQ(0, absl::ToInt64##UNIT(z)); \ - EXPECT_EQ(1, absl::ToInt64##UNIT(d)); \ - EXPECT_EQ(kint64max, absl::ToInt64##UNIT(inf)); \ - EXPECT_EQ(-dbl_inf, absl::ToDouble##UNIT(-inf)); \ - EXPECT_EQ(-1.5, absl::ToDouble##UNIT(-d)); \ - EXPECT_EQ(0, absl::ToDouble##UNIT(z)); \ - EXPECT_EQ(1.5, absl::ToDouble##UNIT(d)); \ - EXPECT_EQ(dbl_inf, absl::ToDouble##UNIT(inf)); \ +#define TEST_DURATION_CONVERSION(UNIT) \ + do { \ + const absl::Duration d = absl::UNIT(1.5); \ + constexpr absl::Duration z = absl::ZeroDuration(); \ + constexpr absl::Duration inf = absl::InfiniteDuration(); \ + constexpr double dbl_inf = std::numeric_limits<double>::infinity(); \ + EXPECT_EQ(kint64min, absl::ToInt64##UNIT(-inf)); \ + EXPECT_EQ(-1, absl::ToInt64##UNIT(-d)); \ + EXPECT_EQ(0, absl::ToInt64##UNIT(z)); \ + EXPECT_EQ(1, absl::ToInt64##UNIT(d)); \ + EXPECT_EQ(kint64max, absl::ToInt64##UNIT(inf)); \ + EXPECT_EQ(-dbl_inf, absl::ToDouble##UNIT(-inf)); \ + EXPECT_EQ(-1.5, absl::ToDouble##UNIT(-d)); \ + EXPECT_EQ(0, absl::ToDouble##UNIT(z)); \ + EXPECT_EQ(1.5, absl::ToDouble##UNIT(d)); \ + EXPECT_EQ(dbl_inf, absl::ToDouble##UNIT(inf)); \ } while (0) TEST_DURATION_CONVERSION(Nanoseconds); @@ -790,6 +803,40 @@ TEST(Duration, DivisionByZero) { EXPECT_EQ(-dbl_inf, absl::FDivDuration(-any_dur, zero)); } +TEST(Duration, NaN) { + // Note that IEEE 754 does not define the behavior of a nan's sign when it is + // copied, so the code below allows for either + or - InfiniteDuration. +#define TEST_NAN_HANDLING(NAME, NAN) \ + do { \ + const auto inf = absl::InfiniteDuration(); \ + auto x = NAME(NAN); \ + EXPECT_TRUE(x == inf || x == -inf); \ + auto y = NAME(42); \ + y *= NAN; \ + EXPECT_TRUE(y == inf || y == -inf); \ + auto z = NAME(42); \ + z /= NAN; \ + EXPECT_TRUE(z == inf || z == -inf); \ + } while (0) + + const double nan = std::numeric_limits<double>::quiet_NaN(); + TEST_NAN_HANDLING(absl::Nanoseconds, nan); + TEST_NAN_HANDLING(absl::Microseconds, nan); + TEST_NAN_HANDLING(absl::Milliseconds, nan); + TEST_NAN_HANDLING(absl::Seconds, nan); + TEST_NAN_HANDLING(absl::Minutes, nan); + TEST_NAN_HANDLING(absl::Hours, nan); + + TEST_NAN_HANDLING(absl::Nanoseconds, -nan); + TEST_NAN_HANDLING(absl::Microseconds, -nan); + TEST_NAN_HANDLING(absl::Milliseconds, -nan); + TEST_NAN_HANDLING(absl::Seconds, -nan); + TEST_NAN_HANDLING(absl::Minutes, -nan); + TEST_NAN_HANDLING(absl::Hours, -nan); + +#undef TEST_NAN_HANDLING +} + TEST(Duration, Range) { const absl::Duration range = ApproxYears(100 * 1e9); const absl::Duration range_future = range; @@ -1284,6 +1331,16 @@ TEST(Duration, SmallConversions) { EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(0.875e-9)); EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(1.000e-9)); + EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(-0.124999999e-9)); + EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.125e-9)); + EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.250e-9)); + EXPECT_EQ(-absl::Nanoseconds(1) / 2, absl::Seconds(-0.375e-9)); + EXPECT_EQ(-absl::Nanoseconds(1) / 2, absl::Seconds(-0.500e-9)); + EXPECT_EQ(-absl::Nanoseconds(3) / 4, absl::Seconds(-0.625e-9)); + EXPECT_EQ(-absl::Nanoseconds(3) / 4, absl::Seconds(-0.750e-9)); + EXPECT_EQ(-absl::Nanoseconds(1), absl::Seconds(-0.875e-9)); + EXPECT_EQ(-absl::Nanoseconds(1), absl::Seconds(-1.000e-9)); + timespec ts; ts.tv_sec = 0; ts.tv_nsec = 0; @@ -1313,6 +1370,86 @@ TEST(Duration, SmallConversions) { EXPECT_THAT(ToTimeval(absl::Nanoseconds(2000)), TimevalMatcher(tv)); } +void VerifySameAsMul(double time_as_seconds, int* const misses) { + auto direct_seconds = absl::Seconds(time_as_seconds); + auto mul_by_one_second = time_as_seconds * absl::Seconds(1); + if (direct_seconds != mul_by_one_second) { + if (*misses > 10) return; + ASSERT_LE(++(*misses), 10) << "Too many errors, not reporting more."; + EXPECT_EQ(direct_seconds, mul_by_one_second) + << "given double time_as_seconds = " << std::setprecision(17) + << time_as_seconds; + } +} + +// For a variety of interesting durations, we find the exact point +// where one double converts to that duration, and the very next double +// converts to the next duration. For both of those points, verify that +// Seconds(point) returns the same duration as point * Seconds(1.0) +TEST(Duration, ToDoubleSecondsCheckEdgeCases) { + constexpr uint32_t kTicksPerSecond = absl::time_internal::kTicksPerSecond; + constexpr auto duration_tick = absl::time_internal::MakeDuration(0, 1u); + int misses = 0; + for (int64_t seconds = 0; seconds < 99; ++seconds) { + uint32_t tick_vals[] = {0, +999, +999999, +999999999, kTicksPerSecond - 1, + 0, 1000, 1000000, 1000000000, kTicksPerSecond, + 1, 1001, 1000001, 1000000001, kTicksPerSecond + 1, + 2, 1002, 1000002, 1000000002, kTicksPerSecond + 2, + 3, 1003, 1000003, 1000000003, kTicksPerSecond + 3, + 4, 1004, 1000004, 1000000004, kTicksPerSecond + 4, + 5, 6, 7, 8, 9}; + for (uint32_t ticks : tick_vals) { + absl::Duration s_plus_t = absl::Seconds(seconds) + ticks * duration_tick; + for (absl::Duration d : {s_plus_t, -s_plus_t}) { + absl::Duration after_d = d + duration_tick; + EXPECT_NE(d, after_d); + EXPECT_EQ(after_d - d, duration_tick); + + double low_edge = ToDoubleSeconds(d); + EXPECT_EQ(d, absl::Seconds(low_edge)); + + double high_edge = ToDoubleSeconds(after_d); + EXPECT_EQ(after_d, absl::Seconds(high_edge)); + + for (;;) { + double midpoint = low_edge + (high_edge - low_edge) / 2; + if (midpoint == low_edge || midpoint == high_edge) break; + absl::Duration mid_duration = absl::Seconds(midpoint); + if (mid_duration == d) { + low_edge = midpoint; + } else { + EXPECT_EQ(mid_duration, after_d); + high_edge = midpoint; + } + } + // Now low_edge is the highest double that converts to Duration d, + // and high_edge is the lowest double that converts to Duration after_d. + VerifySameAsMul(low_edge, &misses); + VerifySameAsMul(high_edge, &misses); + } + } + } +} + +TEST(Duration, ToDoubleSecondsCheckRandom) { + std::random_device rd; + std::seed_seq seed({rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()}); + std::mt19937_64 gen(seed); + // We want doubles distributed from 1/8ns up to 2^63, where + // as many values are tested from 1ns to 2ns as from 1sec to 2sec, + // so even distribute along a log-scale of those values, and + // exponentiate before using them. (9.223377e+18 is just slightly + // out of bounds for absl::Duration.) + std::uniform_real_distribution<double> uniform(std::log(0.125e-9), + std::log(9.223377e+18)); + int misses = 0; + for (int i = 0; i < 1000000; ++i) { + double d = std::exp(uniform(gen)); + VerifySameAsMul(d, &misses); + VerifySameAsMul(-d, &misses); + } +} + TEST(Duration, ConversionSaturation) { absl::Duration d; diff --git a/absl/time/format.cc b/absl/time/format.cc index 6bf3c20f..6aabcee9 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc @@ -22,7 +22,7 @@ namespace cctz = absl::time_internal::cctz; namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; @@ -35,15 +35,13 @@ namespace { const char kInfiniteFutureStr[] = "infinite-future"; const char kInfinitePastStr[] = "infinite-past"; -using cctz_sec = cctz::time_point<cctz::sys_seconds>; -using cctz_fem = cctz::detail::femtoseconds; struct cctz_parts { - cctz_sec sec; - cctz_fem fem; + cctz::time_point<cctz::seconds> sec; + cctz::detail::femtoseconds fem; }; -inline cctz_sec unix_epoch() { - return std::chrono::time_point_cast<cctz::sys_seconds>( +inline cctz::time_point<cctz::seconds> unix_epoch() { + return std::chrono::time_point_cast<cctz::seconds>( std::chrono::system_clock::from_time_t(0)); } @@ -54,8 +52,8 @@ cctz_parts Split(absl::Time t) { const auto d = time_internal::ToUnixDuration(t); const int64_t rep_hi = time_internal::GetRepHi(d); const int64_t rep_lo = time_internal::GetRepLo(d); - const auto sec = unix_epoch() + cctz::sys_seconds(rep_hi); - const auto fem = cctz_fem(rep_lo * (1000 * 1000 / 4)); + const auto sec = unix_epoch() + cctz::seconds(rep_hi); + const auto fem = cctz::detail::femtoseconds(rep_lo * (1000 * 1000 / 4)); return {sec, fem}; } @@ -91,7 +89,7 @@ bool ParseTime(const std::string& format, const std::string& input, absl::Time* return absl::ParseTime(format, input, absl::UTCTimeZone(), time, err); } -// If the input std::string does not contain an explicit UTC offset, interpret +// If the input string does not contain an explicit UTC offset, interpret // the fields with respect to the given TimeZone. bool ParseTime(const std::string& format, const std::string& input, absl::TimeZone tz, absl::Time* time, std::string* err) { @@ -139,5 +137,5 @@ std::string UnparseFlag(absl::Time t) { return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone()); } -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/format_benchmark.cc b/absl/time/format_benchmark.cc index ee53d71c..766f1b39 100644 --- a/absl/time/format_benchmark.cc +++ b/absl/time/format_benchmark.cc @@ -38,7 +38,8 @@ void BM_Format_FormatTime(benchmark::State& state) { const absl::TimeZone lax = absl::time_internal::LoadTimeZone("America/Los_Angeles"); const absl::Time t = - absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); + absl::FromCivil(absl::CivilSecond(1977, 6, 28, 9, 8, 7), lax) + + absl::Nanoseconds(1); while (state.KeepRunning()) { benchmark::DoNotOptimize(absl::FormatTime(fmt, t, lax).length()); } @@ -50,8 +51,8 @@ void BM_Format_ParseTime(benchmark::State& state) { state.SetLabel(fmt); const absl::TimeZone lax = absl::time_internal::LoadTimeZone("America/Los_Angeles"); - absl::Time t = - absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); + absl::Time t = absl::FromCivil(absl::CivilSecond(1977, 6, 28, 9, 8, 7), lax) + + absl::Nanoseconds(1); const std::string when = absl::FormatTime(fmt, t, lax); std::string err; while (state.KeepRunning()) { diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index 7c84c33f..ac8d5ea3 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc @@ -118,7 +118,7 @@ TEST(FormatTime, RFC1123FormatPadsYear) { // locale specific absl::TimeZone tz = absl::UTCTimeZone(); // A year of 77 should be padded to 0077. - absl::Time t = absl::FromDateTime(77, 6, 28, 9, 8, 7, tz); + absl::Time t = absl::FromCivil(absl::CivilSecond(77, 6, 28, 9, 8, 7), tz); EXPECT_EQ("Mon, 28 Jun 0077 09:08:07 +0000", absl::FormatTime(absl::RFC1123_full, t, tz)); EXPECT_EQ("28 Jun 0077 09:08:07 +0000", @@ -154,9 +154,9 @@ TEST(ParseTime, Basics) { EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 -0800", &t, &err)) << err; - absl::Time::Breakdown bd = t.In(absl::FixedTimeZone(-8 * 60 * 60)); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, -8 * 60 * 60, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); + const auto ci = absl::FixedTimeZone(-8 * 60 * 60).At(t); + EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); } TEST(ParseTime, NullErrorString) { @@ -177,17 +177,17 @@ TEST(ParseTime, WithTimeZone) { EXPECT_TRUE( absl::ParseTime("%Y-%m-%d %H:%M:%S", "2013-06-28 19:08:09", tz, &t, &e)) << e; - absl::Time::Breakdown bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, -7 * 60 * 60, true); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); + auto ci = tz.At(t); + EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); // But the timezone is ignored when a UTC offset is present. EXPECT_TRUE(absl::ParseTime("%Y-%m-%d %H:%M:%S %z", "2013-06-28 19:08:09 +0800", tz, &t, &e)) << e; - bd = t.In(absl::FixedTimeZone(8 * 60 * 60)); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 6, 28, 19, 8, 9, 8 * 60 * 60, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); + ci = absl::FixedTimeZone(8 * 60 * 60).At(t); + EXPECT_EQ(absl::CivilSecond(2013, 6, 28, 19, 8, 9), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); } TEST(ParseTime, ErrorCases) { @@ -332,15 +332,15 @@ TEST(ParseTime, InfiniteTime) { EXPECT_TRUE(absl::ParseTime("infinite-future %H:%M", "infinite-future 03:04", &t, &err)); EXPECT_NE(absl::InfiniteFuture(), t); - EXPECT_EQ(3, t.In(tz).hour); - EXPECT_EQ(4, t.In(tz).minute); + EXPECT_EQ(3, tz.At(t).cs.hour()); + EXPECT_EQ(4, tz.At(t).cs.minute()); // "infinite-past" as literal std::string EXPECT_TRUE( absl::ParseTime("infinite-past %H:%M", "infinite-past 03:04", &t, &err)); EXPECT_NE(absl::InfinitePast(), t); - EXPECT_EQ(3, t.In(tz).hour); - EXPECT_EQ(4, t.In(tz).minute); + EXPECT_EQ(3, tz.At(t).cs.hour()); + EXPECT_EQ(4, tz.At(t).cs.minute()); // The input doesn't match the format. EXPECT_FALSE(absl::ParseTime("infinite-future %H:%M", "03:04", &t, &err)); @@ -365,16 +365,17 @@ TEST(ParseTime, FailsOnUnrepresentableTime) { // TEST(FormatParse, RoundTrip) { - const absl::TimeZone gst = + const absl::TimeZone lax = absl::time_internal::LoadTimeZone("America/Los_Angeles"); - const absl::Time in = absl::FromDateTime(1977, 6, 28, 9, 8, 7, gst); + const absl::Time in = + absl::FromCivil(absl::CivilSecond(1977, 6, 28, 9, 8, 7), lax); const absl::Duration subseconds = absl::Nanoseconds(654321); std::string err; // RFC3339, which renders subseconds. { absl::Time out; - const std::string s = absl::FormatTime(absl::RFC3339_full, in + subseconds, gst); + const std::string s = absl::FormatTime(absl::RFC3339_full, in + subseconds, lax); EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err)) << s << ": " << err; EXPECT_EQ(in + subseconds, out); // RFC3339_full includes %Ez @@ -383,7 +384,7 @@ TEST(FormatParse, RoundTrip) { // RFC1123, which only does whole seconds. { absl::Time out; - const std::string s = absl::FormatTime(absl::RFC1123_full, in, gst); + const std::string s = absl::FormatTime(absl::RFC1123_full, in, lax); EXPECT_TRUE(absl::ParseTime(absl::RFC1123_full, s, &out, &err)) << s << ": " << err; EXPECT_EQ(in, out); // RFC1123_full includes %z @@ -393,7 +394,12 @@ TEST(FormatParse, RoundTrip) { // work. On Windows, `absl::ParseTime()` falls back to std::get_time() which // appears to fail on "%c" (or at least on the "%c" text produced by // `strftime()`). This makes it fail the round-trip test. -#ifndef _MSC_VER + // + // Under the emscripten compiler `absl::ParseTime() falls back to + // `strptime()`, but that ends up using a different definition for "%c" + // compared to `strftime()`, also causing the round-trip test to fail + // (see https://github.com/kripken/emscripten/pull/7491). +#if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__) // Even though we don't know what %c will produce, it should roundtrip, // but only in the 0-offset timezone. { @@ -402,7 +408,7 @@ TEST(FormatParse, RoundTrip) { EXPECT_TRUE(absl::ParseTime("%c", s, &out, &err)) << s << ": " << err; EXPECT_EQ(in, out); } -#endif // _MSC_VER +#endif // !_MSC_VER && !__EMSCRIPTEN__ } TEST(FormatParse, RoundTripDistantFuture) { diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel index 9f1ba21c..e2cfe801 100644 --- a/absl/time/internal/cctz/BUILD.bazel +++ b/absl/time/internal/cctz/BUILD.bazel @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +package(features = ["-parse_headers"]) + licenses(["notice"]) # Apache License ### libraries @@ -102,6 +104,7 @@ cc_test( "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", + "no_test_wasm", ], deps = [ ":civil_time", diff --git a/absl/time/internal/cctz/include/cctz/civil_time.h b/absl/time/internal/cctz/include/cctz/civil_time.h index 31a28cb7..9fabbc3d 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time.h +++ b/absl/time/internal/cctz/include/cctz/civil_time.h @@ -18,7 +18,7 @@ #include "absl/time/internal/cctz/include/cctz/civil_time_detail.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -60,7 +60,7 @@ namespace cctz { // inferior fields to their minimum valid value (as described above). The // following are examples of how each of the six types would align the fields // representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the -// std::string format used here is not important; it's just a shorthand way of +// string format used here is not important; it's just a shorthand way of // showing the six YMDHMS fields.) // // civil_second 2015-11-22 12:34:56 @@ -325,7 +325,7 @@ using detail::get_yearday; } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h index 78d1db1c..289ff499 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h +++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h @@ -32,7 +32,7 @@ #endif namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -327,6 +327,37 @@ CONSTEXPR_F fields align(year_tag, fields f) noexcept { //////////////////////////////////////////////////////////////////////// +namespace impl { + +template <typename H> +H AbslHashValueImpl(second_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm, f.ss); +} +template <typename H> +H AbslHashValueImpl(minute_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm); +} +template <typename H> +H AbslHashValueImpl(hour_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh); +} +template <typename H> +H AbslHashValueImpl(day_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d); +} +template <typename H> +H AbslHashValueImpl(month_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m); +} +template <typename H> +H AbslHashValueImpl(year_tag, H h, fields f) { + return H::combine(std::move(h), f.y); +} + +} // namespace impl + +//////////////////////////////////////////////////////////////////////// + template <typename T> class civil_time { public: @@ -356,11 +387,11 @@ class civil_time { : civil_time(ct.f_) {} // Factories for the maximum/minimum representable civil_time. - static civil_time max() { + static CONSTEXPR_F civil_time max() { const auto max_year = std::numeric_limits<std::int_least64_t>::max(); return civil_time(max_year, 12, 31, 23, 59, 59); } - static civil_time min() { + static CONSTEXPR_F civil_time min() { const auto min_year = std::numeric_limits<std::int_least64_t>::min(); return civil_time(min_year, 1, 1, 0, 0, 0); } @@ -404,23 +435,24 @@ class civil_time { } // Binary arithmetic operators. - inline friend CONSTEXPR_M civil_time operator+(civil_time a, - diff_t n) noexcept { + friend CONSTEXPR_F civil_time operator+(civil_time a, diff_t n) noexcept { return a += n; } - inline friend CONSTEXPR_M civil_time operator+(diff_t n, - civil_time a) noexcept { + friend CONSTEXPR_F civil_time operator+(diff_t n, civil_time a) noexcept { return a += n; } - inline friend CONSTEXPR_M civil_time operator-(civil_time a, - diff_t n) noexcept { + friend CONSTEXPR_F civil_time operator-(civil_time a, diff_t n) noexcept { return a -= n; } - inline friend CONSTEXPR_M diff_t operator-(const civil_time& lhs, - const civil_time& rhs) noexcept { + friend CONSTEXPR_F diff_t operator-(civil_time lhs, civil_time rhs) noexcept { return difference(T{}, lhs.f_, rhs.f_); } + template <typename H> + friend H AbslHashValue(H h, civil_time a) { + return impl::AbslHashValueImpl(T{}, std::move(h), a.f_); + } + private: // All instantiations of this template are allowed to call the following // private constructor and access the private fields member. @@ -435,8 +467,8 @@ class civil_time { // Disallows difference between differently aligned types. // auto n = civil_day(...) - civil_hour(...); // would be confusing. -template <typename Tag1, typename Tag2> -CONSTEXPR_F diff_t operator-(civil_time<Tag1>, civil_time<Tag2>) = delete; +template <typename T, typename U> +CONSTEXPR_F diff_t operator-(civil_time<T>, civil_time<U>) = delete; using civil_year = civil_time<year_tag>; using civil_month = civil_time<month_tag>; @@ -505,22 +537,20 @@ enum class weekday { }; CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept { - CONSTEXPR_D weekday k_weekday_by_sun_off[7] = { - weekday::sunday, weekday::monday, weekday::tuesday, - weekday::wednesday, weekday::thursday, weekday::friday, + CONSTEXPR_D weekday k_weekday_by_mon_off[13] = { + weekday::monday, weekday::tuesday, weekday::wednesday, + weekday::thursday, weekday::friday, weekday::saturday, + weekday::sunday, weekday::monday, weekday::tuesday, + weekday::wednesday, weekday::thursday, weekday::friday, weekday::saturday, }; CONSTEXPR_D int k_weekday_offsets[1 + 12] = { -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4, }; - year_t wd = cd.year() - (cd.month() < 3); - if (wd >= 0) { - wd += wd / 4 - wd / 100 + wd / 400; - } else { - wd += (wd - 3) / 4 - (wd - 99) / 100 + (wd - 399) / 400; - } + year_t wd = 2400 + (cd.year() % 400) - (cd.month() < 3); + wd += wd / 4 - wd / 100 + wd / 400; wd += k_weekday_offsets[cd.month()] + cd.day(); - return k_weekday_by_sun_off[(wd % 7 + 7) % 7]; + return k_weekday_by_mon_off[wd % 7 + 6]; } //////////////////////////////////////////////////////////////////////// @@ -556,7 +586,7 @@ std::ostream& operator<<(std::ostream& os, weekday wd); } // namespace detail } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #undef CONSTEXPR_M diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h index 52d69384..0c34393e 100644 --- a/absl/time/internal/cctz/include/cctz/time_zone.h +++ b/absl/time/internal/cctz/include/cctz/time_zone.h @@ -28,30 +28,31 @@ #include "absl/time/internal/cctz/include/cctz/civil_time.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { // Convenience aliases. Not intended as public API points. template <typename D> using time_point = std::chrono::time_point<std::chrono::system_clock, D>; -using sys_seconds = std::chrono::duration<std::int_fast64_t>; +using seconds = std::chrono::duration<std::int_fast64_t>; +using sys_seconds = seconds; // Deprecated. Use cctz::seconds instead. namespace detail { template <typename D> -inline std::pair<time_point<sys_seconds>, D> +inline std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) { - auto sec = std::chrono::time_point_cast<sys_seconds>(tp); + auto sec = std::chrono::time_point_cast<seconds>(tp); auto sub = tp - sec; if (sub.count() < 0) { - sec -= sys_seconds(1); - sub += sys_seconds(1); + sec -= seconds(1); + sub += seconds(1); } return {sec, std::chrono::duration_cast<D>(sub)}; } -inline std::pair<time_point<sys_seconds>, sys_seconds> -split_seconds(const time_point<sys_seconds>& tp) { - return {tp, sys_seconds(0)}; +inline std::pair<time_point<seconds>, seconds> +split_seconds(const time_point<seconds>& tp) { + return {tp, seconds::zero()}; } } // namespace detail @@ -100,7 +101,7 @@ class time_zone { bool is_dst; // is offset non-standard? const char* abbr; // time-zone abbreviation (e.g., "PST") }; - absolute_lookup lookup(const time_point<sys_seconds>& tp) const; + absolute_lookup lookup(const time_point<seconds>& tp) const; template <typename D> absolute_lookup lookup(const time_point<D>& tp) const { return lookup(detail::split_seconds(tp).first); @@ -119,9 +120,9 @@ class time_zone { // of the given civil-time argument, and the pre, trans, and post // members will give the absolute time answers using the pre-transition // offset, the transition point itself, and the post-transition offset, - // respectively (all three times are equal if kind == UNIQUE). If any + // respectively (all three times are equal if kind == UNIQUE). If any // of these three absolute times is outside the representable range of a - // time_point<sys_seconds> the field is set to its maximum/minimum value. + // time_point<seconds> the field is set to its maximum/minimum value. // // Example: // cctz::time_zone lax; @@ -153,23 +154,90 @@ class time_zone { SKIPPED, // the civil time did not exist (pre >= trans > post) REPEATED, // the civil time was ambiguous (pre < trans <= post) } kind; - time_point<sys_seconds> pre; // uses the pre-transition offset - time_point<sys_seconds> trans; // instant of civil-offset change - time_point<sys_seconds> post; // uses the post-transition offset + time_point<seconds> pre; // uses the pre-transition offset + time_point<seconds> trans; // instant of civil-offset change + time_point<seconds> post; // uses the post-transition offset }; civil_lookup lookup(const civil_second& cs) const; + // Finds the time of the next/previous offset change in this time zone. + // + // By definition, next_transition(tp, &trans) returns false when tp has + // its maximum value, and prev_transition(tp, &trans) returns false + // when tp has its minimum value. If the zone has no transitions, the + // result will also be false no matter what the argument. + // + // Otherwise, when tp has its minimum value, next_transition(tp, &trans) + // returns true and sets trans to the first recorded transition. Chains + // of calls to next_transition()/prev_transition() will eventually return + // false, but it is unspecified exactly when next_transition(tp, &trans) + // jumps to false, or what time is set by prev_transition(tp, &trans) for + // a very distant tp. + // + // Note: Enumeration of time-zone transitions is for informational purposes + // only. Modern time-related code should not care about when offset changes + // occur. + // + // Example: + // cctz::time_zone nyc; + // if (!cctz::load_time_zone("America/New_York", &nyc)) { ... } + // const auto now = std::chrono::system_clock::now(); + // auto tp = cctz::time_point<cctz::seconds>::min(); + // cctz::time_zone::civil_transition trans; + // while (tp <= now && nyc.next_transition(tp, &trans)) { + // // transition: trans.from -> trans.to + // tp = nyc.lookup(trans.to).trans; + // } + struct civil_transition { + civil_second from; // the civil time we jump from + civil_second to; // the civil time we jump to + }; + bool next_transition(const time_point<seconds>& tp, + civil_transition* trans) const; + template <typename D> + bool next_transition(const time_point<D>& tp, + civil_transition* trans) const { + return next_transition(detail::split_seconds(tp).first, trans); + } + bool prev_transition(const time_point<seconds>& tp, + civil_transition* trans) const; + template <typename D> + bool prev_transition(const time_point<D>& tp, + civil_transition* trans) const { + return prev_transition(detail::split_seconds(tp).first, trans); + } + + // version() and description() provide additional information about the + // time zone. The content of each of the returned strings is unspecified, + // however, when the IANA Time Zone Database is the underlying data source + // the version() std::string will be in the familar form (e.g, "2018e") or + // empty when unavailable. + // + // Note: These functions are for informational or testing purposes only. + std::string version() const; // empty when unknown + std::string description() const; + + // Relational operators. + friend bool operator==(time_zone lhs, time_zone rhs) { + return &lhs.effective_impl() == &rhs.effective_impl(); + } + friend bool operator!=(time_zone lhs, time_zone rhs) { + return !(lhs == rhs); + } + + template <typename H> + friend H AbslHashValue(H h, time_zone tz) { + return H::combine(std::move(h), &tz.effective_impl()); + } + class Impl; private: explicit time_zone(const Impl* impl) : impl_(impl) {} + const Impl& effective_impl() const; // handles implicit UTC const Impl* impl_; }; -// Relational operators. -bool operator==(time_zone lhs, time_zone rhs); -inline bool operator!=(time_zone lhs, time_zone rhs) { return !(lhs == rhs); } - // Loads the named time zone. May perform I/O on the initial load. // If the name is invalid, or some other kind of error occurs, returns // false and "*tz" is set to the UTC time zone. @@ -181,9 +249,10 @@ time_zone utc_time_zone(); // Returns a time zone that is a fixed offset (seconds east) from UTC. // Note: If the absolute value of the offset is greater than 24 hours // you'll get UTC (i.e., zero offset) instead. -time_zone fixed_time_zone(const sys_seconds& offset); +time_zone fixed_time_zone(const seconds& offset); // Returns a time zone representing the local time zone. Falls back to UTC. +// Note: local_time_zone.name() may only be something like "localtime". time_zone local_time_zone(); // Returns the civil time (cctz::civil_second) within the given time zone at @@ -200,8 +269,8 @@ inline civil_second convert(const time_point<D>& tp, const time_zone& tz) { // it was either repeated or non-existent), then the returned time_point is // the best estimate that preserves relative order. That is, this function // guarantees that if cs1 < cs2, then convert(cs1, tz) <= convert(cs2, tz). -inline time_point<sys_seconds> convert(const civil_second& cs, - const time_zone& tz) { +inline time_point<seconds> convert(const civil_second& cs, + const time_zone& tz) { const time_zone::civil_lookup cl = tz.lookup(cs); if (cl.kind == time_zone::civil_lookup::SKIPPED) return cl.trans; return cl.pre; @@ -209,14 +278,14 @@ inline time_point<sys_seconds> convert(const civil_second& cs, namespace detail { using femtoseconds = std::chrono::duration<std::int_fast64_t, std::femto>; -std::string format(const std::string&, const time_point<sys_seconds>&, +std::string format(const std::string&, const time_point<seconds>&, const femtoseconds&, const time_zone&); bool parse(const std::string&, const std::string&, const time_zone&, - time_point<sys_seconds>*, femtoseconds*, std::string* err = nullptr); + time_point<seconds>*, femtoseconds*, std::string* err = nullptr); } // namespace detail // Formats the given time_point in the given cctz::time_zone according to -// the provided format std::string. Uses strftime()-like formatting options, +// the provided format string. Uses strftime()-like formatting options, // with the following extensions: // // - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) @@ -227,7 +296,7 @@ bool parse(const std::string&, const std::string&, const time_zone&, // - %E*f - Fractional seconds with full precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) // -// Note that %E0S behaves like %S, and %E0f produces no characters. In +// Note that %E0S behaves like %S, and %E0f produces no characters. In // contrast %E*f always produces at least one digit, which may be '0'. // // Note that %Y produces as many characters as it takes to fully render the @@ -235,7 +304,7 @@ bool parse(const std::string&, const std::string&, const time_zone&, // more than four characters, just like %Y. // // Tip: Format strings should include the UTC offset (e.g., %z, %Ez, or %E*z) -// so that the resulting std::string uniquely identifies an absolute time. +// so that the resulting string uniquely identifies an absolute time. // // Example: // cctz::time_zone lax; @@ -251,10 +320,10 @@ inline std::string format(const std::string& fmt, const time_point<D>& tp, return detail::format(fmt, p.first, n, tz); } -// Parses an input std::string according to the provided format std::string and +// Parses an input string according to the provided format string and // returns the corresponding time_point. Uses strftime()-like formatting // options, with the same extensions as cctz::format(), but with the -// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez +// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez // and %E*z also accept the same inputs. // // %Y consumes as many numeric characters as it can, so the matching data @@ -265,7 +334,7 @@ inline std::string format(const std::string& fmt, const time_point<D>& tp, // // "1970-01-01 00:00:00.0 +0000" // -// For example, parsing a std::string of "15:45" (%H:%M) will return a time_point +// For example, parsing a string of "15:45" (%H:%M) will return a time_point // that represents "1970-01-01 15:45:00.0 +0000". // // Note that parse() returns time instants, so it makes most sense to parse @@ -299,7 +368,7 @@ inline std::string format(const std::string& fmt, const time_point<D>& tp, template <typename D> inline bool parse(const std::string& fmt, const std::string& input, const time_zone& tz, time_point<D>* tpp) { - time_point<sys_seconds> sec; + time_point<seconds> sec; detail::femtoseconds fs; const bool b = detail::parse(fmt, input, tz, &sec, &fs); if (b) { @@ -312,7 +381,7 @@ inline bool parse(const std::string& fmt, const std::string& input, } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_ diff --git a/absl/time/internal/cctz/include/cctz/zone_info_source.h b/absl/time/internal/cctz/include/cctz/zone_info_source.h index b72a02cf..b3274e00 100644 --- a/absl/time/internal/cctz/include/cctz/zone_info_source.h +++ b/absl/time/internal/cctz/include/cctz/zone_info_source.h @@ -21,7 +21,7 @@ #include <string> namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -32,15 +32,20 @@ class ZoneInfoSource { virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread() virtual int Skip(std::size_t offset) = 0; // like fseek() + + // Until the zoneinfo data supports versioning information, we provide + // a way for a ZoneInfoSource to indicate it out-of-band. The default + // implementation returns an empty std::string. + virtual std::string Version() const; }; } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz_extension { @@ -89,7 +94,7 @@ extern ZoneInfoSourceFactory zone_info_source_factory; } // namespace cctz_extension } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc index f13cb4ee..4498d7d0 100644 --- a/absl/time/internal/cctz/src/cctz_benchmark.cc +++ b/absl/time/internal/cctz/src/cctz_benchmark.cc @@ -754,23 +754,21 @@ void BM_Zone_LoadAllTimeZonesCached(benchmark::State& state) { } BENCHMARK(BM_Zone_LoadAllTimeZonesCached); -void BM_Zone_TimeZoneImplGetImplicit(benchmark::State& state) { +void BM_Zone_TimeZoneEqualityImplicit(benchmark::State& state) { cctz::time_zone tz; // implicit UTC - cctz::time_zone::Impl::get(tz); while (state.KeepRunning()) { - cctz::time_zone::Impl::get(tz); + benchmark::DoNotOptimize(tz == tz); } } -BENCHMARK(BM_Zone_TimeZoneImplGetImplicit); +BENCHMARK(BM_Zone_TimeZoneEqualityImplicit); -void BM_Zone_TimeZoneImplGetExplicit(benchmark::State& state) { +void BM_Zone_TimeZoneEqualityExplicit(benchmark::State& state) { cctz::time_zone tz = cctz::utc_time_zone(); // explicit UTC - cctz::time_zone::Impl::get(tz); while (state.KeepRunning()) { - cctz::time_zone::Impl::get(tz); + benchmark::DoNotOptimize(tz == tz); } } -BENCHMARK(BM_Zone_TimeZoneImplGetExplicit); +BENCHMARK(BM_Zone_TimeZoneEqualityExplicit); void BM_Zone_UTCTimeZone(benchmark::State& state) { cctz::time_zone tz; @@ -780,13 +778,13 @@ void BM_Zone_UTCTimeZone(benchmark::State& state) { } BENCHMARK(BM_Zone_UTCTimeZone); -// In each "ToDateTime" benchmark we switch between two instants -// separated by at least one transition in order to defeat any -// internal caching of previous results (e.g., see local_time_hint_). +// In each "ToCivil" benchmark we switch between two instants separated +// by at least one transition in order to defeat any internal caching of +// previous results (e.g., see local_time_hint_). // // The "UTC" variants use UTC instead of the Google/local time zone. -void BM_Time_ToDateTime_CCTZ(benchmark::State& state) { +void BM_Time_ToCivil_CCTZ(benchmark::State& state) { const cctz::time_zone tz = TestTimeZone(); std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(1384569027); @@ -798,9 +796,9 @@ void BM_Time_ToDateTime_CCTZ(benchmark::State& state) { benchmark::DoNotOptimize(cctz::convert(tp, tz)); } } -BENCHMARK(BM_Time_ToDateTime_CCTZ); +BENCHMARK(BM_Time_ToCivil_CCTZ); -void BM_Time_ToDateTime_Libc(benchmark::State& state) { +void BM_Time_ToCivil_Libc(benchmark::State& state) { // No timezone support, so just use localtime. time_t t = 1384569027; time_t t2 = 1418962578; @@ -815,9 +813,9 @@ void BM_Time_ToDateTime_Libc(benchmark::State& state) { #endif } } -BENCHMARK(BM_Time_ToDateTime_Libc); +BENCHMARK(BM_Time_ToCivil_Libc); -void BM_Time_ToDateTimeUTC_CCTZ(benchmark::State& state) { +void BM_Time_ToCivilUTC_CCTZ(benchmark::State& state) { const cctz::time_zone tz = cctz::utc_time_zone(); std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(1384569027); @@ -826,9 +824,9 @@ void BM_Time_ToDateTimeUTC_CCTZ(benchmark::State& state) { benchmark::DoNotOptimize(cctz::convert(tp, tz)); } } -BENCHMARK(BM_Time_ToDateTimeUTC_CCTZ); +BENCHMARK(BM_Time_ToCivilUTC_CCTZ); -void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) { +void BM_Time_ToCivilUTC_Libc(benchmark::State& state) { time_t t = 1384569027; struct tm tm; while (state.KeepRunning()) { @@ -840,16 +838,16 @@ void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) { #endif } } -BENCHMARK(BM_Time_ToDateTimeUTC_Libc); +BENCHMARK(BM_Time_ToCivilUTC_Libc); -// In each "FromDateTime" benchmark we switch between two YMDhms -// values separated by at least one transition in order to defeat any -// internal caching of previous results (e.g., see time_local_hint_). +// In each "FromCivil" benchmark we switch between two YMDhms values +// separated by at least one transition in order to defeat any internal +// caching of previous results (e.g., see time_local_hint_). // // The "UTC" variants use UTC instead of the Google/local time zone. // The "Day0" variants require normalization of the day of month. -void BM_Time_FromDateTime_CCTZ(benchmark::State& state) { +void BM_Time_FromCivil_CCTZ(benchmark::State& state) { const cctz::time_zone tz = TestTimeZone(); int i = 0; while (state.KeepRunning()) { @@ -862,9 +860,9 @@ void BM_Time_FromDateTime_CCTZ(benchmark::State& state) { } } } -BENCHMARK(BM_Time_FromDateTime_CCTZ); +BENCHMARK(BM_Time_FromCivil_CCTZ); -void BM_Time_FromDateTime_Libc(benchmark::State& state) { +void BM_Time_FromCivil_Libc(benchmark::State& state) { // No timezone support, so just use localtime. int i = 0; while (state.KeepRunning()) { @@ -888,20 +886,20 @@ void BM_Time_FromDateTime_Libc(benchmark::State& state) { benchmark::DoNotOptimize(mktime(&tm)); } } -BENCHMARK(BM_Time_FromDateTime_Libc); +BENCHMARK(BM_Time_FromCivil_Libc); -void BM_Time_FromDateTimeUTC_CCTZ(benchmark::State& state) { +void BM_Time_FromCivilUTC_CCTZ(benchmark::State& state) { const cctz::time_zone tz = cctz::utc_time_zone(); while (state.KeepRunning()) { benchmark::DoNotOptimize( cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz)); } } -BENCHMARK(BM_Time_FromDateTimeUTC_CCTZ); +BENCHMARK(BM_Time_FromCivilUTC_CCTZ); -// There is no BM_Time_FromDateTimeUTC_Libc. +// There is no BM_Time_FromCivilUTC_Libc. -void BM_Time_FromDateTimeDay0_CCTZ(benchmark::State& state) { +void BM_Time_FromCivilDay0_CCTZ(benchmark::State& state) { const cctz::time_zone tz = TestTimeZone(); int i = 0; while (state.KeepRunning()) { @@ -914,9 +912,9 @@ void BM_Time_FromDateTimeDay0_CCTZ(benchmark::State& state) { } } } -BENCHMARK(BM_Time_FromDateTimeDay0_CCTZ); +BENCHMARK(BM_Time_FromCivilDay0_CCTZ); -void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { +void BM_Time_FromCivilDay0_Libc(benchmark::State& state) { // No timezone support, so just use localtime. int i = 0; while (state.KeepRunning()) { @@ -940,7 +938,7 @@ void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { benchmark::DoNotOptimize(mktime(&tm)); } } -BENCHMARK(BM_Time_FromDateTimeDay0_Libc); +BENCHMARK(BM_Time_FromCivilDay0_Libc); const char* const kFormats[] = { RFC1123_full, // 0 diff --git a/absl/time/internal/cctz/src/civil_time_detail.cc b/absl/time/internal/cctz/src/civil_time_detail.cc index 92a2e09c..e888066d 100644 --- a/absl/time/internal/cctz/src/civil_time_detail.cc +++ b/absl/time/internal/cctz/src/civil_time_detail.cc @@ -19,7 +19,7 @@ #include <sstream> namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { namespace detail { @@ -88,5 +88,5 @@ std::ostream& operator<<(std::ostream& os, weekday wd) { } // namespace detail } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/civil_time_test.cc b/absl/time/internal/cctz/src/civil_time_test.cc index d26c6498..2417a2a9 100644 --- a/absl/time/internal/cctz/src/civil_time_test.cc +++ b/absl/time/internal/cctz/src/civil_time_test.cc @@ -23,7 +23,7 @@ #include "gtest/gtest.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -621,7 +621,7 @@ TEST(CivilTime, Relational) { TEST_RELATIONAL(civil_second(2014, 1, 1, 1, 1, 0), civil_second(2014, 1, 1, 1, 1, 1)); - // Tests the relational operators of two different CivilTime types. + // Tests the relational operators of two different civil-time types. TEST_RELATIONAL(civil_day(2014, 1, 1), civil_minute(2014, 1, 1, 1, 1)); TEST_RELATIONAL(civil_day(2014, 1, 1), civil_month(2014, 2)); @@ -1047,5 +1047,5 @@ TEST(CivilTime, FirstThursdayInMonth) { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc index 4b608f68..070abd26 100644 --- a/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/absl/time/internal/cctz/src/time_zone_fixed.cc @@ -15,13 +15,13 @@ #include "time_zone_fixed.h" #include <algorithm> +#include <cassert> #include <chrono> -#include <cstdio> #include <cstring> #include <string> namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -30,8 +30,15 @@ namespace { // The prefix used for the internal names of fixed-offset zones. const char kFixedOffsetPrefix[] = "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) { - static const char kDigits[] = "0123456789"; if (const char* ap = std::strchr(kDigits, *p)) { int v = static_cast<int>(ap - kDigits); if (const char* bp = std::strchr(kDigits, *++p)) { @@ -43,9 +50,9 @@ int Parse02d(const char* p) { } // namespace -bool FixedOffsetFromName(const std::string& name, sys_seconds* offset) { +bool FixedOffsetFromName(const std::string& name, seconds* offset) { if (name.compare(0, std::string::npos, "UTC", 3) == 0) { - *offset = sys_seconds::zero(); + *offset = seconds::zero(); return true; } @@ -70,12 +77,12 @@ bool FixedOffsetFromName(const std::string& name, sys_seconds* offset) { secs += ((hours * 60) + mins) * 60; if (secs > 24 * 60 * 60) return false; // outside supported offset range - *offset = sys_seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west + *offset = seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west return true; } -std::string FixedOffsetToName(const sys_seconds& offset) { - if (offset == sys_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 @@ -96,13 +103,21 @@ std::string FixedOffsetToName(const sys_seconds& offset) { } int hours = minutes / 60; minutes %= 60; - char buf[sizeof(kFixedOffsetPrefix) + sizeof("-24:00:00")]; - snprintf(buf, sizeof(buf), "%s%c%02d:%02d:%02d", - kFixedOffsetPrefix, sign, hours, minutes, seconds); + char buf[sizeof(kFixedOffsetPrefix) - 1 + sizeof("-24:00:00")]; + std::strcpy(buf, kFixedOffsetPrefix); + char* ep = buf + sizeof(kFixedOffsetPrefix) - 1; + *ep++ = sign; + ep = Format02d(ep, hours); + *ep++ = ':'; + ep = Format02d(ep, minutes); + *ep++ = ':'; + ep = Format02d(ep, seconds); + *ep++ = '\0'; + assert(ep == buf + sizeof(buf)); return buf; } -std::string FixedOffsetToAbbr(const sys_seconds& offset) { +std::string FixedOffsetToAbbr(const seconds& offset) { std::string abbr = FixedOffsetToName(offset); const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1; if (abbr.size() == prefix_len + 9) { // <prefix>+99:99:99 @@ -121,5 +136,5 @@ std::string FixedOffsetToAbbr(const sys_seconds& offset) { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_fixed.h b/absl/time/internal/cctz/src/time_zone_fixed.h index 15e9db1e..dbb2958e 100644 --- a/absl/time/internal/cctz/src/time_zone_fixed.h +++ b/absl/time/internal/cctz/src/time_zone_fixed.h @@ -20,7 +20,7 @@ #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -39,13 +39,13 @@ 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, sys_seconds* offset); -std::string FixedOffsetToName(const sys_seconds& offset); -std::string FixedOffsetToAbbr(const sys_seconds& offset); +bool FixedOffsetFromName(const std::string& name, seconds* offset); +std::string FixedOffsetToName(const seconds& offset); +std::string FixedOffsetToAbbr(const seconds& offset); } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_ diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc index 0efbbc79..02ecb2cf 100644 --- a/absl/time/internal/cctz/src/time_zone_format.cc +++ b/absl/time/internal/cctz/src/time_zone_format.cc @@ -38,7 +38,7 @@ #include "time_zone_if.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { namespace detail { @@ -142,6 +142,9 @@ 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 sign = '+'; if (offset < 0) { offset = -offset; // bounded by 24h so no overflow @@ -278,7 +281,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<sys_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. @@ -531,7 +534,7 @@ const char* ParseSubSeconds(const char* dp, detail::femtoseconds* subseconds) { return dp; } -// Parses a std::string into a std::tm using strptime(3). +// Parses a string into a std::tm using strptime(3). const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) { if (dp != nullptr) { dp = strptime(dp, fmt, tm); @@ -556,7 +559,7 @@ const char* ParseTM(const char* dp, const char* fmt, 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<sys_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 @@ -741,7 +744,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 ConvertDateTime(). + // 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) { @@ -823,15 +826,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<sys_seconds>::max()) { - const auto al = ptz.lookup(time_point<sys_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<sys_seconds>::min()) { - const auto al = ptz.lookup(time_point<sys_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; @@ -846,5 +849,5 @@ bool parse(const std::string& format, const std::string& input, } // namespace detail } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc index 649e9b9a..260c56ad 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -23,18 +23,10 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -using std::chrono::time_point_cast; -using std::chrono::system_clock; -using std::chrono::nanoseconds; -using std::chrono::microseconds; -using std::chrono::milliseconds; -using std::chrono::seconds; -using std::chrono::minutes; -using std::chrono::hours; -using testing::HasSubstr; +namespace chrono = std::chrono; namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -73,6 +65,17 @@ void TestFormatSpecifier(time_point<D> tp, time_zone tz, const std::string& fmt, EXPECT_EQ("xxx " + ans + " yyy", format("xxx " + fmt + " yyy", tp, tz)); } +// These tests sometimes run on platforms that have zoneinfo data so old +// that the transition we are attempting to check does not exist, most +// notably Android emulators. Fortunately, AndroidZoneInfoSource supports +// time_zone::version() so, in cases where we've learned that it matters, +// we can make the check conditionally. +int VersionCmp(time_zone tz, const std::string& target) { + std::string version = tz.version(); + if (version.empty() && !target.empty()) return 1; // unknown > known + return version.compare(target); +} + } // namespace // @@ -82,33 +85,36 @@ void TestFormatSpecifier(time_point<D> tp, time_zone tz, const std::string& fmt, TEST(Format, TimePointResolution) { const char kFmt[] = "%H:%M:%E*S"; const time_zone utc = utc_time_zone(); - const time_point<nanoseconds> t0 = system_clock::from_time_t(1420167845) + - milliseconds(123) + microseconds(456) + - nanoseconds(789); - EXPECT_EQ("03:04:05.123456789", - format(kFmt, time_point_cast<nanoseconds>(t0), utc)); - EXPECT_EQ("03:04:05.123456", - format(kFmt, time_point_cast<microseconds>(t0), utc)); - EXPECT_EQ("03:04:05.123", - format(kFmt, time_point_cast<milliseconds>(t0), utc)); + const time_point<chrono::nanoseconds> t0 = + chrono::system_clock::from_time_t(1420167845) + + chrono::milliseconds(123) + chrono::microseconds(456) + + chrono::nanoseconds(789); + EXPECT_EQ( + "03:04:05.123456789", + format(kFmt, chrono::time_point_cast<chrono::nanoseconds>(t0), utc)); + EXPECT_EQ( + "03:04:05.123456", + format(kFmt, chrono::time_point_cast<chrono::microseconds>(t0), utc)); + EXPECT_EQ( + "03:04:05.123", + format(kFmt, chrono::time_point_cast<chrono::milliseconds>(t0), utc)); EXPECT_EQ("03:04:05", - format(kFmt, time_point_cast<seconds>(t0), utc)); + format(kFmt, chrono::time_point_cast<chrono::seconds>(t0), utc)); EXPECT_EQ("03:04:05", - format(kFmt, time_point_cast<sys_seconds>(t0), utc)); + format(kFmt, chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0), utc)); EXPECT_EQ("03:04:00", - format(kFmt, time_point_cast<minutes>(t0), utc)); + format(kFmt, chrono::time_point_cast<chrono::minutes>(t0), utc)); EXPECT_EQ("03:00:00", - format(kFmt, time_point_cast<hours>(t0), utc)); + format(kFmt, chrono::time_point_cast<chrono::hours>(t0), utc)); } TEST(Format, TimePointExtendedResolution) { const char kFmt[] = "%H:%M:%E*S"; const time_zone utc = utc_time_zone(); - const time_point<sys_seconds> tp = - std::chrono::time_point_cast<sys_seconds>( - std::chrono::system_clock::from_time_t(0)) + - std::chrono::hours(12) + std::chrono::minutes(34) + - std::chrono::seconds(56); + const time_point<absl::time_internal::cctz::seconds> tp = + chrono::time_point_cast<absl::time_internal::cctz::seconds>( + chrono::system_clock::from_time_t(0)) + + chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56); EXPECT_EQ( "12:34:56.123456789012345", @@ -133,7 +139,7 @@ TEST(Format, TimePointExtendedResolution) { TEST(Format, Basics) { time_zone tz = utc_time_zone(); - time_point<nanoseconds> tp = system_clock::from_time_t(0); + time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); // Starts with a couple basic edge cases. EXPECT_EQ("", format("", tp, tz)); @@ -146,8 +152,9 @@ TEST(Format, Basics) { std::string bigger(100000, 'x'); EXPECT_EQ(bigger, format(bigger, tp, tz)); - tp += hours(13) + minutes(4) + seconds(5); - tp += milliseconds(6) + microseconds(7) + nanoseconds(8); + tp += chrono::hours(13) + chrono::minutes(4) + chrono::seconds(5); + tp += chrono::milliseconds(6) + chrono::microseconds(7) + + chrono::nanoseconds(8); EXPECT_EQ("1970-01-01", format("%Y-%m-%d", tp, tz)); EXPECT_EQ("13:04:05", format("%H:%M:%S", tp, tz)); EXPECT_EQ("13:04:05.006", format("%H:%M:%E3S", tp, tz)); @@ -157,7 +164,7 @@ TEST(Format, Basics) { TEST(Format, PosixConversions) { const time_zone tz = utc_time_zone(); - auto tp = system_clock::from_time_t(0); + auto tp = chrono::system_clock::from_time_t(0); TestFormatSpecifier(tp, tz, "%d", "01"); TestFormatSpecifier(tp, tz, "%e", " 1"); // extension but internal support @@ -197,7 +204,7 @@ TEST(Format, PosixConversions) { TEST(Format, LocaleSpecific) { const time_zone tz = utc_time_zone(); - auto tp = system_clock::from_time_t(0); + auto tp = chrono::system_clock::from_time_t(0); TestFormatSpecifier(tp, tz, "%a", "Thu"); TestFormatSpecifier(tp, tz, "%A", "Thursday"); @@ -206,8 +213,8 @@ TEST(Format, LocaleSpecific) { // %c should at least produce the numeric year and time-of-day. const std::string s = format("%c", tp, utc_time_zone()); - EXPECT_THAT(s, HasSubstr("1970")); - EXPECT_THAT(s, HasSubstr("00:00:00")); + EXPECT_THAT(s, testing::HasSubstr("1970")); + EXPECT_THAT(s, testing::HasSubstr("00:00:00")); TestFormatSpecifier(tp, tz, "%p", "AM"); TestFormatSpecifier(tp, tz, "%x", "01/01/70"); @@ -246,7 +253,7 @@ TEST(Format, LocaleSpecific) { TEST(Format, Escaping) { const time_zone tz = utc_time_zone(); - auto tp = system_clock::from_time_t(0); + auto tp = chrono::system_clock::from_time_t(0); TestFormatSpecifier(tp, tz, "%%", "%"); TestFormatSpecifier(tp, tz, "%%a", "%a"); @@ -267,8 +274,8 @@ TEST(Format, ExtendedSeconds) { const time_zone tz = utc_time_zone(); // No subseconds. - time_point<nanoseconds> tp = system_clock::from_time_t(0); - tp += seconds(5); + time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); + tp += chrono::seconds(5); EXPECT_EQ("05", format("%E*S", tp, tz)); EXPECT_EQ("05", format("%E0S", tp, tz)); EXPECT_EQ("05.0", format("%E1S", tp, tz)); @@ -288,7 +295,8 @@ TEST(Format, ExtendedSeconds) { EXPECT_EQ("05.000000000000000", format("%E15S", tp, tz)); // With subseconds. - tp += milliseconds(6) + microseconds(7) + nanoseconds(8); + tp += chrono::milliseconds(6) + chrono::microseconds(7) + + chrono::nanoseconds(8); EXPECT_EQ("05.006007008", format("%E*S", tp, tz)); EXPECT_EQ("05", format("%E0S", tp, tz)); EXPECT_EQ("05.0", format("%E1S", tp, tz)); @@ -308,17 +316,18 @@ TEST(Format, ExtendedSeconds) { EXPECT_EQ("05.006007008000000", format("%E15S", tp, tz)); // Times before the Unix epoch. - tp = system_clock::from_time_t(0) + microseconds(-1); + tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1); EXPECT_EQ("1969-12-31 23:59:59.999999", format("%Y-%m-%d %H:%M:%E*S", tp, tz)); // Here is a "%E*S" case we got wrong for a while. While the first // instant below is correctly rendered as "...:07.333304", the second // one used to appear as "...:07.33330499999999999". - tp = system_clock::from_time_t(0) + microseconds(1395024427333304); + tp = chrono::system_clock::from_time_t(0) + + chrono::microseconds(1395024427333304); EXPECT_EQ("2014-03-17 02:47:07.333304", format("%Y-%m-%d %H:%M:%E*S", tp, tz)); - tp += microseconds(1); + tp += chrono::microseconds(1); EXPECT_EQ("2014-03-17 02:47:07.333305", format("%Y-%m-%d %H:%M:%E*S", tp, tz)); } @@ -327,8 +336,8 @@ TEST(Format, ExtendedSubeconds) { const time_zone tz = utc_time_zone(); // No subseconds. - time_point<nanoseconds> tp = system_clock::from_time_t(0); - tp += seconds(5); + time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); + tp += chrono::seconds(5); EXPECT_EQ("0", format("%E*f", tp, tz)); EXPECT_EQ("", format("%E0f", tp, tz)); EXPECT_EQ("0", format("%E1f", tp, tz)); @@ -348,7 +357,8 @@ TEST(Format, ExtendedSubeconds) { EXPECT_EQ("000000000000000", format("%E15f", tp, tz)); // With subseconds. - tp += milliseconds(6) + microseconds(7) + nanoseconds(8); + tp += chrono::milliseconds(6) + chrono::microseconds(7) + + chrono::nanoseconds(8); EXPECT_EQ("006007008", format("%E*f", tp, tz)); EXPECT_EQ("", format("%E0f", tp, tz)); EXPECT_EQ("0", format("%E1f", tp, tz)); @@ -368,17 +378,18 @@ TEST(Format, ExtendedSubeconds) { EXPECT_EQ("006007008000000", format("%E15f", tp, tz)); // Times before the Unix epoch. - tp = system_clock::from_time_t(0) + microseconds(-1); + tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1); EXPECT_EQ("1969-12-31 23:59:59.999999", format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); // Here is a "%E*S" case we got wrong for a while. While the first // instant below is correctly rendered as "...:07.333304", the second // one used to appear as "...:07.33330499999999999". - tp = system_clock::from_time_t(0) + microseconds(1395024427333304); + tp = chrono::system_clock::from_time_t(0) + + chrono::microseconds(1395024427333304); EXPECT_EQ("2014-03-17 02:47:07.333304", format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); - tp += microseconds(1); + tp += chrono::microseconds(1); EXPECT_EQ("2014-03-17 02:47:07.333305", format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); } @@ -393,8 +404,8 @@ TEST(Format, CompareExtendSecondsVsSubseconds) { auto fmt_B = [](const std::string& prec) { return "%S.%E" + prec + "f"; }; // No subseconds: - time_point<nanoseconds> tp = system_clock::from_time_t(0); - tp += seconds(5); + time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); + tp += chrono::seconds(5); // ... %E*S and %S.%E*f are different. EXPECT_EQ("05", format(fmt_A("*"), tp, tz)); EXPECT_EQ("05.0", format(fmt_B("*"), tp, tz)); @@ -410,7 +421,8 @@ TEST(Format, CompareExtendSecondsVsSubseconds) { // With subseconds: // ... %E*S and %S.%E*f are the same. - tp += milliseconds(6) + microseconds(7) + nanoseconds(8); + tp += chrono::milliseconds(6) + chrono::microseconds(7) + + chrono::nanoseconds(8); EXPECT_EQ("05.006007008", format(fmt_A("*"), tp, tz)); EXPECT_EQ("05.006007008", format(fmt_B("*"), tp, tz)); // ... %E0S and %S.%E0f are different. @@ -425,7 +437,7 @@ TEST(Format, CompareExtendSecondsVsSubseconds) { } TEST(Format, ExtendedOffset) { - auto tp = system_clock::from_time_t(0); + auto tp = chrono::system_clock::from_time_t(0); time_zone tz = utc_time_zone(); TestFormatSpecifier(tp, tz, "%Ez", "+00:00"); @@ -447,30 +459,28 @@ TEST(Format, ExtendedOffset) { TEST(Format, ExtendedSecondOffset) { const time_zone utc = utc_time_zone(); - time_point<seconds> tp; + time_point<chrono::seconds> tp; time_zone tz; EXPECT_TRUE(load_time_zone("America/New_York", &tz)); tp = convert(civil_second(1883, 11, 18, 16, 59, 59), utc); if (tz.lookup(tp).offset == -5 * 60 * 60) { - // We're likely dealing with zoneinfo that doesn't support really old - // timestamps, so America/New_York never looks to be on local mean time. + // It looks like the tzdata is only 32 bit (probably macOS), + // which bottoms out at 1901-12-13T20:45:52+00:00. } else { TestFormatSpecifier(tp, tz, "%E*z", "-04:56:02"); TestFormatSpecifier(tp, tz, "%Ez", "-04:56"); } - tp += seconds(1); + tp += chrono::seconds(1); TestFormatSpecifier(tp, tz, "%E*z", "-05:00:00"); EXPECT_TRUE(load_time_zone("Europe/Moscow", &tz)); tp = convert(civil_second(1919, 6, 30, 23, 59, 59), utc); -#if defined(__ANDROID__) && __ANDROID_API__ < 25 - // Only Android 'N'.1 and beyond have this tz2016g transition. -#else - TestFormatSpecifier(tp, tz, "%E*z", "+04:31:19"); - TestFormatSpecifier(tp, tz, "%Ez", "+04:31"); -#endif - tp += seconds(1); + if (VersionCmp(tz, "2016g") >= 0) { + TestFormatSpecifier(tp, tz, "%E*z", "+04:31:19"); + TestFormatSpecifier(tp, tz, "%Ez", "+04:31"); + } + tp += chrono::seconds(1); TestFormatSpecifier(tp, tz, "%E*z", "+04:00:00"); } @@ -511,44 +521,44 @@ TEST(Format, RFC3339Format) { time_zone tz; EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); - time_point<nanoseconds> tp = + time_point<chrono::nanoseconds> tp = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += milliseconds(100); + tp += chrono::milliseconds(100); EXPECT_EQ("1977-06-28T09:08:07.1-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += milliseconds(20); + tp += chrono::milliseconds(20); EXPECT_EQ("1977-06-28T09:08:07.12-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += milliseconds(3); + tp += chrono::milliseconds(3); EXPECT_EQ("1977-06-28T09:08:07.123-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += microseconds(400); + tp += chrono::microseconds(400); EXPECT_EQ("1977-06-28T09:08:07.1234-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += microseconds(50); + tp += chrono::microseconds(50); EXPECT_EQ("1977-06-28T09:08:07.12345-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += microseconds(6); + tp += chrono::microseconds(6); EXPECT_EQ("1977-06-28T09:08:07.123456-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += nanoseconds(700); + tp += chrono::nanoseconds(700); EXPECT_EQ("1977-06-28T09:08:07.1234567-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += nanoseconds(80); + tp += chrono::nanoseconds(80); EXPECT_EQ("1977-06-28T09:08:07.12345678-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); - tp += nanoseconds(9); + tp += chrono::nanoseconds(9); EXPECT_EQ("1977-06-28T09:08:07.123456789-07:00", format(RFC3339_full, tp, tz)); EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); @@ -571,13 +581,13 @@ TEST(Parse, TimePointResolution) { const char kFmt[] = "%H:%M:%E*S"; const time_zone utc = utc_time_zone(); - time_point<nanoseconds> tp_ns; + time_point<chrono::nanoseconds> tp_ns; EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_ns)); EXPECT_EQ("03:04:05.123456789", format(kFmt, tp_ns, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ns)); EXPECT_EQ("03:04:05.123456", format(kFmt, tp_ns, utc)); - time_point<microseconds> tp_us; + time_point<chrono::microseconds> tp_us; EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_us)); EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_us)); @@ -585,7 +595,7 @@ TEST(Parse, TimePointResolution) { EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_us)); EXPECT_EQ("03:04:05.123", format(kFmt, tp_us, utc)); - time_point<milliseconds> tp_ms; + time_point<chrono::milliseconds> tp_ms; EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ms)); EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_ms)); @@ -593,17 +603,17 @@ TEST(Parse, TimePointResolution) { EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_ms)); EXPECT_EQ("03:04:05", format(kFmt, tp_ms, utc)); - time_point<seconds> tp_s; + time_point<chrono::seconds> tp_s; EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_s)); EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_s)); EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc)); - time_point<minutes> tp_m; + time_point<chrono::minutes> tp_m; EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_m)); EXPECT_EQ("03:04:00", format(kFmt, tp_m, utc)); - time_point<hours> tp_h; + time_point<chrono::hours> tp_h; EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_h)); EXPECT_EQ("03:00:00", format(kFmt, tp_h, utc)); } @@ -612,7 +622,7 @@ TEST(Parse, TimePointExtendedResolution) { const char kFmt[] = "%H:%M:%E*S"; const time_zone utc = utc_time_zone(); - time_point<sys_seconds> tp; + time_point<absl::time_internal::cctz::seconds> tp; detail::femtoseconds fs; EXPECT_TRUE(detail::parse(kFmt, "12:34:56.123456789012345", utc, &tp, &fs)); EXPECT_EQ("12:34:56.123456789012345", detail::format(kFmt, tp, fs, utc)); @@ -630,11 +640,12 @@ TEST(Parse, TimePointExtendedResolution) { TEST(Parse, Basics) { time_zone tz = utc_time_zone(); - time_point<nanoseconds> tp = system_clock::from_time_t(1234567890); + time_point<chrono::nanoseconds> tp = + chrono::system_clock::from_time_t(1234567890); // Simple edge cases. EXPECT_TRUE(parse("", "", tz, &tp)); - EXPECT_EQ(system_clock::from_time_t(0), tp); // everything defaulted + EXPECT_EQ(chrono::system_clock::from_time_t(0), tp); // everything defaulted EXPECT_TRUE(parse(" ", " ", tz, &tp)); EXPECT_TRUE(parse(" ", " ", tz, &tp)); EXPECT_TRUE(parse("x", "x", tz, &tp)); @@ -648,7 +659,7 @@ TEST(Parse, Basics) { TEST(Parse, WithTimeZone) { time_zone tz; EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); - time_point<nanoseconds> tp; + time_point<chrono::nanoseconds> tp; // We can parse a std::string without a UTC offset if we supply a timezone. EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2013-06-28 19:08:09", tz, &tp)); @@ -659,13 +670,13 @@ TEST(Parse, WithTimeZone) { utc_time_zone(), &tp)); ExpectTime(tp, tz, 2013, 6, 28, 19 - 8 - 7, 8, 9, -7 * 60 * 60, true, "PDT"); - // Check a skipped time (a Spring DST transition). parse() returns - // the preferred-offset result, as defined for ConvertDateTime(). + // Check a skipped time (a Spring DST transition). parse() uses the + // pre-transition offset. EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2011-03-13 02:15:00", tz, &tp)); ExpectTime(tp, tz, 2011, 3, 13, 3, 15, 0, -7 * 60 * 60, true, "PDT"); - // Check a repeated time (a Fall DST transition). parse() returns - // the preferred-offset result, as defined for ConvertDateTime(). + // Check a repeated time (a Fall DST transition). parse() uses the + // pre-transition offset. EXPECT_TRUE(parse("%Y-%m-%d %H:%M:%S", "2011-11-06 01:15:00", tz, &tp)); ExpectTime(tp, tz, 2011, 11, 6, 1, 15, 0, -7 * 60 * 60, true, "PDT"); } @@ -673,7 +684,7 @@ TEST(Parse, WithTimeZone) { TEST(Parse, LeapSecond) { time_zone tz; EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); - time_point<nanoseconds> tp; + time_point<chrono::nanoseconds> tp; // ":59" -> ":59" EXPECT_TRUE(parse(RFC3339_full, "2013-06-28T07:08:59-08:00", tz, &tp)); @@ -697,7 +708,7 @@ TEST(Parse, LeapSecond) { TEST(Parse, ErrorCases) { const time_zone tz = utc_time_zone(); - auto tp = system_clock::from_time_t(0); + auto tp = chrono::system_clock::from_time_t(0); // Illegal trailing data. EXPECT_FALSE(parse("%S", "123", tz, &tp)); @@ -740,7 +751,7 @@ TEST(Parse, ErrorCases) { TEST(Parse, PosixConversions) { time_zone tz = utc_time_zone(); - auto tp = system_clock::from_time_t(0); + auto tp = chrono::system_clock::from_time_t(0); const auto reset = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); tp = reset; @@ -829,14 +840,14 @@ TEST(Parse, PosixConversions) { tp = reset; EXPECT_TRUE(parse("%s", "1234567890", tz, &tp)); - EXPECT_EQ(system_clock::from_time_t(1234567890), tp); + EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp); // %s conversion, like %z/%Ez, pays no heed to the optional zone. time_zone lax; EXPECT_TRUE(load_time_zone("America/Los_Angeles", &lax)); tp = reset; EXPECT_TRUE(parse("%s", "1234567890", lax, &tp)); - EXPECT_EQ(system_clock::from_time_t(1234567890), tp); + EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp); // This is most important when the time has the same YMDhms // breakdown in the zone as some other time. For example, ... @@ -844,16 +855,16 @@ TEST(Parse, PosixConversions) { // 1414920600 in US/Pacific -> Sun Nov 2 01:30:00 2014 (PST) tp = reset; EXPECT_TRUE(parse("%s", "1414917000", lax, &tp)); - EXPECT_EQ(system_clock::from_time_t(1414917000), tp); + EXPECT_EQ(chrono::system_clock::from_time_t(1414917000), tp); tp = reset; EXPECT_TRUE(parse("%s", "1414920600", lax, &tp)); - EXPECT_EQ(system_clock::from_time_t(1414920600), tp); + EXPECT_EQ(chrono::system_clock::from_time_t(1414920600), tp); #endif } TEST(Parse, LocaleSpecific) { time_zone tz = utc_time_zone(); - auto tp = system_clock::from_time_t(0); + auto tp = chrono::system_clock::from_time_t(0); const auto reset = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); // %a is parsed but ignored. @@ -984,7 +995,8 @@ TEST(Parse, LocaleSpecific) { TEST(Parse, ExtendedSeconds) { const time_zone tz = utc_time_zone(); - const time_point<nanoseconds> unix_epoch = system_clock::from_time_t(0); + const time_point<chrono::nanoseconds> unix_epoch = + chrono::system_clock::from_time_t(0); // All %E<prec>S cases are treated the same as %E*S on input. auto precisions = {"*", "0", "1", "2", "3", "4", "5", "6", "7", @@ -992,47 +1004,47 @@ TEST(Parse, ExtendedSeconds) { for (const std::string& prec : precisions) { const std::string fmt = "%E" + prec + "S"; SCOPED_TRACE(fmt); - time_point<nanoseconds> tp = unix_epoch; + time_point<chrono::nanoseconds> tp = unix_epoch; EXPECT_TRUE(parse(fmt, "5", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.0", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.00", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.6", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5) + milliseconds(600), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.60", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5) + milliseconds(600), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.600", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5) + milliseconds(600), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(600), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.67", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5) + milliseconds(670), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(670), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.670", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5) + milliseconds(670), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(670), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "05.678", tz, &tp)); - EXPECT_EQ(unix_epoch + seconds(5) + milliseconds(678), tp); + EXPECT_EQ(unix_epoch + chrono::seconds(5) + chrono::milliseconds(678), tp); } // Here is a "%E*S" case we got wrong for a while. The fractional // part of the first instant is less than 2^31 and was correctly // parsed, while the second (and any subsecond field >=2^31) failed. - time_point<nanoseconds> tp = unix_epoch; + time_point<chrono::nanoseconds> tp = unix_epoch; EXPECT_TRUE(parse("%E*S", "0.2147483647", tz, &tp)); - EXPECT_EQ(unix_epoch + nanoseconds(214748364), tp); + EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); tp = unix_epoch; EXPECT_TRUE(parse("%E*S", "0.2147483648", tz, &tp)); - EXPECT_EQ(unix_epoch + nanoseconds(214748364), tp); + EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); // We should also be able to specify long strings of digits far // beyond the current resolution and have them convert the same way. @@ -1040,18 +1052,18 @@ TEST(Parse, ExtendedSeconds) { EXPECT_TRUE(parse( "%E*S", "0.214748364801234567890123456789012345678901234567890123456789", tz, &tp)); - EXPECT_EQ(unix_epoch + nanoseconds(214748364), tp); + EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); } TEST(Parse, ExtendedSecondsScan) { const time_zone tz = utc_time_zone(); - time_point<nanoseconds> tp; + time_point<chrono::nanoseconds> tp; for (int ms = 0; ms < 1000; ms += 111) { for (int us = 0; us < 1000; us += 27) { const int micros = ms * 1000 + us; for (int ns = 0; ns < 1000; ns += 9) { - const auto expected = - system_clock::from_time_t(0) + nanoseconds(micros * 1000 + ns); + const auto expected = chrono::system_clock::from_time_t(0) + + chrono::nanoseconds(micros * 1000 + ns); std::ostringstream oss; oss << "0." << std::setfill('0') << std::setw(3); oss << ms << std::setw(3) << us << std::setw(3) << ns; @@ -1065,7 +1077,8 @@ TEST(Parse, ExtendedSecondsScan) { TEST(Parse, ExtendedSubeconds) { const time_zone tz = utc_time_zone(); - const time_point<nanoseconds> unix_epoch = system_clock::from_time_t(0); + const time_point<chrono::nanoseconds> unix_epoch = + chrono::system_clock::from_time_t(0); // All %E<prec>f cases are treated the same as %E*f on input. auto precisions = {"*", "0", "1", "2", "3", "4", "5", "6", "7", @@ -1073,41 +1086,42 @@ TEST(Parse, ExtendedSubeconds) { for (const std::string& prec : precisions) { const std::string fmt = "%E" + prec + "f"; SCOPED_TRACE(fmt); - time_point<nanoseconds> tp = unix_epoch - seconds(1); + time_point<chrono::nanoseconds> tp = unix_epoch - chrono::seconds(1); EXPECT_TRUE(parse(fmt, "", tz, &tp)); EXPECT_EQ(unix_epoch, tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "6", tz, &tp)); - EXPECT_EQ(unix_epoch + milliseconds(600), tp); + EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "60", tz, &tp)); - EXPECT_EQ(unix_epoch + milliseconds(600), tp); + EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "600", tz, &tp)); - EXPECT_EQ(unix_epoch + milliseconds(600), tp); + EXPECT_EQ(unix_epoch + chrono::milliseconds(600), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "67", tz, &tp)); - EXPECT_EQ(unix_epoch + milliseconds(670), tp); + EXPECT_EQ(unix_epoch + chrono::milliseconds(670), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "670", tz, &tp)); - EXPECT_EQ(unix_epoch + milliseconds(670), tp); + EXPECT_EQ(unix_epoch + chrono::milliseconds(670), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "678", tz, &tp)); - EXPECT_EQ(unix_epoch + milliseconds(678), tp); + EXPECT_EQ(unix_epoch + chrono::milliseconds(678), tp); tp = unix_epoch; EXPECT_TRUE(parse(fmt, "6789", tz, &tp)); - EXPECT_EQ(unix_epoch + milliseconds(678) + microseconds(900), tp); + EXPECT_EQ( + unix_epoch + chrono::milliseconds(678) + chrono::microseconds(900), tp); } // Here is a "%E*f" case we got wrong for a while. The fractional // part of the first instant is less than 2^31 and was correctly // parsed, while the second (and any subsecond field >=2^31) failed. - time_point<nanoseconds> tp = unix_epoch; + time_point<chrono::nanoseconds> tp = unix_epoch; EXPECT_TRUE(parse("%E*f", "2147483647", tz, &tp)); - EXPECT_EQ(unix_epoch + nanoseconds(214748364), tp); + EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); tp = unix_epoch; EXPECT_TRUE(parse("%E*f", "2147483648", tz, &tp)); - EXPECT_EQ(unix_epoch + nanoseconds(214748364), tp); + EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); // We should also be able to specify long strings of digits far // beyond the current resolution and have them convert the same way. @@ -1115,11 +1129,11 @@ TEST(Parse, ExtendedSubeconds) { EXPECT_TRUE(parse( "%E*f", "214748364801234567890123456789012345678901234567890123456789", tz, &tp)); - EXPECT_EQ(unix_epoch + nanoseconds(214748364), tp); + EXPECT_EQ(unix_epoch + chrono::nanoseconds(214748364), tp); } TEST(Parse, ExtendedSubecondsScan) { - time_point<nanoseconds> tp; + time_point<chrono::nanoseconds> tp; const time_zone tz = utc_time_zone(); for (int ms = 0; ms < 1000; ms += 111) { for (int us = 0; us < 1000; us += 27) { @@ -1129,14 +1143,14 @@ TEST(Parse, ExtendedSubecondsScan) { oss << std::setfill('0') << std::setw(3) << ms; oss << std::setw(3) << us << std::setw(3) << ns; const std::string nanos = oss.str(); - const auto expected = - system_clock::from_time_t(0) + nanoseconds(micros * 1000 + ns); + const auto expected = chrono::system_clock::from_time_t(0) + + chrono::nanoseconds(micros * 1000 + ns); for (int ps = 0; ps < 1000; ps += 250) { std::ostringstream oss; oss << std::setfill('0') << std::setw(3) << ps; const std::string input = nanos + oss.str() + "999"; EXPECT_TRUE(parse("%E*f", input, tz, &tp)); - EXPECT_EQ(expected + nanoseconds(ps) / 1000, tp) << input; + EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input; } } } @@ -1145,7 +1159,7 @@ TEST(Parse, ExtendedSubecondsScan) { TEST(Parse, ExtendedOffset) { const time_zone utc = utc_time_zone(); - time_point<sys_seconds> tp; + time_point<absl::time_internal::cctz::seconds> tp; // %z against +-HHMM. EXPECT_TRUE(parse("%z", "+0000", utc, &tp)); @@ -1195,7 +1209,7 @@ TEST(Parse, ExtendedOffset) { TEST(Parse, ExtendedSecondOffset) { const time_zone utc = utc_time_zone(); - time_point<sys_seconds> tp; + time_point<absl::time_internal::cctz::seconds> tp; // %Ez against +-HH:MM:SS. EXPECT_TRUE(parse("%Ez", "+00:00:00", utc, &tp)); @@ -1264,7 +1278,7 @@ TEST(Parse, ExtendedSecondOffset) { TEST(Parse, ExtendedYears) { const time_zone utc = utc_time_zone(); const char e4y_fmt[] = "%E4Y%m%d"; // no separators - time_point<sys_seconds> tp; + time_point<absl::time_internal::cctz::seconds> tp; // %E4Y consumes exactly four chars, including any sign. EXPECT_TRUE(parse(e4y_fmt, "-9991127", utc, &tp)); @@ -1295,45 +1309,45 @@ TEST(Parse, ExtendedYears) { TEST(Parse, RFC3339Format) { const time_zone tz = utc_time_zone(); - time_point<nanoseconds> tp; + time_point<chrono::nanoseconds> tp; EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00+00:00", tz, &tp)); ExpectTime(tp, tz, 2014, 2, 12, 20, 21, 0, 0, false, "UTC"); // Check that %Ez also accepts "Z" as a synonym for "+00:00". - time_point<nanoseconds> tp2; + time_point<chrono::nanoseconds> tp2; EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp2)); EXPECT_EQ(tp, tp2); } TEST(Parse, MaxRange) { const time_zone utc = utc_time_zone(); - time_point<sys_seconds> tp; + time_point<absl::time_internal::cctz::seconds> tp; // tests the upper limit using +00:00 offset EXPECT_TRUE( parse(RFC3339_sec, "292277026596-12-04T15:30:07+00:00", utc, &tp)); - EXPECT_EQ(tp, time_point<sys_seconds>::max()); + EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::max()); EXPECT_FALSE( parse(RFC3339_sec, "292277026596-12-04T15:30:08+00:00", utc, &tp)); // tests the upper limit using -01:00 offset EXPECT_TRUE( parse(RFC3339_sec, "292277026596-12-04T14:30:07-01:00", utc, &tp)); - EXPECT_EQ(tp, time_point<sys_seconds>::max()); + EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::max()); EXPECT_FALSE( parse(RFC3339_sec, "292277026596-12-04T15:30:07-01:00", utc, &tp)); // tests the lower limit using +00:00 offset EXPECT_TRUE( parse(RFC3339_sec, "-292277022657-01-27T08:29:52+00:00", utc, &tp)); - EXPECT_EQ(tp, time_point<sys_seconds>::min()); + EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::min()); EXPECT_FALSE( parse(RFC3339_sec, "-292277022657-01-27T08:29:51+00:00", utc, &tp)); // tests the lower limit using +01:00 offset EXPECT_TRUE( parse(RFC3339_sec, "-292277022657-01-27T09:29:52+01:00", utc, &tp)); - EXPECT_EQ(tp, time_point<sys_seconds>::min()); + EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::min()); EXPECT_FALSE( parse(RFC3339_sec, "-292277022657-01-27T08:29:51+01:00", utc, &tp)); @@ -1356,11 +1370,11 @@ TEST(FormatParse, RoundTrip) { time_zone lax; EXPECT_TRUE(load_time_zone("America/Los_Angeles", &lax)); const auto in = convert(civil_second(1977, 6, 28, 9, 8, 7), lax); - const auto subseconds = nanoseconds(654321); + const auto subseconds = chrono::nanoseconds(654321); // RFC3339, which renders subseconds. { - time_point<nanoseconds> out; + time_point<chrono::nanoseconds> out; const std::string s = format(RFC3339_full, in + subseconds, lax); EXPECT_TRUE(parse(RFC3339_full, s, lax, &out)) << s; EXPECT_EQ(in + subseconds, out); // RFC3339_full includes %Ez @@ -1368,7 +1382,7 @@ TEST(FormatParse, RoundTrip) { // RFC1123, which only does whole seconds. { - time_point<nanoseconds> out; + time_point<chrono::nanoseconds> out; const std::string s = format(RFC1123_full, in, lax); EXPECT_TRUE(parse(RFC1123_full, s, lax, &out)) << s; EXPECT_EQ(in, out); // RFC1123_full includes %z @@ -1381,7 +1395,7 @@ TEST(FormatParse, RoundTrip) { // Even though we don't know what %c will produce, it should roundtrip, // but only in the 0-offset timezone. { - time_point<nanoseconds> out; + time_point<chrono::nanoseconds> out; time_zone utc = utc_time_zone(); const std::string s = format("%c", in, utc); EXPECT_TRUE(parse("%c", s, utc, &out)) << s; @@ -1392,23 +1406,23 @@ TEST(FormatParse, RoundTrip) { TEST(FormatParse, RoundTripDistantFuture) { const time_zone utc = utc_time_zone(); - const time_point<sys_seconds> in = time_point<sys_seconds>::max(); + const time_point<absl::time_internal::cctz::seconds> in = time_point<absl::time_internal::cctz::seconds>::max(); const std::string s = format(RFC3339_full, in, utc); - time_point<sys_seconds> out; + time_point<absl::time_internal::cctz::seconds> out; EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s; EXPECT_EQ(in, out); } TEST(FormatParse, RoundTripDistantPast) { const time_zone utc = utc_time_zone(); - const time_point<sys_seconds> in = time_point<sys_seconds>::min(); + const time_point<absl::time_internal::cctz::seconds> in = time_point<absl::time_internal::cctz::seconds>::min(); const std::string s = format(RFC3339_full, in, utc); - time_point<sys_seconds> out; + time_point<absl::time_internal::cctz::seconds> out; EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s; EXPECT_EQ(in, out); } } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_if.cc b/absl/time/internal/cctz/src/time_zone_if.cc index d289a5c9..f7c36b2b 100644 --- a/absl/time/internal/cctz/src/time_zone_if.cc +++ b/absl/time/internal/cctz/src/time_zone_if.cc @@ -17,7 +17,7 @@ #include "time_zone_libc.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -39,5 +39,5 @@ TimeZoneIf::~TimeZoneIf() {} } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_if.h b/absl/time/internal/cctz/src/time_zone_if.h index 2d5f885d..9886f2c5 100644 --- a/absl/time/internal/cctz/src/time_zone_if.h +++ b/absl/time/internal/cctz/src/time_zone_if.h @@ -24,7 +24,7 @@ #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -38,35 +38,37 @@ class TimeZoneIf { virtual ~TimeZoneIf(); virtual time_zone::absolute_lookup BreakTime( - const time_point<sys_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 std::string Description() const = 0; - virtual bool NextTransition(time_point<sys_seconds>* tp) const = 0; - virtual bool PrevTransition(time_point<sys_seconds>* tp) const = 0; protected: TimeZoneIf() {} }; -// Convert between time_point<sys_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<sys_seconds>& tp) { - return (tp - std::chrono::time_point_cast<sys_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<sys_seconds> FromUnixSeconds(std::int_fast64_t t) { - return std::chrono::time_point_cast<sys_seconds>( - std::chrono::system_clock::from_time_t(0)) + - sys_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 } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_ diff --git a/absl/time/internal/cctz/src/time_zone_impl.cc b/absl/time/internal/cctz/src/time_zone_impl.cc index 3ba40ac2..a4e42916 100644 --- a/absl/time/internal/cctz/src/time_zone_impl.cc +++ b/absl/time/internal/cctz/src/time_zone_impl.cc @@ -22,7 +22,7 @@ #include "time_zone_fixed.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -46,8 +46,8 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { const time_zone::Impl* const utc_impl = UTCImpl(); // First check for UTC (which is never a key in time_zone_map). - auto offset = sys_seconds::zero(); - if (FixedOffsetFromName(name, &offset) && offset == sys_seconds::zero()) { + auto offset = seconds::zero(); + if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) { *tz = time_zone(utc_impl); return true; } @@ -84,15 +84,6 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { return impl != utc_impl; } -const time_zone::Impl& time_zone::Impl::get(const time_zone& tz) { - if (tz.impl_ == nullptr) { - // Dereferencing an implicit-UTC time_zone is expected to be - // rare, so we don't mind paying a small synchronization cost. - return *UTCImpl(); - } - return *tz.impl_; -} - void time_zone::Impl::ClearTimeZoneMapTestOnly() { std::lock_guard<std::mutex> lock(time_zone_mutex); if (time_zone_map != nullptr) { @@ -115,5 +106,5 @@ const time_zone::Impl* time_zone::Impl::UTCImpl() { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_impl.h b/absl/time/internal/cctz/src/time_zone_impl.h index a955e40e..7da2e99d 100644 --- a/absl/time/internal/cctz/src/time_zone_impl.h +++ b/absl/time/internal/cctz/src/time_zone_impl.h @@ -24,7 +24,7 @@ #include "time_zone_info.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -38,19 +38,18 @@ class time_zone::Impl { // some other kind of error occurs. Note that loading "UTC" never fails. static bool LoadTimeZone(const std::string& name, time_zone* tz); - // Dereferences the time_zone to obtain its Impl. - static const time_zone::Impl& get(const time_zone& tz); - // Clears the map of cached time zones. Primarily for use in benchmarks // that gauge the performance of loading/parsing the time-zone data. static void ClearTimeZoneMapTestOnly(); // The primary key is the time-zone ID (e.g., "America/New_York"). - const std::string& name() const { 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<sys_seconds>& tp) const { + time_zone::absolute_lookup BreakTime(const time_point<seconds>& tp) const { return zone_->BreakTime(tp); } @@ -61,28 +60,22 @@ class time_zone::Impl { return zone_->MakeTime(cs); } - // Returns an implementation-specific description of this time zone. - std::string Description() const { return zone_->Description(); } - // Finds the time of the next/previous offset change in this time zone. - // - // By definition, NextTransition(&tp) returns false when tp has its - // maximum value, and PrevTransition(&tp) returns false when tp has its - // mimimum value. If the zone has no transitions, the result will also - // be false no matter what the argument. - // - // Otherwise, when tp has its mimimum value, NextTransition(&tp) returns - // true and sets tp to the first recorded transition. Chains of calls - // to NextTransition()/PrevTransition() will eventually return false, - // but it is unspecified exactly when NextTransition(&tp) jumps to false, - // or what time is set by PrevTransition(&tp) for a very distant tp. - bool NextTransition(time_point<sys_seconds>* tp) const { - return zone_->NextTransition(tp); + bool NextTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { + return zone_->NextTransition(tp, trans); } - bool PrevTransition(time_point<sys_seconds>* tp) const { - return zone_->PrevTransition(tp); + bool PrevTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { + return zone_->PrevTransition(tp, trans); } + // Returns an implementation-defined version std::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(); @@ -93,7 +86,7 @@ class time_zone::Impl { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_ diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc index 7f5a8fad..e19d1d2d 100644 --- a/absl/time/internal/cctz/src/time_zone_info.cc +++ b/absl/time/internal/cctz/src/time_zone_info.cc @@ -50,7 +50,7 @@ #include "time_zone_posix.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -141,7 +141,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<sys_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; @@ -180,21 +180,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 sys_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 (2012 through 2021) + // We temporarily add some redundant, contemporary (2013 through 2023) // 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), // BIG_BANG - 1325376000LL, // 2012-01-01T00:00:00+00:00 1356998400LL, // 2013-01-01T00:00:00+00:00 1388534400LL, // 2014-01-01T00:00:00+00:00 1420070400LL, // 2015-01-01T00:00:00+00:00 @@ -204,6 +203,8 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const sys_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 2147483647LL, // 2^31 - 1 }) { Transition& tr(*transitions_.emplace(transitions_.end())); @@ -219,8 +220,8 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const sys_seconds& offset) { future_spec_.clear(); // never needed for a fixed-offset zone extended_ = false; - tt.civil_max = LocalTime(sys_seconds::max().count(), tt).cs; - tt.civil_min = LocalTime(sys_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; @@ -286,7 +287,7 @@ bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index, return true; } -// Use the POSIX-TZ-environment-variable-style std::string to handle times +// Use the POSIX-TZ-environment-variable-style string to handle times // in years after the last transition stored in the zoneinfo data. void TimeZoneInfo::ExtendTransitions(const std::string& name, const Header& hdr) { @@ -520,6 +521,13 @@ bool TimeZoneInfo::Load(const std::string& name, 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 std::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). @@ -566,10 +574,10 @@ bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) { } // Compute the maximum/minimum civil times that can be converted to a - // time_point<sys_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(sys_seconds::max().count(), tt).cs; - tt.civil_min = LocalTime(sys_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(); @@ -606,6 +614,10 @@ class FileZoneInfoSource : public ZoneInfoSource { 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( @@ -655,14 +667,15 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open( return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(fp, length)); } -#if defined(__ANDROID__) 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) - : FileZoneInfoSource(fp, len) {} + 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( @@ -670,6 +683,7 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( // Use of the "file:" prefix is intended for testing purposes only. if (name.compare(0, 5, "file:") == 0) return Open(name.substr(5)); +#if defined(__ANDROID__) // See Android's libc/tzcode/bionic.cpp for additional information. for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", "/system/usr/share/zoneinfo/tzdata"}) { @@ -679,6 +693,7 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( 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; @@ -699,13 +714,13 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( if (strcmp(name.c_str(), 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))); + fp.release(), static_cast<std::size_t>(length), vers)); } } } +#endif // __ANDROID__ return nullptr; } -#endif } // namespace @@ -714,7 +729,7 @@ 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 = sys_seconds::zero(); + auto offset = seconds::zero(); if (FixedOffsetFromName(name, &offset)) { return ResetToBuiltinUTC(offset); } @@ -723,9 +738,7 @@ bool TimeZoneInfo::Load(const std::string& name) { auto zip = cctz_extension::zone_info_source_factory( name, [](const std::string& name) -> std::unique_ptr<ZoneInfoSource> { if (auto zip = FileZoneInfoSource::Open(name)) return zip; -#if defined(__ANDROID__) if (auto zip = AndroidZoneInfoSource::Open(name)) return zip; -#endif return nullptr; }); return zip != nullptr && Load(name, zip.get()); @@ -756,14 +769,14 @@ time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs, 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 > sys_seconds::max().count() / kSecsPer400Years) { - cl.pre = cl.trans = cl.post = time_point<sys_seconds>::max(); + if (c4_shift > seconds::max().count() / kSecsPer400Years) { + cl.pre = cl.trans = cl.post = time_point<seconds>::max(); } else { - const auto offset = sys_seconds(c4_shift * kSecsPer400Years); - const auto limit = time_point<sys_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<sys_seconds>::max(); + *tp = time_point<seconds>::max(); } else { *tp += offset; } @@ -773,7 +786,7 @@ time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs, } time_zone::absolute_lookup TimeZoneInfo::BreakTime( - const time_point<sys_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. @@ -789,7 +802,7 @@ time_zone::absolute_lookup TimeZoneInfo::BreakTime( const std::int_fast64_t diff = unix_time - transitions_[timecnt - 1].unix_time; const year_t shift = diff / kSecsPer400Years + 1; - const auto d = sys_seconds(shift * kSecsPer400Years); + const auto d = seconds(shift * kSecsPer400Years); time_zone::absolute_lookup al = BreakTime(tp - d); al.cs = YearShift(al.cs, shift * 400); return al; @@ -848,7 +861,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<sys_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 @@ -865,7 +878,7 @@ time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const { return TimeLocal(YearShift(cs, shift * -400), shift); } const TransitionType& tt(transition_types_[tr->type_index]); - if (cs > tt.civil_max) return MakeUnique(time_point<sys_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 @@ -886,17 +899,20 @@ 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::Description() const { std::ostringstream oss; - // TODO: It would nice if the zoneinfo data included the zone name. - // TODO: It would nice if the zoneinfo data included the tzdb version. oss << "#trans=" << transitions_.size(); oss << " #types=" << transition_types_.size(); oss << " spec='" << future_spec_ << "'"; return oss.str(); } -bool TimeZoneInfo::NextTransition(time_point<sys_seconds>* tp) 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(); @@ -905,22 +921,24 @@ bool TimeZoneInfo::NextTransition(time_point<sys_seconds>* tp) const { // really a sentinel, not a transition. See tz/zic.c. ++begin; } - std::int_fast64_t unix_time = ToUnixSeconds(*tp); + std::int_fast64_t unix_time = ToUnixSeconds(tp); const Transition target = { unix_time }; const Transition* tr = std::upper_bound(begin, end, target, Transition::ByUnixTime()); - if (tr != begin) { // skip no-op transitions - for (; tr != end; ++tr) { - if (!EquivTransitions(tr[-1].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; - *tp = FromUnixSeconds(tr->unix_time); + trans->from = tr->prev_civil_sec + 1; + trans->to = tr->civil_sec; return true; } -bool TimeZoneInfo::PrevTransition(time_point<sys_seconds>* tp) 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(); @@ -929,11 +947,12 @@ bool TimeZoneInfo::PrevTransition(time_point<sys_seconds>* tp) const { // really a sentinel, not a transition. See 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_. - *tp = FromUnixSeconds((--end)->unix_time); + trans->from = (--end)->prev_civil_sec + 1; + trans->to = end->civil_sec; return true; } unix_time += 1; // ceils @@ -941,18 +960,19 @@ bool TimeZoneInfo::PrevTransition(time_point<sys_seconds>* tp) const { const Transition target = { unix_time }; const Transition* tr = std::lower_bound(begin, end, target, Transition::ByUnixTime()); - if (tr != begin) { // skip no-op transitions - for (; tr - 1 != begin; --tr) { - if (!EquivTransitions(tr[-2].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; - *tp = FromUnixSeconds((--tr)->unix_time); + trans->from = (--tr)->prev_civil_sec + 1; + trans->to = tr->civil_sec; return true; } } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_info.h b/absl/time/internal/cctz/src/time_zone_info.h index 5abf2811..e7a7d02f 100644 --- a/absl/time/internal/cctz/src/time_zone_info.h +++ b/absl/time/internal/cctz/src/time_zone_info.h @@ -28,7 +28,7 @@ #include "tzfile.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -72,12 +72,15 @@ class TimeZoneInfo : public TimeZoneIf { // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( - const time_point<sys_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; std::string Description() const override; - bool NextTransition(time_point<sys_seconds>* tp) const override; - bool PrevTransition(time_point<sys_seconds>* tp) const override; private: struct Header { // counts of: @@ -99,7 +102,7 @@ class TimeZoneInfo : public TimeZoneIf { std::uint_fast8_t tt2_index) const; void ExtendTransitions(const std::string& name, const Header& hdr); - bool ResetToBuiltinUTC(const sys_seconds& offset); + bool ResetToBuiltinUTC(const seconds& offset); bool Load(const std::string& name, ZoneInfoSource* zip); // Helpers for BreakTime() and MakeTime(). @@ -115,6 +118,7 @@ class TimeZoneInfo : public TimeZoneIf { 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 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 @@ -128,7 +132,7 @@ class TimeZoneInfo : public TimeZoneIf { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_ diff --git a/absl/time/internal/cctz/src/time_zone_libc.cc b/absl/time/internal/cctz/src/time_zone_libc.cc index 32a7a927..3dd75b50 100644 --- a/absl/time/internal/cctz/src/time_zone_libc.cc +++ b/absl/time/internal/cctz/src/time_zone_libc.cc @@ -20,6 +20,7 @@ #include <chrono> #include <ctime> +#include <limits> #include <tuple> #include <utility> @@ -27,7 +28,7 @@ #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -86,73 +87,206 @@ OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::__tm_gmtoff) = nullptr, #endif // !defined(__tm_gmtoff) && !defined(__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 +} + +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 = get_offset_abbr(tm).first; + 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; + if (std::tm* tmp = local_time(&mid, &tm)) { + if (get_offset_abbr(*tmp).first == 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) { + if (std::tm* tmp = local_time(&lo, &tm)) { + if (get_offset_abbr(*tmp).first == 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<sys_seconds>& tp) const { + const time_point<seconds>& tp) const { time_zone::absolute_lookup al; - std::time_t t = ToUnixSeconds(tp); + 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; - if (local_) { -#if defined(_WIN32) || defined(_WIN64) - localtime_s(&tm, &t); -#else - localtime_r(&t, &tm); -#endif - std::tie(al.offset, al.abbr) = get_offset_abbr(tm); - } else { -#if defined(_WIN32) || defined(_WIN64) - gmtime_s(&tm, &t); -#else - gmtime_r(&t, &tm); -#endif - al.offset = 0; - al.abbr = "UTC"; + 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; } - al.cs = civil_second(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - al.is_dst = tm.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); + std::tie(al.offset, al.abbr) = get_offset_abbr(*tmp); + if (!local_) al.abbr = "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 { - time_zone::civil_lookup cl; - std::time_t t; - if (local_) { - // Does not handle SKIPPED/AMBIGUOUS or huge years. - std::tm tm; - tm.tm_year = static_cast<int>(cs.year() - 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 = -1; - t = std::mktime(&tm); + 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 { - t = cs - civil_second(); + 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}; + } } - cl.kind = time_zone::civil_lookup::UNIQUE; - cl.pre = cl.trans = cl.post = FromUnixSeconds(t); - return cl; -} -std::string TimeZoneLibC::Description() const { - return local_ ? "localtime" : "UTC"; + // 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(time_point<sys_seconds>* tp) const { +bool TimeZoneLibC::NextTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { return false; } -bool TimeZoneLibC::PrevTransition(time_point<sys_seconds>* tp) const { +bool TimeZoneLibC::PrevTransition(const time_point<seconds>& tp, + time_zone::civil_transition* trans) const { return false; } +std::string TimeZoneLibC::Version() const { + return std::string(); // unknown +} + +std::string TimeZoneLibC::Description() const { + return local_ ? "localtime" : "UTC"; +} + } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_libc.h b/absl/time/internal/cctz/src/time_zone_libc.h index 0856b200..67372d45 100644 --- a/absl/time/internal/cctz/src/time_zone_libc.h +++ b/absl/time/internal/cctz/src/time_zone_libc.h @@ -20,7 +20,7 @@ #include "time_zone_if.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -33,12 +33,15 @@ class TimeZoneLibC : public TimeZoneIf { // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( - const time_point<sys_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; std::string Description() const override; - bool NextTransition(time_point<sys_seconds>* tp) const override; - bool PrevTransition(time_point<sys_seconds>* tp) const override; private: const bool local_; // localtime or UTC @@ -46,7 +49,7 @@ class TimeZoneLibC : public TimeZoneIf { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_ diff --git a/absl/time/internal/cctz/src/time_zone_lookup.cc b/absl/time/internal/cctz/src/time_zone_lookup.cc index 18d1565f..711d705a 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup.cc @@ -28,7 +28,7 @@ #include "time_zone_impl.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -62,20 +62,43 @@ int __system_property_get(const char* name, char* value) { #endif std::string time_zone::name() const { - return time_zone::Impl::get(*this).name(); + return effective_impl().Name(); } time_zone::absolute_lookup time_zone::lookup( - const time_point<sys_seconds>& tp) const { - return time_zone::Impl::get(*this).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 time_zone::Impl::get(*this).MakeTime(cs); + return effective_impl().MakeTime(cs); } -bool operator==(time_zone lhs, time_zone rhs) { - return &time_zone::Impl::get(lhs) == &time_zone::Impl::get(rhs); +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) { @@ -86,7 +109,7 @@ time_zone utc_time_zone() { return time_zone::Impl::UTC(); // avoid name lookup } -time_zone fixed_time_zone(const sys_seconds& offset) { +time_zone fixed_time_zone(const seconds& offset) { time_zone tz; load_time_zone(FixedOffsetToName(offset), &tz); return tz; @@ -143,5 +166,5 @@ time_zone local_time_zone() { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index a1b6c687..e0e355ee 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -16,7 +16,9 @@ #include <chrono> #include <cstddef> +#include <cstdlib> #include <future> +#include <limits> #include <string> #include <thread> #include <vector> @@ -24,17 +26,10 @@ #include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "gtest/gtest.h" -using std::chrono::time_point_cast; -using std::chrono::system_clock; -using std::chrono::nanoseconds; -using std::chrono::microseconds; -using std::chrono::milliseconds; -using std::chrono::seconds; -using std::chrono::minutes; -using std::chrono::hours; +namespace chrono = std::chrono; namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -659,6 +654,17 @@ time_zone LoadZone(const std::string& name) { /* EXPECT_STREQ(zone, al.abbr); */ \ } while (0) +// These tests sometimes run on platforms that have zoneinfo data so old +// that the transition we are attempting to check does not exist, most +// notably Android emulators. Fortunately, AndroidZoneInfoSource supports +// time_zone::version() so, in cases where we've learned that it matters, +// we can make the check conditionally. +int VersionCmp(time_zone tz, const std::string& target) { + std::string version = tz.version(); + if (version.empty() && !target.empty()) return 1; // unknown > known + return version.compare(target); +} + } // namespace TEST(TimeZones, LoadZonesConcurrently) { @@ -716,13 +722,13 @@ TEST(TimeZone, NamedTimeZones) { EXPECT_EQ("America/New_York", nyc.name()); const time_zone syd = LoadZone("Australia/Sydney"); EXPECT_EQ("Australia/Sydney", syd.name()); - const time_zone fixed0 = fixed_time_zone(sys_seconds::zero()); + const time_zone fixed0 = fixed_time_zone(absl::time_internal::cctz::seconds::zero()); EXPECT_EQ("UTC", fixed0.name()); - const time_zone fixed_pos = - fixed_time_zone(hours(3) + minutes(25) + seconds(45)); + const time_zone fixed_pos = fixed_time_zone( + chrono::hours(3) + chrono::minutes(25) + chrono::seconds(45)); EXPECT_EQ("Fixed/UTC+03:25:45", fixed_pos.name()); - const time_zone fixed_neg = - fixed_time_zone(-(hours(12) + minutes(34) + seconds(56))); + const time_zone fixed_neg = fixed_time_zone( + -(chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56))); EXPECT_EQ("Fixed/UTC-12:34:56", fixed_neg.name()); } @@ -732,19 +738,19 @@ TEST(TimeZone, Failures) { tz = LoadZone("America/Los_Angeles"); EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz)); - EXPECT_EQ(system_clock::from_time_t(0), + EXPECT_EQ(chrono::system_clock::from_time_t(0), convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC // Ensures that the load still fails on a subsequent attempt. tz = LoadZone("America/Los_Angeles"); EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz)); - EXPECT_EQ(system_clock::from_time_t(0), + EXPECT_EQ(chrono::system_clock::from_time_t(0), convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC // Loading an empty std::string timezone should fail. tz = LoadZone("America/Los_Angeles"); EXPECT_FALSE(load_time_zone("", &tz)); - EXPECT_EQ(system_clock::from_time_t(0), + EXPECT_EQ(chrono::system_clock::from_time_t(0), convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC } @@ -759,7 +765,7 @@ TEST(TimeZone, Equality) { EXPECT_EQ(implicit_utc, explicit_utc); EXPECT_EQ(implicit_utc.name(), explicit_utc.name()); - const time_zone fixed_zero = fixed_time_zone(sys_seconds::zero()); + const time_zone fixed_zero = fixed_time_zone(absl::time_internal::cctz::seconds::zero()); EXPECT_EQ(fixed_zero, LoadZone(fixed_zero.name())); EXPECT_EQ(fixed_zero, explicit_utc); @@ -767,23 +773,25 @@ TEST(TimeZone, Equality) { EXPECT_EQ(fixed_utc, LoadZone(fixed_utc.name())); EXPECT_EQ(fixed_utc, explicit_utc); - const time_zone fixed_pos = - fixed_time_zone(hours(3) + minutes(25) + seconds(45)); + const time_zone fixed_pos = fixed_time_zone( + chrono::hours(3) + chrono::minutes(25) + chrono::seconds(45)); EXPECT_EQ(fixed_pos, LoadZone(fixed_pos.name())); EXPECT_NE(fixed_pos, explicit_utc); - const time_zone fixed_neg = - fixed_time_zone(-(hours(12) + minutes(34) + seconds(56))); + const time_zone fixed_neg = fixed_time_zone( + -(chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56))); EXPECT_EQ(fixed_neg, LoadZone(fixed_neg.name())); EXPECT_NE(fixed_neg, explicit_utc); - const time_zone fixed_lim = fixed_time_zone(hours(24)); + const time_zone fixed_lim = fixed_time_zone(chrono::hours(24)); EXPECT_EQ(fixed_lim, LoadZone(fixed_lim.name())); EXPECT_NE(fixed_lim, explicit_utc); - const time_zone fixed_ovfl = fixed_time_zone(hours(24) + seconds(1)); + const time_zone fixed_ovfl = + fixed_time_zone(chrono::hours(24) + chrono::seconds(1)); EXPECT_EQ(fixed_ovfl, LoadZone(fixed_ovfl.name())); EXPECT_EQ(fixed_ovfl, explicit_utc); - EXPECT_EQ(fixed_time_zone(seconds(1)), fixed_time_zone(seconds(1))); + EXPECT_EQ(fixed_time_zone(chrono::seconds(1)), + fixed_time_zone(chrono::seconds(1))); const time_zone local = local_time_zone(); EXPECT_EQ(local, LoadZone(local.name())); @@ -796,40 +804,43 @@ TEST(TimeZone, Equality) { TEST(StdChronoTimePoint, TimeTAlignment) { // Ensures that the Unix epoch and the system clock epoch are an integral // number of seconds apart. This simplifies conversions to/from time_t. - auto diff = system_clock::time_point() - system_clock::from_time_t(0); - EXPECT_EQ(system_clock::time_point::duration::zero(), diff % seconds(1)); + auto diff = chrono::system_clock::time_point() - + chrono::system_clock::from_time_t(0); + EXPECT_EQ(chrono::system_clock::time_point::duration::zero(), + diff % chrono::seconds(1)); } TEST(BreakTime, TimePointResolution) { const time_zone utc = utc_time_zone(); - const auto t0 = system_clock::from_time_t(0); + const auto t0 = chrono::system_clock::from_time_t(0); - ExpectTime(time_point_cast<nanoseconds>(t0), utc, + ExpectTime(chrono::time_point_cast<chrono::nanoseconds>(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); - ExpectTime(time_point_cast<microseconds>(t0), utc, + ExpectTime(chrono::time_point_cast<chrono::microseconds>(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); - ExpectTime(time_point_cast<milliseconds>(t0), utc, + ExpectTime(chrono::time_point_cast<chrono::milliseconds>(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); - ExpectTime(time_point_cast<seconds>(t0), utc, + ExpectTime(chrono::time_point_cast<chrono::seconds>(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); - ExpectTime(time_point_cast<sys_seconds>(t0), utc, + ExpectTime(chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); - ExpectTime(time_point_cast<minutes>(t0), utc, + ExpectTime(chrono::time_point_cast<chrono::minutes>(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); - ExpectTime(time_point_cast<hours>(t0), utc, + ExpectTime(chrono::time_point_cast<chrono::hours>(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); } TEST(BreakTime, LocalTimeInUTC) { const time_zone tz = utc_time_zone(); - const auto tp = system_clock::from_time_t(0); + const auto tp = chrono::system_clock::from_time_t(0); ExpectTime(tp, tz, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimeInUTCUnaligned) { const time_zone tz = utc_time_zone(); - const auto tp = system_clock::from_time_t(0) - milliseconds(500); + const auto tp = + chrono::system_clock::from_time_t(0) - chrono::milliseconds(500); ExpectTime(tp, tz, 1969, 12, 31, 23, 59, 59, 0, false, "UTC"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } @@ -837,15 +848,16 @@ TEST(BreakTime, LocalTimeInUTCUnaligned) { TEST(BreakTime, LocalTimePosix) { // See IEEE Std 1003.1-1988 B.2.3 General Terms, Epoch. const time_zone tz = utc_time_zone(); - const auto tp = system_clock::from_time_t(536457599); + const auto tp = chrono::system_clock::from_time_t(536457599); ExpectTime(tp, tz, 1986, 12, 31, 23, 59, 59, 0, false, "UTC"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } TEST(TimeZoneImpl, LocalTimeInFixed) { - const sys_seconds offset = -(hours(8) + minutes(33) + seconds(47)); + const absl::time_internal::cctz::seconds offset = + -(chrono::hours(8) + chrono::minutes(33) + chrono::seconds(47)); const time_zone tz = fixed_time_zone(offset); - const auto tp = system_clock::from_time_t(0); + const auto tp = chrono::system_clock::from_time_t(0); ExpectTime(tp, tz, 1969, 12, 31, 15, 26, 13, offset.count(), false, "-083347"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); @@ -853,52 +865,52 @@ TEST(TimeZoneImpl, LocalTimeInFixed) { TEST(BreakTime, LocalTimeInNewYork) { const time_zone tz = LoadZone("America/New_York"); - const auto tp = system_clock::from_time_t(45); + const auto tp = chrono::system_clock::from_time_t(45); ExpectTime(tp, tz, 1969, 12, 31, 19, 0, 45, -5 * 60 * 60, false, "EST"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimeInMTV) { const time_zone tz = LoadZone("America/Los_Angeles"); - const auto tp = system_clock::from_time_t(1380855729); + const auto tp = chrono::system_clock::from_time_t(1380855729); ExpectTime(tp, tz, 2013, 10, 3, 20, 2, 9, -7 * 60 * 60, true, "PDT"); EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimeInSydney) { const time_zone tz = LoadZone("Australia/Sydney"); - const auto tp = system_clock::from_time_t(90); + const auto tp = chrono::system_clock::from_time_t(90); ExpectTime(tp, tz, 1970, 1, 1, 10, 1, 30, 10 * 60 * 60, false, "AEST"); EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); } TEST(MakeTime, TimePointResolution) { const time_zone utc = utc_time_zone(); - const time_point<nanoseconds> tp_ns = + const time_point<chrono::nanoseconds> tp_ns = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_ns, utc)); - const time_point<microseconds> tp_us = + const time_point<chrono::microseconds> tp_us = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_us, utc)); - const time_point<milliseconds> tp_ms = + const time_point<chrono::milliseconds> tp_ms = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_ms, utc)); - const time_point<seconds> tp_s = + const time_point<chrono::seconds> tp_s = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_s, utc)); - const time_point<sys_seconds> tp_s64 = + const time_point<absl::time_internal::cctz::seconds> tp_s64 = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_s64, utc)); - // These next two require time_point_cast because the conversion from a - // resolution of seconds (the return value of convert()) to a coarser - // resolution requires an explicit cast. - const time_point<minutes> tp_m = - time_point_cast<minutes>( + // These next two require chrono::time_point_cast because the conversion + // from a resolution of seconds (the return value of convert()) to a + // coarser resolution requires an explicit cast. + const time_point<chrono::minutes> tp_m = + chrono::time_point_cast<chrono::minutes>( convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); EXPECT_EQ("04:00", format("%M:%E*S", tp_m, utc)); - const time_point<hours> tp_h = - time_point_cast<hours>( + const time_point<chrono::hours> tp_h = + chrono::time_point_cast<chrono::hours>( convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); EXPECT_EQ("00:00", format("%M:%E*S", tp_h, utc)); } @@ -906,7 +918,7 @@ TEST(MakeTime, TimePointResolution) { TEST(MakeTime, Normalization) { const time_zone tz = LoadZone("America/New_York"); const auto tp = convert(civil_second(2009, 2, 13, 18, 31, 30), tz); - EXPECT_EQ(system_clock::from_time_t(1234567890), tp); + EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp); // Now requests for the same time_point but with out-of-range fields. EXPECT_EQ(tp, convert(civil_second(2008, 14, 13, 18, 31, 30), tz)); // month @@ -916,71 +928,234 @@ TEST(MakeTime, Normalization) { EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 18, 30, 90), tz)); // second } -// NOTE: Run this with --copt=-ftrapv to detect overflow problems. +// NOTE: Run this with -ftrapv to detect overflow problems. TEST(MakeTime, SysSecondsLimits) { const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez"; const time_zone utc = utc_time_zone(); - const time_zone east = fixed_time_zone(hours(14)); - const time_zone west = fixed_time_zone(-hours(14)); - time_point<sys_seconds> tp; + const time_zone east = fixed_time_zone(chrono::hours(14)); + const time_zone west = fixed_time_zone(-chrono::hours(14)); + time_point<absl::time_internal::cctz::seconds> tp; - // Approach the maximal time_point<sys_seconds> value from below. + // Approach the maximal time_point<cctz::seconds> value from below. tp = convert(civil_second(292277026596, 12, 4, 15, 30, 6), utc); EXPECT_EQ("292277026596-12-04T15:30:06+00:00", format(RFC3339, tp, utc)); tp = convert(civil_second(292277026596, 12, 4, 15, 30, 7), utc); EXPECT_EQ("292277026596-12-04T15:30:07+00:00", format(RFC3339, tp, utc)); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second(292277026596, 12, 4, 15, 30, 8), utc); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second::max(), utc); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); // Checks that we can also get the maximal value for a far-east zone. tp = convert(civil_second(292277026596, 12, 5, 5, 30, 7), east); EXPECT_EQ("292277026596-12-05T05:30:07+14:00", format(RFC3339, tp, east)); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second(292277026596, 12, 5, 5, 30, 8), east); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second::max(), east); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); // Checks that we can also get the maximal value for a far-west zone. tp = convert(civil_second(292277026596, 12, 4, 1, 30, 7), west); EXPECT_EQ("292277026596-12-04T01:30:07-14:00", format(RFC3339, tp, west)); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second(292277026596, 12, 4, 7, 30, 8), west); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second::max(), west); - EXPECT_EQ(time_point<sys_seconds>::max(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); - // Approach the minimal time_point<sys_seconds> value from above. + // Approach the minimal time_point<cctz::seconds> value from above. tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 53), utc); EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", format(RFC3339, tp, utc)); tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 52), utc); EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", format(RFC3339, tp, utc)); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 51), utc); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second::min(), utc); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); // Checks that we can also get the minimal value for a far-east zone. tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 52), east); EXPECT_EQ("-292277022657-01-27T22:29:52+14:00", format(RFC3339, tp, east)); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 51), east); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second::min(), east); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); // Checks that we can also get the minimal value for a far-west zone. tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 52), west); EXPECT_EQ("-292277022657-01-26T18:29:52-14:00", format(RFC3339, tp, west)); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 51), west); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second::min(), west); - EXPECT_EQ(time_point<sys_seconds>::min(), tp); + EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); + + // Some similar checks for the "libc" time-zone implementation. + if (sizeof(std::time_t) >= 8) { + // Checks that "tm_year + 1900", as used by the "libc" implementation, + // can produce year values beyond the range on an int without overflow. +#if defined(_WIN32) || defined(_WIN64) + // localtime_s() and gmtime_s() don't believe in years outside [1970:3000]. +#else + const time_zone utc = LoadZone("libc:UTC"); + const year_t max_tm_year = year_t{std::numeric_limits<int>::max()} + 1900; + tp = convert(civil_second(max_tm_year, 12, 31, 23, 59, 59), utc); + EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, utc)); + const year_t min_tm_year = year_t{std::numeric_limits<int>::min()} + 1900; + tp = convert(civil_second(min_tm_year, 1, 1, 0, 0, 0), utc); + EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, utc)); +#endif + } +} + +TEST(MakeTime, LocalTimeLibC) { + // Checks that cctz and libc agree on transition points in [1970:2037]. + // + // We limit this test case to environments where: + // 1) we know how to change the time zone used by localtime()/mktime(), + // 2) cctz and localtime()/mktime() will use similar-enough tzdata, and + // 3) we have some idea about how mktime() behaves during transitions. +#if defined(__linux__) + const char* const ep = getenv("TZ"); + std::string tz_name = (ep != nullptr) ? ep : ""; + for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { + ASSERT_EQ(0, setenv("TZ", *np, 1)); // change what "localtime" means + const auto zi = local_time_zone(); + const auto lc = LoadZone("libc:localtime"); + time_zone::civil_transition trans; + for (auto tp = zi.lookup(civil_second()).trans; + zi.next_transition(tp, &trans); + tp = zi.lookup(trans.to).trans) { + const auto fcl = zi.lookup(trans.from); + const auto tcl = zi.lookup(trans.to); + civil_second cs; // compare cs in zi and lc + if (fcl.kind == time_zone::civil_lookup::UNIQUE) { + if (tcl.kind == time_zone::civil_lookup::UNIQUE) { + // Both unique; must be an is_dst or abbr change. + ASSERT_EQ(trans.from, trans.to); + const auto trans = fcl.trans; + const auto tal = zi.lookup(trans); + const auto tprev = trans - absl::time_internal::cctz::seconds(1); + const auto pal = zi.lookup(tprev); + if (pal.is_dst == tal.is_dst) { + ASSERT_STRNE(pal.abbr, tal.abbr); + } + continue; + } + ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind); + cs = trans.to; + } else { + ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind); + ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind); + cs = trans.from; + } + if (cs.year() > 2037) break; // limit test time (and to 32-bit time_t) + const auto cl_zi = zi.lookup(cs); + if (zi.lookup(cl_zi.pre).is_dst == zi.lookup(cl_zi.post).is_dst) { + // The "libc" implementation cannot correctly classify transitions + // that don't change the "tm_isdst" flag. In Europe/Volgograd, for + // example, there is a SKIPPED transition from +03 to +04 with dst=F + // on both sides ... + // 1540681199 = 2018-10-28 01:59:59 +03:00:00 [dst=F off=10800] + // 1540681200 = 2018-10-28 03:00:00 +04:00:00 [dst=F off=14400] + // but std::mktime(2018-10-28 02:00:00, tm_isdst=0) fails, unlike, + // say, the similar Europe/Chisinau transition from +02 to +03 ... + // 1521935999 = 2018-03-25 01:59:59 +02:00:00 [dst=F off=7200] + // 1521936000 = 2018-03-25 03:00:00 +03:00:00 [dst=T off=10800] + // where std::mktime(2018-03-25 02:00:00, tm_isdst=0) succeeds and + // returns 1521936000. + continue; + } + if (cs == civil_second(2037, 10, 4, 2, 0, 0)) { + const std::string tzname = *np; + if (tzname == "Africa/Casablanca" || tzname == "Africa/El_Aaiun") { + // The "libc" implementation gets this transition wrong (at least + // until 2018g when it was removed), returning an offset of 3600 + // instead of 0. TODO: Revert this when 2018g is ubiquitous. + continue; + } + } + const auto cl_lc = lc.lookup(cs); + SCOPED_TRACE(testing::Message() << "For " << cs << " in " << *np); + EXPECT_EQ(cl_zi.kind, cl_lc.kind); + EXPECT_EQ(cl_zi.pre, cl_lc.pre); + EXPECT_EQ(cl_zi.trans, cl_lc.trans); + EXPECT_EQ(cl_zi.post, cl_lc.post); + } + } + if (ep == nullptr) { + ASSERT_EQ(0, unsetenv("TZ")); + } else { + ASSERT_EQ(0, setenv("TZ", tz_name.c_str(), 1)); + } +#endif +} + +TEST(NextTransition, UTC) { + const auto tz = utc_time_zone(); + time_zone::civil_transition trans; + + auto tp = time_point<absl::time_internal::cctz::seconds>::min(); + EXPECT_FALSE(tz.next_transition(tp, &trans)); + + tp = time_point<absl::time_internal::cctz::seconds>::max(); + EXPECT_FALSE(tz.next_transition(tp, &trans)); +} + +TEST(PrevTransition, UTC) { + const auto tz = utc_time_zone(); + time_zone::civil_transition trans; + + auto tp = time_point<absl::time_internal::cctz::seconds>::max(); + EXPECT_FALSE(tz.prev_transition(tp, &trans)); + + tp = time_point<absl::time_internal::cctz::seconds>::min(); + EXPECT_FALSE(tz.prev_transition(tp, &trans)); +} + +TEST(NextTransition, AmericaNewYork) { + const auto tz = LoadZone("America/New_York"); + time_zone::civil_transition trans; + + auto tp = convert(civil_second(2018, 6, 30, 0, 0, 0), tz); + EXPECT_TRUE(tz.next_transition(tp, &trans)); + EXPECT_EQ(civil_second(2018, 11, 4, 2, 0, 0), trans.from); + EXPECT_EQ(civil_second(2018, 11, 4, 1, 0, 0), trans.to); + + tp = time_point<absl::time_internal::cctz::seconds>::max(); + EXPECT_FALSE(tz.next_transition(tp, &trans)); + + tp = time_point<absl::time_internal::cctz::seconds>::min(); + EXPECT_TRUE(tz.next_transition(tp, &trans)); + if (trans.from == civil_second(1918, 3, 31, 2, 0, 0)) { + // It looks like the tzdata is only 32 bit (probably macOS), + // which bottoms out at 1901-12-13T20:45:52+00:00. + EXPECT_EQ(civil_second(1918, 3, 31, 3, 0, 0), trans.to); + } else { + EXPECT_EQ(civil_second(1883, 11, 18, 12, 3, 58), trans.from); + EXPECT_EQ(civil_second(1883, 11, 18, 12, 0, 0), trans.to); + } +} + +TEST(PrevTransition, AmericaNewYork) { + const auto tz = LoadZone("America/New_York"); + time_zone::civil_transition trans; + + auto tp = convert(civil_second(2018, 6, 30, 0, 0, 0), tz); + EXPECT_TRUE(tz.prev_transition(tp, &trans)); + EXPECT_EQ(civil_second(2018, 3, 11, 2, 0, 0), trans.from); + EXPECT_EQ(civil_second(2018, 3, 11, 3, 0, 0), trans.to); + + tp = time_point<absl::time_internal::cctz::seconds>::min(); + EXPECT_FALSE(tz.prev_transition(tp, &trans)); + + tp = time_point<absl::time_internal::cctz::seconds>::max(); + EXPECT_TRUE(tz.prev_transition(tp, &trans)); + // We have a transition but we don't know which one. } TEST(TimeZoneEdgeCase, AmericaNewYork) { @@ -989,13 +1164,13 @@ TEST(TimeZoneEdgeCase, AmericaNewYork) { // Spring 1:59:59 -> 3:00:00 auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -5 * 3600, false, "EST"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -4 * 3600, true, "EDT"); // Fall 1:59:59 -> 1:00:00 tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -4 * 3600, true, "EDT"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -5 * 3600, false, "EST"); } @@ -1005,13 +1180,13 @@ TEST(TimeZoneEdgeCase, AmericaLosAngeles) { // Spring 1:59:59 -> 3:00:00 auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -8 * 3600, false, "PST"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -7 * 3600, true, "PDT"); // Fall 1:59:59 -> 1:00:00 tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, true, "PDT"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -8 * 3600, false, "PST"); } @@ -1021,13 +1196,13 @@ TEST(TimeZoneEdgeCase, ArizonaNoTransition) { // No transition in Spring. auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -7 * 3600, false, "MST"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 3, 10, 2, 0, 0, -7 * 3600, false, "MST"); // No transition in Fall. tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, false, "MST"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 11, 3, 2, 0, 0, -7 * 3600, false, "MST"); } @@ -1040,7 +1215,7 @@ TEST(TimeZoneEdgeCase, AsiaKathmandu) { // 504901800 == Wed, 1 Jan 1986 00:15:00 +0545 (+0545) auto tp = convert(civil_second(1985, 12, 31, 23, 59, 59), tz); ExpectTime(tp, tz, 1985, 12, 31, 23, 59, 59, 5.5 * 3600, false, "+0530"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 1986, 1, 1, 0, 15, 0, 5.75 * 3600, false, "+0545"); } @@ -1053,14 +1228,14 @@ TEST(TimeZoneEdgeCase, PacificChatham) { // 1365256800 == Sun, 7 Apr 2013 02:45:00 +1245 (+1245) auto tp = convert(civil_second(2013, 4, 7, 3, 44, 59), tz); ExpectTime(tp, tz, 2013, 4, 7, 3, 44, 59, 13.75 * 3600, true, "+1345"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 4, 7, 2, 45, 0, 12.75 * 3600, false, "+1245"); // 1380376799 == Sun, 29 Sep 2013 02:44:59 +1245 (+1245) // 1380376800 == Sun, 29 Sep 2013 03:45:00 +1345 (+1345) tp = convert(civil_second(2013, 9, 29, 2, 44, 59), tz); ExpectTime(tp, tz, 2013, 9, 29, 2, 44, 59, 12.75 * 3600, false, "+1245"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 9, 29, 3, 45, 0, 13.75 * 3600, true, "+1345"); } @@ -1073,14 +1248,14 @@ TEST(TimeZoneEdgeCase, AustraliaLordHowe) { // 1365260400 == Sun, 7 Apr 2013 01:30:00 +1030 (+1030) auto tp = convert(civil_second(2013, 4, 7, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 4, 7, 1, 59, 59, 11 * 3600, true, "+11"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 4, 7, 1, 30, 0, 10.5 * 3600, false, "+1030"); // 1380986999 == Sun, 6 Oct 2013 01:59:59 +1030 (+1030) // 1380987000 == Sun, 6 Oct 2013 02:30:00 +1100 (+11) tp = convert(civil_second(2013, 10, 6, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 10, 6, 1, 59, 59, 10.5 * 3600, false, "+1030"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2013, 10, 6, 2, 30, 0, 11 * 3600, true, "+11"); } @@ -1098,7 +1273,7 @@ TEST(TimeZoneEdgeCase, PacificApia) { auto tp = convert(civil_second(2011, 12, 29, 23, 59, 59), tz); ExpectTime(tp, tz, 2011, 12, 29, 23, 59, 59, -10 * 3600, true, "-10"); EXPECT_EQ(363, get_yearday(civil_day(convert(tp, tz)))); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2011, 12, 31, 0, 0, 0, 14 * 3600, true, "+14"); EXPECT_EQ(365, get_yearday(civil_day(convert(tp, tz)))); } @@ -1106,35 +1281,31 @@ TEST(TimeZoneEdgeCase, PacificApia) { TEST(TimeZoneEdgeCase, AfricaCairo) { const time_zone tz = LoadZone("Africa/Cairo"); -#if defined(__ANDROID__) && __ANDROID_API__ < 21 - // Only Android 'L' and beyond have this tz2014c transition. -#else - // An interesting case of midnight not existing. - // - // 1400191199 == Thu, 15 May 2014 23:59:59 +0200 (EET) - // 1400191200 == Fri, 16 May 2014 01:00:00 +0300 (EEST) - auto tp = convert(civil_second(2014, 5, 15, 23, 59, 59), tz); - ExpectTime(tp, tz, 2014, 5, 15, 23, 59, 59, 2 * 3600, false, "EET"); - tp += seconds(1); - ExpectTime(tp, tz, 2014, 5, 16, 1, 0, 0, 3 * 3600, true, "EEST"); -#endif + if (VersionCmp(tz, "2014c") >= 0) { + // An interesting case of midnight not existing. + // + // 1400191199 == Thu, 15 May 2014 23:59:59 +0200 (EET) + // 1400191200 == Fri, 16 May 2014 01:00:00 +0300 (EEST) + auto tp = convert(civil_second(2014, 5, 15, 23, 59, 59), tz); + ExpectTime(tp, tz, 2014, 5, 15, 23, 59, 59, 2 * 3600, false, "EET"); + tp += absl::time_internal::cctz::seconds(1); + ExpectTime(tp, tz, 2014, 5, 16, 1, 0, 0, 3 * 3600, true, "EEST"); + } } TEST(TimeZoneEdgeCase, AfricaMonrovia) { const time_zone tz = LoadZone("Africa/Monrovia"); -#if defined(__ANDROID__) && __ANDROID_API__ < 26 - // Only Android 'O' and beyond have this tz2017b transition. -#else - // Strange offset change -00:44:30 -> +00:00:00 (non-DST) - // - // 63593069 == Thu, 6 Jan 1972 23:59:59 -0044 (MMT) - // 63593070 == Fri, 7 Jan 1972 00:44:30 +0000 (GMT) - auto tp = convert(civil_second(1972, 1, 6, 23, 59, 59), tz); - ExpectTime(tp, tz, 1972, 1, 6, 23, 59, 59, -44.5 * 60, false, "MMT"); - tp += seconds(1); - ExpectTime(tp, tz, 1972, 1, 7, 0, 44, 30, 0 * 60, false, "GMT"); -#endif + if (VersionCmp(tz, "2017b") >= 0) { + // Strange offset change -00:44:30 -> +00:00:00 (non-DST) + // + // 63593069 == Thu, 6 Jan 1972 23:59:59 -0044 (MMT) + // 63593070 == Fri, 7 Jan 1972 00:44:30 +0000 (GMT) + auto tp = convert(civil_second(1972, 1, 6, 23, 59, 59), tz); + ExpectTime(tp, tz, 1972, 1, 6, 23, 59, 59, -44.5 * 60, false, "MMT"); + tp += absl::time_internal::cctz::seconds(1); + ExpectTime(tp, tz, 1972, 1, 7, 0, 44, 30, 0 * 60, false, "GMT"); + } } TEST(TimeZoneEdgeCase, AmericaJamaica) { @@ -1146,30 +1317,31 @@ TEST(TimeZoneEdgeCase, AmericaJamaica) { const time_zone tz = LoadZone("America/Jamaica"); // Before the first transition. - auto tp = convert(civil_second(1889, 12, 31, 0, 0, 0), tz); -#if AMERICA_JAMAICA_PRE_1913_OFFSET_FIX - // Commit 907241e: Fix off-by-1 error for Jamaica and T&C before 1913. - // Until that commit has made its way into a full release we avoid the - // expectations on the -18430 offset below. TODO: Uncomment these. - ExpectTime(tp, tz, 1889, 12, 31, 0, 0, 0, -18430, false, - tz.lookup(tp).abbr); - - // Over the first (abbreviation-change only) transition. - // -2524503170 == Tue, 31 Dec 1889 23:59:59 -0507 (LMT) - // -2524503169 == Wed, 1 Jan 1890 00:00:00 -0507 (KMT) - tp = convert(civil_second(1889, 12, 31, 23, 59, 59), tz); - ExpectTime(tp, tz, 1889, 12, 31, 23, 59, 59, -18430, false, - tz.lookup(tp).abbr); - tp += seconds(1); - ExpectTime(tp, tz, 1890, 1, 1, 0, 0, 0, -18430, false, "KMT"); -#endif + if (!tz.version().empty() && VersionCmp(tz, "2018d") >= 0) { + // We avoid the expectations on the -18430 offset below unless we are + // certain we have commit 907241e (Fix off-by-1 error for Jamaica and + // T&C before 1913) from 2018d. TODO: Remove the "version() not empty" + // part when 2018d is generally available from /usr/share/zoneinfo. + auto tp = convert(civil_second(1889, 12, 31, 0, 0, 0), tz); + ExpectTime(tp, tz, 1889, 12, 31, 0, 0, 0, -18430, false, + tz.lookup(tp).abbr); + + // Over the first (abbreviation-change only) transition. + // -2524503170 == Tue, 31 Dec 1889 23:59:59 -0507 (LMT) + // -2524503169 == Wed, 1 Jan 1890 00:00:00 -0507 (KMT) + tp = convert(civil_second(1889, 12, 31, 23, 59, 59), tz); + ExpectTime(tp, tz, 1889, 12, 31, 23, 59, 59, -18430, false, + tz.lookup(tp).abbr); + tp += absl::time_internal::cctz::seconds(1); + ExpectTime(tp, tz, 1890, 1, 1, 0, 0, 0, -18430, false, "KMT"); + } // Over the last (DST) transition. // 436341599 == Sun, 30 Oct 1983 01:59:59 -0400 (EDT) // 436341600 == Sun, 30 Oct 1983 01:00:00 -0500 (EST) - tp = convert(civil_second(1983, 10, 30, 1, 59, 59), tz); + auto tp = convert(civil_second(1983, 10, 30, 1, 59, 59), tz); ExpectTime(tp, tz, 1983, 10, 30, 1, 59, 59, -4 * 3600, true, "EDT"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 1983, 10, 30, 1, 0, 0, -5 * 3600, false, "EST"); // After the last transition. @@ -1190,7 +1362,7 @@ TEST(TimeZoneEdgeCase, WET) { // 228877200 == Sun, 3 Apr 1977 02:00:00 +0100 (WEST) tp = convert(civil_second(1977, 4, 3, 0, 59, 59), tz); ExpectTime(tp, tz, 1977, 4, 3, 0, 59, 59, 0, false, "WET"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 1977, 4, 3, 2, 0, 0, 1 * 3600, true, "WEST"); // A non-existent time within the first transition. @@ -1212,12 +1384,12 @@ TEST(TimeZoneEdgeCase, FixedOffsets) { const time_zone gmtm5 = LoadZone("Etc/GMT+5"); // -0500 auto tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtm5); ExpectTime(tp, gmtm5, 1970, 1, 1, 0, 0, 0, -5 * 3600, false, "-05"); - EXPECT_EQ(system_clock::from_time_t(5 * 3600), tp); + EXPECT_EQ(chrono::system_clock::from_time_t(5 * 3600), tp); const time_zone gmtp5 = LoadZone("Etc/GMT-5"); // +0500 tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtp5); ExpectTime(tp, gmtp5, 1970, 1, 1, 0, 0, 0, 5 * 3600, false, "+05"); - EXPECT_EQ(system_clock::from_time_t(-5 * 3600), tp); + EXPECT_EQ(chrono::system_clock::from_time_t(-5 * 3600), tp); } TEST(TimeZoneEdgeCase, NegativeYear) { @@ -1226,7 +1398,7 @@ TEST(TimeZoneEdgeCase, NegativeYear) { auto tp = convert(civil_second(0, 1, 1, 0, 0, 0), tz); ExpectTime(tp, tz, 0, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC"); EXPECT_EQ(weekday::saturday, get_weekday(civil_day(convert(tp, tz)))); - tp -= seconds(1); + tp -= absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, -1, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC"); EXPECT_EQ(weekday::friday, get_weekday(civil_day(convert(tp, tz)))); } @@ -1240,7 +1412,7 @@ TEST(TimeZoneEdgeCase, UTC32bitLimit) { // 2147483648 == Tue, 19 Jan 2038 03:14:08 +0000 (UTC) auto tp = convert(civil_second(2038, 1, 19, 3, 14, 7), tz); ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 7, 0 * 3600, false, "UTC"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 8, 0 * 3600, false, "UTC"); } @@ -1253,11 +1425,11 @@ TEST(TimeZoneEdgeCase, UTC5DigitYear) { // 253402300800 == Sat, 1 Jan 1000 00:00:00 +0000 (UTC) auto tp = convert(civil_second(9999, 12, 31, 23, 59, 59), tz); ExpectTime(tp, tz, 9999, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC"); - tp += seconds(1); + tp += absl::time_internal::cctz::seconds(1); ExpectTime(tp, tz, 10000, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC"); } } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_posix.cc b/absl/time/internal/cctz/src/time_zone_posix.cc index b6cf2875..960133d7 100644 --- a/absl/time/internal/cctz/src/time_zone_posix.cc +++ b/absl/time/internal/cctz/src/time_zone_posix.cc @@ -20,7 +20,7 @@ #include <string> namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -153,5 +153,5 @@ bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res) { } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/src/time_zone_posix.h b/absl/time/internal/cctz/src/time_zone_posix.h index 91443a21..84c39afb 100644 --- a/absl/time/internal/cctz/src/time_zone_posix.h +++ b/absl/time/internal/cctz/src/time_zone_posix.h @@ -56,7 +56,7 @@ #include <string> namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz { @@ -69,28 +69,38 @@ namespace cctz { // it would take us to another day, and perhaps week, or even month. struct PosixTransition { enum DateFormat { J, N, M }; - struct { + + 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 { - struct { - std::int_fast16_t day; // day of non-leap year [1:365] - } j; - struct { - std::int_fast16_t day; // day of year [0:365] - } n; - struct { - 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 - } m; + NonLeapDay j; + Day n; + MonthWeekWeekday m; }; - } date; - struct { + }; + + struct Time { std::int_fast32_t offset; // seconds before/after 00:00:00 - } time; + }; + + Date date; + Time time; }; -// The entirety of a POSIX-std::string specified time-zone rule. The standard +// The entirety of a POSIX-string specified time-zone rule. The standard // abbreviation and offset are always given. If the time zone includes // daylight saving, then the daylight abbrevation is non-empty and the // remaining fields are also valid. Note that the start/end transitions @@ -114,7 +124,7 @@ bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res); } // namespace cctz } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_ diff --git a/absl/time/internal/cctz/src/tzfile.h b/absl/time/internal/cctz/src/tzfile.h index 90cfc0c4..4485ba55 100644 --- a/absl/time/internal/cctz/src/tzfile.h +++ b/absl/time/internal/cctz/src/tzfile.h @@ -1,3 +1,5 @@ +/* Layout and location of TZif files. */ + #ifndef TZFILE_H #define TZFILE_H diff --git a/absl/time/internal/cctz/src/zone_info_source.cc b/absl/time/internal/cctz/src/zone_info_source.cc index a73e1c92..61669e7a 100644 --- a/absl/time/internal/cctz/src/zone_info_source.cc +++ b/absl/time/internal/cctz/src/zone_info_source.cc @@ -15,20 +15,21 @@ #include "absl/time/internal/cctz/include/cctz/zone_info_source.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { 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 time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz_extension { @@ -55,20 +56,28 @@ ZoneInfoSourceFactory default_factory = DefaultFactory; #if defined(_M_IX86) #pragma comment( \ linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@lts_2018_06_20@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZA=?default_factory@cctz_extension@time_internal@lts_2018_06_20@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZA") + "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@lts_2018_12_18@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZA=?default_factory@cctz_extension@time_internal@lts_2018_12_18@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZA") #elif defined(_M_IA_64) || defined(_M_AMD64) #pragma comment( \ linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@lts_2018_06_20@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZEA=?default_factory@cctz_extension@time_internal@lts_2018_06_20@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_06_20@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZEA") + "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@lts_2018_12_18@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZEA=?default_factory@cctz_extension@time_internal@lts_2018_12_18@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@6@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@lts_2018_12_18@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@6@@ZEA") #else #error Unsupported MSVC platform #endif -#else +#else // _MSC_VER +#if !defined(__has_attribute) +#define __has_attribute(x) 0 +#endif +#if __has_attribute(weak) || defined(__GNUC__) ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) = DefaultFactory; +#else +// Make it a "strong" definition if we have no other choice. +ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory; +#endif #endif // _MSC_VER } // namespace cctz_extension } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/cctz/testdata/version b/absl/time/internal/cctz/testdata/version index fe86b5cc..ac954d74 100644 --- a/absl/time/internal/cctz/testdata/version +++ b/absl/time/internal/cctz/testdata/version @@ -1 +1 @@ -2018e-2-g99dd695 +2018g-9-gf0d2759 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Abidjan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra Binary files differindex 8726e80d..eaaa818f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Addis_Ababa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers Binary files differindex 2a25f3ac..a5867a67 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Algiers diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmara diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Asmera diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bamako diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bangui diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Banjul diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau Binary files differindex 8e32be3e..82ea5aaf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bissau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Blantyre diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Brazzaville diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Bujumbura diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo Binary files differindex ba097504..0272fa1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Cairo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca Binary files differindex 65de3445..4c570548 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta Binary files differindex aaa657ff..dd75e3e6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ceuta diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Conakry diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dakar diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Dar_es_Salaam diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Djibouti diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Douala diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun b/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun Binary files differindex f5f8ffbc..0ea02535 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Freetown diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Gaborone diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Harare diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg Binary files differindex ddf3652e..b8b9270a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Johannesburg diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba Binary files differindex 9fa71190..83eca03a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kampala diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum Binary files differindex f2c9e303..549dae27 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Khartoum diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kigali diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Kinshasa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lagos diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Libreville diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lome diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Luanda diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lubumbashi diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Lusaka diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Malabo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo Binary files differindex 5b871dba..31cfad77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maputo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru Binary files differindex ddf3652e..b8b9270a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Maseru diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane Binary files differindex ddf3652e..b8b9270a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mbabane diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Mogadishu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia Binary files differindex b434c67f..2a154f46 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Monrovia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nairobi diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena Binary files differindex bbfe19d6..8779590e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ndjamena diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Niamey diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Nouakchott diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Ouagadougou diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo Binary files differindex b1c97cc5..cbdc0450 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Porto-Novo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome Binary files differindex a4ece7ff..d2a64bd1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Timbuktu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli Binary files differindex b32e2202..bd885315 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tripoli diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis Binary files differindex 4bd3885a..0cd8ffba 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Tunis diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek Binary files differindex f5d40baf..67661856 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Windhoek diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Adak b/absl/time/internal/cctz/testdata/zoneinfo/America/Adak Binary files differindex 5696e0f8..43236498 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Adak +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Adak diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage b/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage Binary files differindex 6c8bdf22..9bbb2fd3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Anchorage diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina b/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina Binary files differindex 8b295a98..bc9a5228 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Araguaina diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires Binary files differindex e4866ce1..dfebfb99 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Buenos_Aires diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca Binary files differindex 9fe9ad64..b798105e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Catamarca diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia Binary files differindex 9fe9ad64..b798105e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/ComodRivadavia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba Binary files differindex 8c58f8c2..5df3cf6e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Cordoba diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy Binary files differindex a74ba046..7d2ba91c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Jujuy diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja Binary files differindex cb184d6a..7654aebf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/La_Rioja diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza Binary files differindex 5e8c44c8..10323564 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Mendoza diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos Binary files differindex 966a529b..3c849fce 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Rio_Gallegos diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta Binary files differindex b19aa222..a4b71c1f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Salta diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan Binary files differindex 9e5ade61..948a3901 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Juan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis Binary files differindex af8aa998..acfbbe43 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/San_Luis diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman Binary files differindex bbb03a0c..085fc9cc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Tucuman diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia Binary files differindex 07e4e9f0..1fc32567 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Argentina/Ushuaia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba Binary files differindex d308336b..d3b318d2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion b/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion Binary files differindex 3c61ddb5..831bf843 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Asuncion diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan Binary files differindex 5708b55a..629ed423 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Atka b/absl/time/internal/cctz/testdata/zoneinfo/America/Atka Binary files differindex 5696e0f8..43236498 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Atka +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Atka diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia Binary files differindex 6008a574..143eafc2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas Binary files differindex 21e2b719..cd531078 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Bahia_Banderas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados Binary files differindex 63399360..7bb7ac4d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Belem b/absl/time/internal/cctz/testdata/zoneinfo/America/Belem Binary files differindex b8e13b02..ab3c8a67 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Belem +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Belem diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Belize b/absl/time/internal/cctz/testdata/zoneinfo/America/Belize Binary files differindex 7dcc4fc5..fd693214 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Belize +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Belize diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon Binary files differindex abcde7d9..f9f13a16 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista b/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista Binary files differindex f7769048..69e17a00 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Boa_Vista diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota b/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota Binary files differindex d8934466..b7ded8e6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Bogota diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Boise b/absl/time/internal/cctz/testdata/zoneinfo/America/Boise Binary files differindex ada6d64b..f8d54e27 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Boise +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Boise diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires b/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires Binary files differindex e4866ce1..dfebfb99 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Buenos_Aires diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay Binary files differindex d322f01e..f8db4b6e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cambridge_Bay diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande b/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande Binary files differindex de52bb68..495ef456 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Campo_Grande diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun b/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun Binary files differindex 7e69f73d..de6930cd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cancun diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas b/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas Binary files differindex c8cab1af..9abd028f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Caracas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca b/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca Binary files differindex 9fe9ad64..b798105e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Catamarca diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne Binary files differindex 6db64098..ff596578 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayenne diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman Binary files differindex 5c1c0637..55b08346 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cayman diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago b/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago Binary files differindex 3dd8f0fa..a5b1617c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Chicago diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua b/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua Binary files differindex e3adbdbf..b2687241 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Chihuahua diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour Binary files differindex 5708b55a..629ed423 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba b/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba Binary files differindex 8c58f8c2..5df3cf6e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cordoba diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica b/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica Binary files differindex c247133e..525a67ea 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Costa_Rica diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston Binary files differindex 798f627a..0fba7417 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba b/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba Binary files differindex 145c89e0..8a4ee7d0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Cuiaba diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao Binary files differindex d308336b..d3b318d2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn b/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn Binary files differindex ad68c722..9549adcb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Danmarkshavn diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson Binary files differindex 61c96889..db9ceadd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek Binary files differindex 78f90763..db9e3396 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dawson_Creek diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Denver b/absl/time/internal/cctz/testdata/zoneinfo/America/Denver Binary files differindex 7fc66917..5fbe26b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Denver +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Denver diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit b/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit Binary files differindex e3ea5c3e..5e022605 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Detroit diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton b/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton Binary files differindex d02fbcd4..3fa05798 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe b/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe Binary files differindex 41047f29..99b7d06e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Eirunepe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador b/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador Binary files differindex 9b8bc7a8..ac774e83 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/El_Salvador diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada b/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada Binary files differindex 29c83e71..ada6bf78 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Ensenada diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson Binary files differindex 5923cc68..5a0b7f1c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Nelson diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne Binary files differindex 4a92c065..09511ccd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Fort_Wayne diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza b/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza Binary files differindex 22396bb5..e637170a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Fortaleza diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay Binary files differindex f58522b6..48412a4c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Glace_Bay diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab b/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab Binary files differindex ea293cc4..0160308b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Godthab diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay Binary files differindex b4b945e8..a3f29907 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Goose_Bay diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk b/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk Binary files differindex 4c8ca6f7..4597a621 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Grand_Turk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala b/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala Binary files differindex abf943be..6118b5ce 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guatemala diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil b/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil Binary files differindex 92de38be..bf087a0e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guayaquil diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana Binary files differindex 7d298767..d1dd2faf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax b/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax Binary files differindex f86ece4c..756099ab 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Halifax diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Havana b/absl/time/internal/cctz/testdata/zoneinfo/America/Havana Binary files differindex 1a58fcdc..8186060a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Havana +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Havana diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo b/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo Binary files differindex ec435c23..26c269d9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Hermosillo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis Binary files differindex 4a92c065..09511ccd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Indianapolis diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox Binary files differindex cc785da9..fcd408d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Knox diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo Binary files differindex a23d7b75..1abf75e7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Marengo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg Binary files differindex f16cb304..0133548e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Petersburg diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City Binary files differindex 0250bf90..4ce95c15 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Tell_City diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay Binary files differindex e934de61..d236b7c0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vevay diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes Binary files differindex adbdbeee..c818929d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Vincennes diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac Binary files differindex b34f7b27..630935c1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indiana/Winamac diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis b/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis Binary files differindex 4a92c065..09511ccd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Indianapolis diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik b/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik Binary files differindex 1388e8a4..e107dc44 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Inuvik diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit b/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit Binary files differindex 0785ac57..c8138bdb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Iqaluit diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica b/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica Binary files differindex 7aedd262..162306f8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Jamaica diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy b/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy Binary files differindex a74ba046..7d2ba91c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Jujuy diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau b/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau Binary files differindex d00668ad..451f3490 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Juneau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville Binary files differindex fdf2e88b..f4c4cf96 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Louisville diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello Binary files differindex 60991aa3..438e3eab 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kentucky/Monticello diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN b/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN Binary files differindex cc785da9..fcd408d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Knox_IN diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk Binary files differindex d308336b..d3b318d2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz b/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz Binary files differindex bc3df523..5e5fec56 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/La_Paz diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Lima b/absl/time/internal/cctz/testdata/zoneinfo/America/Lima Binary files differindex 44280a5c..d9fec371 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Lima +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Lima diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles b/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles Binary files differindex c0ce4402..9dad4f4c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Los_Angeles diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville b/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville Binary files differindex fdf2e88b..f4c4cf96 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Louisville diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes Binary files differindex d308336b..d3b318d2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio b/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio Binary files differindex 54442dc7..fec8a8bf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Maceio diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Managua b/absl/time/internal/cctz/testdata/zoneinfo/America/Managua Binary files differindex c543ffd4..69256c63 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Managua +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Managua diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus b/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus Binary files differindex 855cb02c..b10241e6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Manaus diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique b/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique Binary files differindex f9e2399c..79716de5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Martinique diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros b/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros Binary files differindex 5671d258..5c59984d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Matamoros diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan b/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan Binary files differindex afa94c2a..43ee12d8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Mazatlan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza b/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza Binary files differindex 5e8c44c8..10323564 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Mendoza diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee b/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee Binary files differindex 55d6e326..31461386 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Menominee diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Merida b/absl/time/internal/cctz/testdata/zoneinfo/America/Merida Binary files differindex ecc1856e..b46298e1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Merida +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Merida diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla Binary files differindex c0335970..26356078 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City b/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City Binary files differindex f11e3d2d..1434ab08 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Mexico_City diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon b/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon Binary files differindex 75bbcf2b..06ceaadf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Miquelon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton b/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton Binary files differindex 51cb1ba3..9df8d0f2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Moncton diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey b/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey Binary files differindex dcac92ba..7dc50577 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Monterrey diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo b/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo Binary files differindex f524fd21..0d1e565c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montevideo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal b/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal Binary files differindex 7b4682a3..6752c5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montreal diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau Binary files differindex e5d0289b..5091eb5d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/New_York b/absl/time/internal/cctz/testdata/zoneinfo/America/New_York Binary files differindex 7553fee3..2f75480e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/New_York +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/New_York diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon b/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon Binary files differindex f8a0292b..f6a856e6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nipigon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nome b/absl/time/internal/cctz/testdata/zoneinfo/America/Nome Binary files differindex c886c9bc..10998df3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nome +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nome diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha b/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha Binary files differindex 6d91f914..95ff8a25 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Noronha diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah Binary files differindex 8174c882..246345dd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Beulah diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center Binary files differindex 8035b24f..1fa07037 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/Center diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem Binary files differindex 5b630ee6..123f2aee 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/North_Dakota/New_Salem diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga b/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga Binary files differindex 190c5c86..37d78301 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Ojinaga diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Panama b/absl/time/internal/cctz/testdata/zoneinfo/America/Panama Binary files differindex 5c1c0637..55b08346 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Panama +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Panama diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung b/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung Binary files differindex df78b626..3e4e0db6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Pangnirtung diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo b/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo Binary files differindex 1b608b3e..b95c7842 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Paramaribo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix b/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix Binary files differindex adf28236..4d51271a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Phoenix diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince b/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince Binary files differindex 7306caef..d9590103 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Port-au-Prince diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain b/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre Binary files differindex b612ac23..16b7f923 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Acre diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho Binary files differindex 2423fc19..10cb02b8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Porto_Velho diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico b/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico Binary files differindex d4525a68..a662a571 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Puerto_Rico diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas Binary files differindex 4d84eed4..a5a8af52 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River b/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River Binary files differindex 70dcd2d8..ea660991 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rainy_River diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet b/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet Binary files differindex 9f50f36e..61ff6fcb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rankin_Inlet diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Recife b/absl/time/internal/cctz/testdata/zoneinfo/America/Recife Binary files differindex fe55739d..c6d99b3a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Recife +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Recife diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Regina b/absl/time/internal/cctz/testdata/zoneinfo/America/Regina Binary files differindex 5fe8d6b6..20c9c84d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Regina +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Regina diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute b/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute Binary files differindex 884b1f64..4365a5c8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Resolute diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco b/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco Binary files differindex b612ac23..16b7f923 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rio_Branco diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario b/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario Binary files differindex 8c58f8c2..5df3cf6e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Rosario diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel b/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel Binary files differindex 29c83e71..ada6bf78 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santa_Isabel diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem b/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem Binary files differindex d776a438..8080efab 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santarem diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago Binary files differindex ab766a41..816a0428 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo b/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo Binary files differindex cc2cbf2b..4e5eba52 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santo_Domingo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo b/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo Binary files differindex 308a545c..c417ba1d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Sao_Paulo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund b/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund Binary files differindex 8e1366ca..e20e9e1c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Scoresbysund diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock b/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock Binary files differindex 7fc66917..5fbe26b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Shiprock diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka b/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka Binary files differindex 662b8b67..31f70613 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Sitka diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns Binary files differindex a1d14854..65a5b0c7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Johns diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current b/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current Binary files differindex 4db1300a..8e9ef255 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Swift_Current diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa b/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa Binary files differindex 7aea8f99..477e9395 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tegucigalpa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Thule b/absl/time/internal/cctz/testdata/zoneinfo/America/Thule Binary files differindex deefcc8d..2969ebe5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Thule +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Thule diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay b/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay Binary files differindex aa1d4860..e504c9ac 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Thunder_Bay diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana b/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana Binary files differindex 29c83e71..ada6bf78 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tijuana diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto b/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto Binary files differindex 7b4682a3..6752c5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Toronto diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver b/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver Binary files differindex 9b5d9241..0f9f8328 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Vancouver diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin Binary files differindex 447efbe2..bdedd1bd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse b/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse Binary files differindex 6b62e2d3..fb3cd71a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Whitehorse diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg b/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg Binary files differindex 2ffe3d8d..3718d47d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Winnipeg diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat b/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat Binary files differindex 523b0a10..da209f9f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Yakutat diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife b/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife Binary files differindex d9d6eff7..e6afa390 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey Binary files differindex d0bbacc8..f100f474 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Casey diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis Binary files differindex 40a99266..916f2c25 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Davis diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville Binary files differindex 06863534..bd6563ec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie Binary files differindex aea2be77..83c308ad 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Macquarie diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson Binary files differindex 5197dd97..e1f0b09b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Mawson diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo Binary files differindex a5f5b6d5..60bcef68 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/McMurdo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer Binary files differindex 43a01d3e..3dd85f84 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Palmer diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera Binary files differindex 56913f8a..7940e6ef 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Rothera diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole Binary files differindex a5f5b6d5..60bcef68 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/South_Pole diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa Binary files differindex 94a9d5a2..4bb041a2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll Binary files differindex 3757facc..5e565da2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Troll diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok Binary files differindex 9fa335c4..5696abf5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Vostok diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen b/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen Binary files differindex 239c0174..c6842af8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Arctic/Longyearbyen diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden Binary files differindex e71bc4e8..b2f9a255 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aden diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty Binary files differindex 49a4b4de..d93201cf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Almaty diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman Binary files differindex c3f0994a..281b304e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr Binary files differindex 0e623cf7..6a966013 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Anadyr diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau Binary files differindex 5803a3d3..78cbcf0e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe Binary files differindex 808a5026..7504052a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Aqtobe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat Binary files differindex 046c4728..8d9e03c1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashgabat diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad Binary files differindex 046c4728..8d9e03c1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ashkhabad diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau Binary files differindex 27072eb5..317466d1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Atyrau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad Binary files differindex 3aacd78b..97fa6c73 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baghdad diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain Binary files differindex a0c5f669..f5140926 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bahrain diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku Binary files differindex a17d1ad8..8a090d77 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Baku diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok Binary files differindex 8db5e8a6..72496402 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bangkok diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul Binary files differindex 60efb41b..82cc49c4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Barnaul diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut Binary files differindex 72f08963..efb24c27 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Beirut diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek Binary files differindex e3f81ee3..f7a7d548 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Bishkek diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei Binary files differindex cad16b0d..8624c7ae 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Brunei diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta Binary files differindex b57972dd..e1cfcb8d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Calcutta diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita Binary files differindex 95f56456..3baf7528 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chita diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan Binary files differindex 15b358f2..79b9d3c8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Choibalsan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing Binary files differindex dbd132f2..ce9e00a5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chongqing diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking Binary files differindex dbd132f2..ce9e00a5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Chungking diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo Binary files differindex 28fe4307..4fc96c89 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Colombo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca Binary files differindex 98881f09..776f27da 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dacca diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus Binary files differindex ac457646..4b610b5a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Damascus diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka Binary files differindex 98881f09..776f27da 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dhaka diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili Binary files differindex c94fa610..f6ce91a1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dili diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai Binary files differindex c12f31a1..7880d5d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dubai diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe Binary files differindex 67c772b4..694f6e6a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Dushanbe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta Binary files differindex 021f8a2d..653b146a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Famagusta diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza Binary files differindex 60d0de00..cf54deb8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin Binary files differindex dbd132f2..ce9e00a5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Harbin diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron Binary files differindex a2e1b364..09c876a6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh Binary files differindex 92642679..eab94fe8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ho_Chi_Minh diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong Binary files differindex dc9058e4..8e5c5813 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd Binary files differindex f367a550..8eb5f647 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hovd diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk Binary files differindex 84136366..e8c53c0d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Irkutsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul Binary files differindex 9a53b3a3..833d4eba 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Istanbul diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta Binary files differindex 37b4edde..673d4801 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jakarta diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura Binary files differindex 39ddc843..a4c08297 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jayapura diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem Binary files differindex df511993..2d14c999 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Jerusalem diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul Binary files differindex 80429ec4..a22cf592 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kabul diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka Binary files differindex fab27def..b9ed49ca 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kamchatka diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi Binary files differindex b7dcaab8..337e1d58 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Karachi diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar Binary files differindex b44a1e19..0342b433 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kashgar diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu Binary files differindex 0cbd2952..2f810b12 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kathmandu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu Binary files differindex 0cbd2952..2f810b12 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Katmandu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga Binary files differindex 91836953..2b2f5bfa 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Khandyga diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata Binary files differindex b57972dd..e1cfcb8d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kolkata diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk Binary files differindex faec35d3..59efd24c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Krasnoyarsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur Binary files differindex 5c95ebcd..6d7d47b9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuala_Lumpur diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching Binary files differindex 62b53892..4878622d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuching diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait Binary files differindex e71bc4e8..b2f9a255 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Kuwait diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao Binary files differindex 2c20a326..d801000d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macao diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau Binary files differindex 2c20a326..d801000d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Macau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan Binary files differindex 2db06356..b20cc57e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Magadan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar Binary files differindex 3a5dcb27..ed55442e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Makassar diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila Binary files differindex 06859a70..2c9220c9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Manila diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat Binary files differindex c12f31a1..7880d5d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Muscat diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia Binary files differindex 3e663b21..f7f10ab7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Nicosia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk Binary files differindex ed4b2482..2576a3b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novokuznetsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk Binary files differindex a5d39dff..95e3c73b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Novosibirsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk Binary files differindex 5e0d9b67..d805e4f7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Omsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral Binary files differindex b8eb58d1..e36aec47 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Oral diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh Binary files differindex 8db5e8a6..72496402 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Phnom_Penh diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak Binary files differindex ec98c62b..9377d038 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pontianak diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang Binary files differindex dc24926e..dd54989f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Pyongyang diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar Binary files differindex a0c5f669..f5140926 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qatar diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda Binary files differindex 0fc7fada..00b27844 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon Binary files differindex 3cc2aafa..a00282de 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Rangoon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh Binary files differindex e71bc4e8..b2f9a255 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Riyadh diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon Binary files differindex 92642679..eab94fe8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Saigon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin Binary files differindex 8d6b4dfe..9c94900c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Sakhalin diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand Binary files differindex 10c7af7f..a5d1e970 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Samarkand diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul Binary files differindex 312ec40a..fa1cbd39 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Seoul diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai Binary files differindex dbd132f2..ce9e00a5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Shanghai diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore Binary files differindex 78583666..ebc4b0d9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Singapore diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk Binary files differindex 16b1cd8f..f8b7bb21 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Srednekolymsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei Binary files differindex 748873be..f9cbe672 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Taipei diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent Binary files differindex 6f7dea4a..e75bb365 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tashkent diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi Binary files differindex 4b2d2e29..09bb06eb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tbilisi diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran Binary files differindex 3157f806..ad9058b4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv Binary files differindex df511993..2d14c999 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tel_Aviv diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu Binary files differindex a8bddb9f..06d3324d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimbu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu Binary files differindex a8bddb9f..06d3324d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Thimphu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo Binary files differindex 8ad44ba9..26f4d34d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tokyo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk Binary files differindex 919b0031..28da9c90 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tomsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang Binary files differindex 3a5dcb27..ed55442e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ujung_Pandang diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar Binary files differindex 94ddfea5..82fd4760 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulaanbaatar diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator Binary files differindex 94ddfea5..82fd4760 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ulan_Bator diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi Binary files differindex b44a1e19..0342b433 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Urumqi diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera Binary files differindex 7431eb97..c0c3767e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Ust-Nera diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane Binary files differindex 8db5e8a6..72496402 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vientiane diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok Binary files differindex 80b170bc..15731abc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Vladivostok diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk Binary files differindex 220ad3db..1f86e77f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yakutsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon Binary files differindex 3cc2aafa..a00282de 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yangon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg Binary files differindex c1abb935..fff9f3b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yekaterinburg diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan Binary files differindex 4c4e045b..409c3b17 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Yerevan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores Binary files differindex 1895e1b1..56593dbf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda Binary files differindex 548d979b..3a5c6dbf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Bermuda diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary Binary files differindex 544f443a..f3192156 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Canary diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde Binary files differindex 6bda6db7..e2a49d24 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Cape_Verde diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe Binary files differindex c4865186..4dab7ef0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faeroe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe Binary files differindex c4865186..4dab7ef0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Faroe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen Binary files differindex 239c0174..c6842af8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Jan_Mayen diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira Binary files differindex e25f8a59..5213761f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik Binary files differindex dc49c324..ac6bd697 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Reykjavik diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia Binary files differindex 56b383b1..b3311b63 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/South_Georgia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena Binary files differindex 6fd1af32..65d19ec2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/St_Helena diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley Binary files differindex 3649415b..2fd42a2c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Stanley diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT b/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT Binary files differindex aaed12ca..4ed4467f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/ACT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide Binary files differindex 4f331a87..190b0e33 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Adelaide diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane Binary files differindex a327d83b..26ffd9ac 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Brisbane diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill Binary files differindex 768b1678..874c8650 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Broken_Hill diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra Binary files differindex aaed12ca..4ed4467f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Canberra diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie Binary files differindex a3f6f29a..865801e5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Currie diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin Binary files differindex c6ae9a7b..cf42d1d8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Darwin diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla Binary files differindex 99f07a9f..c49d499c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Eucla diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart Binary files differindex 07784ce5..92d1215d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Hobart diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI b/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI Binary files differindex 57597b0b..8c6c7dd0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/LHI diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman Binary files differindex 71ca143f..8ee1a6f5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lindeman diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe Binary files differindex 57597b0b..8c6c7dd0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Lord_Howe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne Binary files differindex ec8dfe03..3f2d3d7f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Melbourne diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW b/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW Binary files differindex aaed12ca..4ed4467f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/NSW diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/North b/absl/time/internal/cctz/testdata/zoneinfo/Australia/North Binary files differindex c6ae9a7b..cf42d1d8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/North +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/North diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth Binary files differindex 85c26d50..d38b67e2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Perth diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland Binary files differindex a327d83b..26ffd9ac 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Queensland diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/South b/absl/time/internal/cctz/testdata/zoneinfo/Australia/South Binary files differindex 4f331a87..190b0e33 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/South +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/South diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney Binary files differindex aaed12ca..4ed4467f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Sydney diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania Binary files differindex 07784ce5..92d1215d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Tasmania diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria Binary files differindex ec8dfe03..3f2d3d7f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Victoria diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/West b/absl/time/internal/cctz/testdata/zoneinfo/Australia/West Binary files differindex 85c26d50..d38b67e2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/West +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/West diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna Binary files differindex 768b1678..874c8650 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna +++ b/absl/time/internal/cctz/testdata/zoneinfo/Australia/Yancowinna diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre Binary files differindex b612ac23..16b7f923 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/Acre diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha Binary files differindex 6d91f914..95ff8a25 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/DeNoronha diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East Binary files differindex 308a545c..c417ba1d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/East diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West Binary files differindex 855cb02c..b10241e6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West +++ b/absl/time/internal/cctz/testdata/zoneinfo/Brazil/West diff --git a/absl/time/internal/cctz/testdata/zoneinfo/CET b/absl/time/internal/cctz/testdata/zoneinfo/CET Binary files differindex 4c4f8ef9..d585656f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/CET +++ b/absl/time/internal/cctz/testdata/zoneinfo/CET diff --git a/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT b/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT Binary files differindex 5c8a1d9a..41c4136f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/CST6CDT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic Binary files differindex f86ece4c..756099ab 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Atlantic diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central Binary files differindex 2ffe3d8d..3718d47d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Central diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern Binary files differindex 7b4682a3..6752c5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Eastern diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain Binary files differindex d02fbcd4..3fa05798 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland Binary files differindex a1d14854..65a5b0c7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Newfoundland diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific Binary files differindex 9b5d9241..0f9f8328 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Pacific diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan Binary files differindex 5fe8d6b6..20c9c84d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Saskatchewan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon Binary files differindex 6b62e2d3..fb3cd71a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Canada/Yukon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental Binary files differindex ab766a41..816a0428 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental +++ b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland b/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland Binary files differindex 060bef81..cae37440 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Chile/EasterIsland diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Cuba b/absl/time/internal/cctz/testdata/zoneinfo/Cuba Binary files differindex 1a58fcdc..8186060a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Cuba +++ b/absl/time/internal/cctz/testdata/zoneinfo/Cuba diff --git a/absl/time/internal/cctz/testdata/zoneinfo/EET b/absl/time/internal/cctz/testdata/zoneinfo/EET Binary files differindex beb273a2..d2f54c9b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/EET +++ b/absl/time/internal/cctz/testdata/zoneinfo/EET diff --git a/absl/time/internal/cctz/testdata/zoneinfo/EST b/absl/time/internal/cctz/testdata/zoneinfo/EST Binary files differindex ae346633..074a4fc7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/EST +++ b/absl/time/internal/cctz/testdata/zoneinfo/EST diff --git a/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT b/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT Binary files differindex 54541fc2..087b641d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/EST5EDT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Egypt b/absl/time/internal/cctz/testdata/zoneinfo/Egypt Binary files differindex ba097504..0272fa1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Egypt +++ b/absl/time/internal/cctz/testdata/zoneinfo/Egypt diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Eire b/absl/time/internal/cctz/testdata/zoneinfo/Eire Binary files differindex 655daf37..5c5a7a3b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Eire +++ b/absl/time/internal/cctz/testdata/zoneinfo/Eire diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+0 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 Binary files differindex 082986e7..087d1f92 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+1 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 Binary files differindex 23276cd1..6437c684 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+10 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 Binary files differindex 28c579dc..72a912e0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+11 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 Binary files differindex c7406039..6938a1af 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+12 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 Binary files differindex 721cde2f..a3155777 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+2 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 Binary files differindex ae06bcb6..ee776199 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+3 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 Binary files differindex 5a7f878c..1ea7da29 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+4 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 Binary files differindex 18cbf1fe..dda1a9e1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+5 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 Binary files differindex 1aa4be88..f4a03855 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+6 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 Binary files differindex cd8ed49a..2d2ccd00 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+7 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 Binary files differindex e0ba6b88..826c7700 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+8 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 Binary files differindex eee1bcb7..b125ad2b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT+9 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-0 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 Binary files differindex 4ff87014..dde682d8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-1 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 Binary files differindex e12e461d..352ec08a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-10 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 Binary files differindex 37f27397..dfa27fec 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-11 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 Binary files differindex 09297f1b..eef949df 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-12 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 Binary files differindex 97ae1e14..f9363b24 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-13 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 Binary files differindex 58d6d1b2..35add05a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-14 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 Binary files differindex f0dc7062..315cae4f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-2 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 Binary files differindex a0790fe9..7489a153 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-3 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 Binary files differindex a75a173d..560243e8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-4 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 Binary files differindex 85ebf22e..b2bbe977 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-5 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 Binary files differindex 95def1f9..b979dbbc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-6 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 Binary files differindex c6a776e9..365ab1f6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-7 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 Binary files differindex f74a16f9..742082fc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-8 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 Binary files differindex 9b647c0f..abc0b275 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT-9 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/GMT0 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Greenwich diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT Binary files differindex 40147b9e..a88c4b66 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UCT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC Binary files differindex c3b97f1a..5583f5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/UTC diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal Binary files differindex c3b97f1a..5583f5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Universal diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu Binary files differindex c3b97f1a..5583f5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Etc/Zulu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam Binary files differindex 6dae5e47..ed064ed4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Amsterdam diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra Binary files differindex b06de7a5..59625503 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Andorra diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan Binary files differindex 90d7c2a8..5e069ea5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Astrakhan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens Binary files differindex 0001602f..9f3a0678 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Athens diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast Binary files differindex 4527515c..a340326e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belfast diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade Binary files differindex 79c25d70..32a57223 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Belgrade diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin Binary files differindex b4f2a2af..7ddd510e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Berlin diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava Binary files differindex ba82f311..85036de3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bratislava diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels Binary files differindex d8f19a63..d0d0a08a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Brussels diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest Binary files differindex e0eac4ce..4eb7ed0d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Bucharest diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest Binary files differindex 3ddf6a52..dfdc6d24 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Budapest diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen Binary files differindex 9c2b600b..ad6cf592 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Busingen diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau Binary files differindex 2109b52a..5bc1bfeb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Chisinau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen Binary files differindex be87cf16..cb2ec067 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Copenhagen diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin Binary files differindex 655daf37..5c5a7a3b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Dublin diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar Binary files differindex a7105faa..117aadb8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Gibraltar diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey Binary files differindex 4527515c..a340326e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Guernsey diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki Binary files differindex 29b3c817..b4f8f9cb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Helsinki diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man Binary files differindex 4527515c..a340326e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Isle_of_Man diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul Binary files differindex 9a53b3a3..833d4eba 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Istanbul diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey Binary files differindex 4527515c..a340326e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Jersey diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad Binary files differindex 37280d05..982d82a3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kaliningrad diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev Binary files differindex b3e20a7e..9337c9ea 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov Binary files differindex 40b558f8..a3b5320a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kirov diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon Binary files differindex a8565304..355817b5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana Binary files differindex 79c25d70..32a57223 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ljubljana diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/London b/absl/time/internal/cctz/testdata/zoneinfo/Europe/London Binary files differindex 4527515c..a340326e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/London +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/London diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg Binary files differindex 6fae86c5..6c194a5c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Luxembourg diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid Binary files differindex 9b51a73b..ccc9d857 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Madrid diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta Binary files differindex c1208e2d..bf2452da 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Malta diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn Binary files differindex 29b3c817..b4f8f9cb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Mariehamn diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk Binary files differindex 60041a41..801aead7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Minsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco Binary files differindex 0b40f1ec..686ae883 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Monaco diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow Binary files differindex 906bd05f..ddb3f4e9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Moscow diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia Binary files differindex 3e663b21..f7f10ab7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Nicosia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo Binary files differindex 239c0174..c6842af8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Oslo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris Binary files differindex cf6e2e2e..ca854351 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Paris diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica Binary files differindex 79c25d70..32a57223 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Podgorica diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague Binary files differindex ba82f311..85036de3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Prague diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga Binary files differindex b729ee8c..8495c506 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Riga diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome Binary files differindex bdd3449e..78a131b9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Rome diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara Binary files differindex 0539acfd..97d5dd9e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Samara diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino b/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino Binary files differindex bdd3449e..78a131b9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/San_Marino diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo Binary files differindex 79c25d70..32a57223 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sarajevo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov Binary files differindex e8cd6b10..8fd5f6d4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Saratov diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol Binary files differindex f3b42b00..e82dbbc7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje Binary files differindex 79c25d70..32a57223 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Skopje diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia Binary files differindex 763e0747..dcfdd082 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Sofia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm Binary files differindex 43c7f2e2..f3e0c7f0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Stockholm diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn Binary files differindex 18f903fa..3a744cc6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tallinn diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane Binary files differindex 52c16a42..0b86017d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tirane diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol Binary files differindex 2109b52a..5bc1bfeb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Tiraspol diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk Binary files differindex c280f430..7b61bdc5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Ulyanovsk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod Binary files differindex 8ddba909..677f0887 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz Binary files differindex 9c2b600b..ad6cf592 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vaduz diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican Binary files differindex bdd3449e..78a131b9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vatican diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna Binary files differindex 9c0fac53..9e2d0c94 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vienna diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius Binary files differindex da380af0..46ce484f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Vilnius diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd Binary files differindex f4cb64f1..8f170dd9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Volgograd diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw Binary files differindex 5cbba412..d6bb1561 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Warsaw diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb Binary files differindex 79c25d70..32a57223 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zagreb diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye Binary files differindex 6f148505..e42edfc8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich Binary files differindex 9c2b600b..ad6cf592 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zurich diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Factory b/absl/time/internal/cctz/testdata/zoneinfo/Factory Binary files differindex afeeb88d..95bc3a3b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Factory +++ b/absl/time/internal/cctz/testdata/zoneinfo/Factory diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GB b/absl/time/internal/cctz/testdata/zoneinfo/GB Binary files differindex 4527515c..a340326e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GB +++ b/absl/time/internal/cctz/testdata/zoneinfo/GB diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire b/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire Binary files differindex 4527515c..a340326e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire +++ b/absl/time/internal/cctz/testdata/zoneinfo/GB-Eire diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT b/absl/time/internal/cctz/testdata/zoneinfo/GMT Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 b/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT+0 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 b/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT-0 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/GMT0 b/absl/time/internal/cctz/testdata/zoneinfo/GMT0 Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/GMT0 +++ b/absl/time/internal/cctz/testdata/zoneinfo/GMT0 diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Greenwich b/absl/time/internal/cctz/testdata/zoneinfo/Greenwich Binary files differindex c05e45fd..2ee14295 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Greenwich +++ b/absl/time/internal/cctz/testdata/zoneinfo/Greenwich diff --git a/absl/time/internal/cctz/testdata/zoneinfo/HST b/absl/time/internal/cctz/testdata/zoneinfo/HST Binary files differindex 03e4db07..616c31bc 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/HST +++ b/absl/time/internal/cctz/testdata/zoneinfo/HST diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Hongkong b/absl/time/internal/cctz/testdata/zoneinfo/Hongkong Binary files differindex dc9058e4..8e5c5813 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Hongkong +++ b/absl/time/internal/cctz/testdata/zoneinfo/Hongkong diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Iceland b/absl/time/internal/cctz/testdata/zoneinfo/Iceland Binary files differindex dc49c324..ac6bd697 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Iceland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Iceland diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Antananarivo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos Binary files differindex 0e5e7192..f609611c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Chagos diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas Binary files differindex 066c1e9f..6babdeea 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Christmas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos Binary files differindex 34a2457b..58f80514 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Cocos diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Comoro diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen Binary files differindex e7d4d3d0..2cb6f3e3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Kerguelen diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe Binary files differindex db8ac687..49e23e5a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mahe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives Binary files differindex 3f1a76e5..ffa33658 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Maldives diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius Binary files differindex fd8d9111..b23e2cee 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mauritius diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte Binary files differindex 39631f21..6e19601f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Mayotte diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion Binary files differindex d5f9aa49..11c6002e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion +++ b/absl/time/internal/cctz/testdata/zoneinfo/Indian/Reunion diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Iran b/absl/time/internal/cctz/testdata/zoneinfo/Iran Binary files differindex 3157f806..ad9058b4 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Iran +++ b/absl/time/internal/cctz/testdata/zoneinfo/Iran diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Israel b/absl/time/internal/cctz/testdata/zoneinfo/Israel Binary files differindex df511993..2d14c999 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Israel +++ b/absl/time/internal/cctz/testdata/zoneinfo/Israel diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Jamaica b/absl/time/internal/cctz/testdata/zoneinfo/Jamaica Binary files differindex 7aedd262..162306f8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Jamaica +++ b/absl/time/internal/cctz/testdata/zoneinfo/Jamaica diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Japan b/absl/time/internal/cctz/testdata/zoneinfo/Japan Binary files differindex 8ad44ba9..26f4d34d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Japan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Japan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein b/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein Binary files differindex 1a27122e..54bd71ff 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein +++ b/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Libya b/absl/time/internal/cctz/testdata/zoneinfo/Libya Binary files differindex b32e2202..bd885315 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Libya +++ b/absl/time/internal/cctz/testdata/zoneinfo/Libya diff --git a/absl/time/internal/cctz/testdata/zoneinfo/MET b/absl/time/internal/cctz/testdata/zoneinfo/MET Binary files differindex 71963d53..388dd744 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/MET +++ b/absl/time/internal/cctz/testdata/zoneinfo/MET diff --git a/absl/time/internal/cctz/testdata/zoneinfo/MST b/absl/time/internal/cctz/testdata/zoneinfo/MST Binary files differindex a1bee7c6..da3e926d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/MST +++ b/absl/time/internal/cctz/testdata/zoneinfo/MST diff --git a/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT b/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT Binary files differindex 726a7e57..ddca8d19 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/MST7MDT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte Binary files differindex 29c83e71..ada6bf78 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte +++ b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaNorte diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur Binary files differindex afa94c2a..43ee12d8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur +++ b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/BajaSur diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General Binary files differindex f11e3d2d..1434ab08 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General +++ b/absl/time/internal/cctz/testdata/zoneinfo/Mexico/General diff --git a/absl/time/internal/cctz/testdata/zoneinfo/NZ b/absl/time/internal/cctz/testdata/zoneinfo/NZ Binary files differindex a5f5b6d5..60bcef68 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/NZ +++ b/absl/time/internal/cctz/testdata/zoneinfo/NZ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT b/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT Binary files differindex 957c80b7..abe09cb9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT +++ b/absl/time/internal/cctz/testdata/zoneinfo/NZ-CHAT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Navajo b/absl/time/internal/cctz/testdata/zoneinfo/Navajo Binary files differindex 7fc66917..5fbe26b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Navajo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Navajo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/PRC b/absl/time/internal/cctz/testdata/zoneinfo/PRC Binary files differindex dbd132f2..ce9e00a5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/PRC +++ b/absl/time/internal/cctz/testdata/zoneinfo/PRC diff --git a/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT b/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT Binary files differindex 6242ac04..d773e28f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT +++ b/absl/time/internal/cctz/testdata/zoneinfo/PST8PDT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia Binary files differindex 4091a85f..fd03ff76 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland Binary files differindex a5f5b6d5..60bcef68 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Auckland diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville Binary files differindex dc5a7d73..6a6c2da2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Bougainville diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham Binary files differindex 957c80b7..abe09cb9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chatham diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk Binary files differindex 289b795a..e79bca2d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter Binary files differindex 060bef81..cae37440 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Easter diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate Binary files differindex 5cee55df..d650a056 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Efate diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury Binary files differindex a3f30e5c..80873503 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo Binary files differindex 6e4b8afd..4fa169f3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fakaofo diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji Binary files differindex 912db189..61a66953 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti Binary files differindex 3289094a..e6a15447 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Funafuti diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos Binary files differindex 76b2b3a1..859b76d9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Galapagos diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier Binary files differindex 625016d5..4e9e36c5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Gambier diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal Binary files differindex 0c24095b..908ccc14 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guadalcanal diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam Binary files differindex 4286e6ba..ffdf8c24 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu Binary files differindex bd855772..c7cd0601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Honolulu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston Binary files differindex bd855772..c7cd0601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Johnston diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati Binary files differindex 762275d3..cf5b3bd3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kiritimati diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae Binary files differindex f8222e66..b6bd4b08 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein Binary files differindex 1a27122e..54bd71ff 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro Binary files differindex b3a8c184..53f32886 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas Binary files differindex 10c5c9bc..5fad0e1b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Marquesas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway Binary files differindex 3e38e97c..72707b5e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Midway diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru Binary files differindex 6092119f..7e7d920e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue Binary files differindex df6110dd..1d58fe36 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk Binary files differindex d0b9607e..f630a65d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Norfolk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea Binary files differindex d9c68f88..99f6bca2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Noumea diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago Binary files differindex 3e38e97c..72707b5e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pago_Pago diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau Binary files differindex e1bbea56..968f1956 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn Binary files differindex 54783cf6..9092e481 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pitcairn diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei Binary files differindex 9743bc3c..d3393a20 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape Binary files differindex 9743bc3c..d3393a20 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby Binary files differindex 3fa1f7fa..f6fd51cb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Port_Moresby diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga Binary files differindex ace1ce4b..9708b870 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan Binary files differindex 4286e6ba..ffdf8c24 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa Binary files differindex 3e38e97c..72707b5e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Samoa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti Binary files differindex 7867d8bd..37e4e883 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tahiti diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa Binary files differindex 33404138..e23c0cd2 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tarawa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu Binary files differindex b3a5a89b..35c9e2c6 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk Binary files differindex 289b795a..e79bca2d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake Binary files differindex 2dc630c6..837ce1f5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wake diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis Binary files differindex b4f0f9bf..8be9ac4d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Wallis diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap Binary files differindex 289b795a..e79bca2d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Poland b/absl/time/internal/cctz/testdata/zoneinfo/Poland Binary files differindex 5cbba412..d6bb1561 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Poland +++ b/absl/time/internal/cctz/testdata/zoneinfo/Poland diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Portugal b/absl/time/internal/cctz/testdata/zoneinfo/Portugal Binary files differindex a8565304..355817b5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Portugal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Portugal diff --git a/absl/time/internal/cctz/testdata/zoneinfo/ROC b/absl/time/internal/cctz/testdata/zoneinfo/ROC Binary files differindex 748873be..f9cbe672 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/ROC +++ b/absl/time/internal/cctz/testdata/zoneinfo/ROC diff --git a/absl/time/internal/cctz/testdata/zoneinfo/ROK b/absl/time/internal/cctz/testdata/zoneinfo/ROK Binary files differindex 312ec40a..fa1cbd39 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/ROK +++ b/absl/time/internal/cctz/testdata/zoneinfo/ROK diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Singapore b/absl/time/internal/cctz/testdata/zoneinfo/Singapore Binary files differindex 78583666..ebc4b0d9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Singapore +++ b/absl/time/internal/cctz/testdata/zoneinfo/Singapore diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Turkey b/absl/time/internal/cctz/testdata/zoneinfo/Turkey Binary files differindex 9a53b3a3..833d4eba 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Turkey +++ b/absl/time/internal/cctz/testdata/zoneinfo/Turkey diff --git a/absl/time/internal/cctz/testdata/zoneinfo/UCT b/absl/time/internal/cctz/testdata/zoneinfo/UCT Binary files differindex 40147b9e..a88c4b66 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/UCT +++ b/absl/time/internal/cctz/testdata/zoneinfo/UCT diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska b/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska Binary files differindex 6c8bdf22..9bbb2fd3 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Alaska diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian b/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian Binary files differindex 5696e0f8..43236498 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Aleutian diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona b/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona Binary files differindex adf28236..4d51271a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Arizona diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Central b/absl/time/internal/cctz/testdata/zoneinfo/US/Central Binary files differindex 3dd8f0fa..a5b1617c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Central +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Central diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana b/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana Binary files differindex 4a92c065..09511ccd 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/East-Indiana diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern b/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern Binary files differindex 7553fee3..2f75480e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Eastern diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii b/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii Binary files differindex bd855772..c7cd0601 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Hawaii diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke b/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke Binary files differindex cc785da9..fcd408d7 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Indiana-Starke diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan b/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan Binary files differindex e3ea5c3e..5e022605 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Michigan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain b/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain Binary files differindex 7fc66917..5fbe26b1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Mountain diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific b/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific Binary files differindex c0ce4402..9dad4f4c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Pacific diff --git a/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa b/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa Binary files differindex 3e38e97c..72707b5e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa +++ b/absl/time/internal/cctz/testdata/zoneinfo/US/Samoa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/UTC b/absl/time/internal/cctz/testdata/zoneinfo/UTC Binary files differindex c3b97f1a..5583f5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/UTC +++ b/absl/time/internal/cctz/testdata/zoneinfo/UTC diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Universal b/absl/time/internal/cctz/testdata/zoneinfo/Universal Binary files differindex c3b97f1a..5583f5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Universal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Universal diff --git a/absl/time/internal/cctz/testdata/zoneinfo/W-SU b/absl/time/internal/cctz/testdata/zoneinfo/W-SU Binary files differindex 906bd05f..ddb3f4e9 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/W-SU +++ b/absl/time/internal/cctz/testdata/zoneinfo/W-SU diff --git a/absl/time/internal/cctz/testdata/zoneinfo/WET b/absl/time/internal/cctz/testdata/zoneinfo/WET Binary files differindex 444a1933..9b03a17f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/WET +++ b/absl/time/internal/cctz/testdata/zoneinfo/WET diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Zulu b/absl/time/internal/cctz/testdata/zoneinfo/Zulu Binary files differindex c3b97f1a..5583f5b0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Zulu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Zulu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab index 2d90ed72..2729e6e8 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +++ b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab @@ -1,35 +1,35 @@ -# tz zone descriptions +# tzdb timezone descriptions # # This file is in the public domain. # -# From Paul Eggert (2017-10-01): -# This file contains a table where each row stands for a zone where -# civil time stamps have agreed since 1970. Columns are separated by +# From Paul Eggert (2018-06-27): +# This file contains a table where each row stands for a timezone where +# civil timestamps have agreed since 1970. Columns are separated by # a single tab. Lines beginning with '#' are comments. All text uses # UTF-8 encoding. The columns of the table are as follows: # -# 1. The countries that overlap the zone, as a comma-separated list +# 1. The countries that overlap the timezone, as a comma-separated list # of ISO 3166 2-character country codes. See the file 'iso3166.tab'. -# 2. Latitude and longitude of the zone's principal location +# 2. Latitude and longitude of the timezone's principal location # in ISO 6709 sign-degrees-minutes-seconds format, # either ±DDMM±DDDMM or ±DDMMSS±DDDMMSS, # first latitude (+ is north), then longitude (+ is east). -# 3. Zone name used in value of TZ environment variable. -# Please see the theory.html file for how zone names are chosen. -# If multiple zones overlap a country, each has a row in the +# 3. Timezone name used in value of TZ environment variable. +# Please see the theory.html file for how these names are chosen. +# If multiple timezones overlap a country, each has a row in the # table, with each column 1 containing the country code. -# 4. Comments; present if and only if a country has multiple zones. +# 4. Comments; present if and only if a country has multiple timezones. # -# If a zone covers multiple countries, the most-populous city is used, +# If a timezone covers multiple countries, the most-populous city is used, # and that country is listed first in column 1; any other countries # are listed alphabetically by country code. The table is sorted # first by country code, then (if possible) by an order within the # country that (1) makes some geographical sense, and (2) puts the -# most populous zones first, where that does not contradict (1). +# most populous timezones first, where that does not contradict (1). # -# This table is intended as an aid for users, to help them select time -# zone data entries appropriate for their practical needs. It is not -# intended to take or endorse any position on legal or territorial claims. +# This table is intended as an aid for users, to help them select timezones +# appropriate for their practical needs. It is not intended to take or +# endorse any position on legal or territorial claims. # #country- #codes coordinates TZ comments @@ -231,7 +231,7 @@ MM +1647+09610 Asia/Yangon MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas) MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar -MO +2214+11335 Asia/Macau +MO +221150+1133230 Asia/Macau MQ +1436-06105 America/Martinique MT +3554+01431 Europe/Malta MU -2010+05730 Indian/Mauritius @@ -289,9 +289,9 @@ RS,BA,HR,ME,MK,SI +4450+02030 Europe/Belgrade RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area RU +4457+03406 Europe/Simferopol MSK+00 - Crimea -RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd RU +5836+04939 Europe/Kirov MSK+00 - Kirov RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan +RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd RU +5134+04602 Europe/Saratov MSK+01 - Saratov RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia diff --git a/absl/time/internal/get_current_time_chrono.inc b/absl/time/internal/get_current_time_chrono.inc new file mode 100644 index 00000000..ba016e3e --- /dev/null +++ b/absl/time/internal/get_current_time_chrono.inc @@ -0,0 +1,31 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// http://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 <chrono> +#include <cstdint> + +namespace absl { +inline namespace lts_2018_12_18 { +namespace time_internal { + +static int64_t GetCurrentTimeNanosFromSystem() { + return std::chrono::duration_cast<std::chrono::nanoseconds>( + std::chrono::system_clock::now() - + std::chrono::system_clock::from_time_t(0)) + .count(); +} + +} // namespace time_internal +} // inline namespace lts_2018_12_18 +} // namespace absl diff --git a/absl/time/internal/get_current_time_ios.inc b/absl/time/internal/get_current_time_ios.inc deleted file mode 100644 index abd43cb4..00000000 --- a/absl/time/internal/get_current_time_ios.inc +++ /dev/null @@ -1,82 +0,0 @@ -#include "absl/time/clock.h" - -#include <sys/time.h> -#include <ctime> -#include <cstdint> - -#include "absl/base/internal/raw_logging.h" - -// These are not defined in the Xcode 7.3.1 SDK Headers. -// Once we are no longer supporting Xcode 7.3.1 we can -// remove these. -#ifndef __WATCHOS_3_0 -#define __WATCHOS_3_0 30000 -#endif - -#ifndef __TVOS_10_0 -#define __TVOS_10_0 100000 -#endif - -#ifndef __IPHONE_10_0 -#define __IPHONE_10_0 100000 -#endif - -#ifndef __MAC_10_12 -#define __MAC_10_12 101200 -#endif - -namespace absl { -inline namespace lts_2018_06_20 { -namespace time_internal { - -static int64_t GetCurrentTimeNanosFromSystem() { -#if (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_12) || \ - (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0) || \ - (__WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0) || \ - (__TV_OS_VERSION_MAX_ALLOWED >= __TVOS_10_0) - // clock_gettime_nsec_np is not defined on SDKs before Xcode 8.0. - // This preprocessor logic is based upon __CLOCK_AVAILABILITY in - // usr/include/time.h. Once we are no longer supporting Xcode 7.3.1 we can - // remove this #if. - // We must continue to check if it is defined until we are sure that ALL the - // platforms we are shipping on support it. - // clock_gettime_nsec_np is preferred because it may give higher accuracy than - // gettimeofday in future Apple operating systems. - // Currently (macOS 10.12/iOS 10.2) clock_gettime_nsec_np accuracy is - // microsecond accuracy (i.e. equivalent to gettimeofday). - if (&clock_gettime_nsec_np != nullptr) { - return clock_gettime_nsec_np(CLOCK_REALTIME); - } -#endif -#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ - (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12)) || \ - (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ - (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)) || \ - (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \ - (__WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_3_0)) || \ - (defined(__TV_OS_VERSION_MIN_REQUIRED) && \ - (__TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0)) - // We need this block in 2 different cases: - // a) where we are compiling with Xcode 7 in which case the block above - // will not be compiled in, and this is the only block executed. - // b) where we are compiling with Xcode 8+ but supporting operating systems - // that do not define clock_gettime_nsec_np, so this is in effect - // an else block to the block above. - // This block will not be compiled if the min supported version is - // guaranteed to supply clock_gettime_nsec_np. - // - // Once we know that clock_gettime_nsec_np is in the SDK *AND* exists on - // all the platforms we support, we can remove both this block and alter the - // block above to just call clock_gettime_nsec_np directly. - const int64_t kNanosPerSecond = 1000 * 1000 * 1000; - const int64_t kNanosPerMicrosecond = 1000; - struct timeval tp; - ABSL_RAW_CHECK(gettimeofday(&tp, nullptr) == 0, "Failed gettimeofday"); - return (int64_t{tp.tv_sec} * kNanosPerSecond + - int64_t{tp.tv_usec} * kNanosPerMicrosecond); -#endif -} - -} // namespace time_internal -} // inline namespace lts_2018_06_20 -} // namespace absl diff --git a/absl/time/internal/get_current_time_posix.inc b/absl/time/internal/get_current_time_posix.inc index dfbcf8a6..3ff45c4a 100644 --- a/absl/time/internal/get_current_time_posix.inc +++ b/absl/time/internal/get_current_time_posix.inc @@ -7,7 +7,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { static int64_t GetCurrentTimeNanosFromSystem() { @@ -20,5 +20,5 @@ static int64_t GetCurrentTimeNanosFromSystem() { } } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/get_current_time_windows.inc b/absl/time/internal/get_current_time_windows.inc deleted file mode 100644 index 273d2d80..00000000 --- a/absl/time/internal/get_current_time_windows.inc +++ /dev/null @@ -1,19 +0,0 @@ -#include "absl/time/clock.h" - -#include <chrono> -#include <cstdint> - -namespace absl { -inline namespace lts_2018_06_20 { -namespace time_internal { - -static int64_t GetCurrentTimeNanosFromSystem() { - return std::chrono::duration_cast<std::chrono::nanoseconds>( - std::chrono::system_clock::now() - - std::chrono::system_clock::from_time_t(0)) - .count(); -} - -} // namespace time_internal -} // inline namespace lts_2018_06_20 -} // namespace absl diff --git a/absl/time/internal/test_util.cc b/absl/time/internal/test_util.cc index 1cc89b5e..69530e64 100644 --- a/absl/time/internal/test_util.cc +++ b/absl/time/internal/test_util.cc @@ -24,15 +24,9 @@ namespace cctz = absl::time_internal::cctz; namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { -#if GTEST_USES_SIMPLE_RE -extern const char kZoneAbbrRE[] = ".*"; // just punt -#else -extern const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?"; -#endif - TimeZone LoadTimeZone(const std::string& name) { TimeZone tz; ABSL_RAW_CHECK(LoadTimeZone(name, &tz), name.c_str()); @@ -40,11 +34,11 @@ TimeZone LoadTimeZone(const std::string& name) { } } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { namespace cctz_extension { namespace { @@ -129,5 +123,5 @@ ZoneInfoSourceFactory zone_info_source_factory = TestFactory; } // namespace cctz_extension } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/internal/test_util.h b/absl/time/internal/test_util.h index fb65f9bd..31ec18e4 100644 --- a/absl/time/internal/test_util.h +++ b/absl/time/internal/test_util.h @@ -17,41 +17,17 @@ #include <string> -#include "gmock/gmock.h" -#include "gtest/gtest.h" #include "absl/time/time.h" -// This helper is a macro so that failed expectations show up with the -// correct line numbers. -// -// This is for internal testing of the Base Time library itself. This is not -// part of a public API. -#define ABSL_INTERNAL_EXPECT_TIME(bd, y, m, d, h, min, s, off, isdst) \ - do { \ - EXPECT_EQ(y, bd.year); \ - EXPECT_EQ(m, bd.month); \ - EXPECT_EQ(d, bd.day); \ - EXPECT_EQ(h, bd.hour); \ - EXPECT_EQ(min, bd.minute); \ - EXPECT_EQ(s, bd.second); \ - EXPECT_EQ(off, bd.offset); \ - EXPECT_EQ(isdst, bd.is_dst); \ - EXPECT_THAT(bd.zone_abbr, \ - testing::MatchesRegex(absl::time_internal::kZoneAbbrRE)); \ - } while (0) - namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace time_internal { -// A regular expression that matches all zone abbreviations (%Z). -extern const char kZoneAbbrRE[]; - // Loads the named timezone, but dies on any failure. absl::TimeZone LoadTimeZone(const std::string& name); } // namespace time_internal -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_INTERNAL_TEST_UTIL_H_ diff --git a/absl/time/time.cc b/absl/time/time.cc index 76ce12c9..e60857e2 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc @@ -22,13 +22,14 @@ // NOTE: To keep type verbosity to a minimum, the following variable naming // conventions are used throughout this file. // -// cz: A cctz::time_zone // tz: An absl::TimeZone +// ci: An absl::TimeZone::CivilInfo +// ti: An absl::TimeZone::TimeInfo +// cd: An absl::CivilDay or a cctz::civil_day +// cs: An absl::CivilSecond or a cctz::civil_second +// bd: An absl::Time::Breakdown // cl: A cctz::time_zone::civil_lookup // al: A cctz::time_zone::absolute_lookup -// cd: A cctz::civil_day -// cs: A cctz::civil_second -// bd: An absl::Time::Breakdown #include "absl/time/time.h" @@ -41,12 +42,12 @@ namespace cctz = absl::time_internal::cctz; namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { namespace { -inline cctz::time_point<cctz::sys_seconds> unix_epoch() { - return std::chrono::time_point_cast<cctz::sys_seconds>( +inline cctz::time_point<cctz::seconds> unix_epoch() { + return std::chrono::time_point_cast<cctz::seconds>( std::chrono::system_clock::from_time_t(0)); } @@ -76,7 +77,7 @@ inline absl::Time::Breakdown InfiniteFutureBreakdown() { return bd; } -inline Time::Breakdown InfinitePastBreakdown() { +inline absl::Time::Breakdown InfinitePastBreakdown() { Time::Breakdown bd; bd.year = std::numeric_limits<int64_t>::min(); bd.month = 1; @@ -93,6 +94,26 @@ inline Time::Breakdown InfinitePastBreakdown() { return bd; } +inline absl::TimeZone::CivilInfo InfiniteFutureCivilInfo() { + TimeZone::CivilInfo ci; + ci.cs = CivilSecond::max(); + ci.subsecond = InfiniteDuration(); + ci.offset = 0; + ci.is_dst = false; + ci.zone_abbr = "-00"; + return ci; +} + +inline absl::TimeZone::CivilInfo InfinitePastCivilInfo() { + TimeZone::CivilInfo ci; + ci.cs = CivilSecond::min(); + ci.subsecond = -InfiniteDuration(); + ci.offset = 0; + ci.is_dst = false; + ci.zone_abbr = "-00"; + return ci; +} + inline absl::TimeConversion InfiniteFutureTimeConversion() { absl::TimeConversion tc; tc.pre = tc.trans = tc.post = absl::InfiniteFuture(); @@ -111,12 +132,12 @@ inline TimeConversion InfinitePastTimeConversion() { // Makes a Time from sec, overflowing to InfiniteFuture/InfinitePast as // necessary. If sec is min/max, then consult cs+tz to check for overlow. -Time MakeTimeWithOverflow(const cctz::time_point<cctz::sys_seconds>& sec, +Time MakeTimeWithOverflow(const cctz::time_point<cctz::seconds>& sec, const cctz::civil_second& cs, const cctz::time_zone& tz, bool* normalized = nullptr) { - const auto max = cctz::time_point<cctz::sys_seconds>::max(); - const auto min = cctz::time_point<cctz::sys_seconds>::min(); + const auto max = cctz::time_point<cctz::seconds>::max(); + const auto min = cctz::time_point<cctz::seconds>::min(); if (sec == max) { const auto al = tz.lookup(max); if (cs > al.cs) { @@ -135,19 +156,6 @@ Time MakeTimeWithOverflow(const cctz::time_point<cctz::sys_seconds>& sec, return time_internal::FromUnixDuration(time_internal::MakeDuration(hi)); } -inline absl::TimeConversion::Kind MapKind( - const cctz::time_zone::civil_lookup::civil_kind& kind) { - switch (kind) { - case cctz::time_zone::civil_lookup::UNIQUE: - return absl::TimeConversion::UNIQUE; - case cctz::time_zone::civil_lookup::SKIPPED: - return absl::TimeConversion::SKIPPED; - case cctz::time_zone::civil_lookup::REPEATED: - return absl::TimeConversion::REPEATED; - } - return absl::TimeConversion::UNIQUE; -} - // Returns Mon=1..Sun=7. inline int MapWeekday(const cctz::weekday& wd) { switch (wd) { @@ -169,14 +177,31 @@ inline int MapWeekday(const cctz::weekday& wd) { return 1; } +bool FindTransition(const cctz::time_zone& tz, + bool (cctz::time_zone::*find_transition)( + const cctz::time_point<cctz::seconds>& tp, + cctz::time_zone::civil_transition* trans) const, + Time t, TimeZone::CivilTransition* trans) { + // Transitions are second-aligned, so we can discard any fractional part. + const auto tp = unix_epoch() + cctz::seconds(ToUnixSeconds(t)); + cctz::time_zone::civil_transition tr; + if (!(tz.*find_transition)(tp, &tr)) return false; + trans->from = CivilSecond(tr.from); + trans->to = CivilSecond(tr.to); + return true; +} + } // namespace +// +// Time +// + absl::Time::Breakdown Time::In(absl::TimeZone tz) const { - if (*this == absl::InfiniteFuture()) return absl::InfiniteFutureBreakdown(); - if (*this == absl::InfinitePast()) return absl::InfinitePastBreakdown(); + if (*this == absl::InfiniteFuture()) return InfiniteFutureBreakdown(); + if (*this == absl::InfinitePast()) return InfinitePastBreakdown(); - const auto tp = - unix_epoch() + cctz::sys_seconds(time_internal::GetRepHi(rep_)); + const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(rep_)); const auto al = cctz::time_zone(tz).lookup(tp); const auto cs = al.cs; const auto cd = cctz::civil_day(cs); @@ -189,92 +214,18 @@ absl::Time::Breakdown Time::In(absl::TimeZone tz) const { bd.minute = cs.minute(); bd.second = cs.second(); bd.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(rep_)); - bd.weekday = MapWeekday(get_weekday(cd)); - bd.yearday = get_yearday(cd); + bd.weekday = MapWeekday(cctz::get_weekday(cd)); + bd.yearday = cctz::get_yearday(cd); bd.offset = al.offset; bd.is_dst = al.is_dst; bd.zone_abbr = al.abbr; return bd; } -absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) { - const auto cz = cctz::time_zone(tz); - const auto cs = - cctz::civil_second(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - const auto cl = cz.lookup(cs); - const auto tp = tm.tm_isdst == 0 ? cl.post : cl.pre; - return MakeTimeWithOverflow(tp, cs, cz); -} - -struct tm ToTM(absl::Time t, absl::TimeZone tz) { - const absl::Time::Breakdown bd = t.In(tz); - struct tm tm; - std::memset(&tm, 0, sizeof(tm)); - tm.tm_sec = bd.second; - tm.tm_min = bd.minute; - tm.tm_hour = bd.hour; - tm.tm_mday = bd.day; - tm.tm_mon = bd.month - 1; - - // Saturates tm.tm_year in cases of over/underflow, accounting for the fact - // that tm.tm_year is years since 1900. - if (bd.year < std::numeric_limits<int>::min() + 1900) { - tm.tm_year = std::numeric_limits<int>::min(); - } else if (bd.year > std::numeric_limits<int>::max()) { - tm.tm_year = std::numeric_limits<int>::max() - 1900; - } else { - tm.tm_year = static_cast<int>(bd.year - 1900); - } - - tm.tm_wday = bd.weekday % 7; - tm.tm_yday = bd.yearday - 1; - tm.tm_isdst = bd.is_dst ? 1 : 0; - - return tm; -} - // -// Factory functions. +// Conversions from/to other time types. // -absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, - int min, int sec, TimeZone tz) { - // Avoids years that are too extreme for civil_second to normalize. - if (year > 300000000000) return InfiniteFutureTimeConversion(); - if (year < -300000000000) return InfinitePastTimeConversion(); - const auto cz = cctz::time_zone(tz); - const auto cs = cctz::civil_second(year, mon, day, hour, min, sec); - absl::TimeConversion tc; - tc.normalized = year != cs.year() || mon != cs.month() || day != cs.day() || - hour != cs.hour() || min != cs.minute() || sec != cs.second(); - const auto cl = cz.lookup(cs); - // Converts the civil_lookup struct to a TimeConversion. - tc.pre = MakeTimeWithOverflow(cl.pre, cs, cz, &tc.normalized); - tc.trans = MakeTimeWithOverflow(cl.trans, cs, cz, &tc.normalized); - tc.post = MakeTimeWithOverflow(cl.post, cs, cz, &tc.normalized); - tc.kind = MapKind(cl.kind); - return tc; -} - -absl::Time FromDateTime(int64_t year, int mon, int day, int hour, int min, - int sec, TimeZone tz) { - if (year > 300000000000) return InfiniteFuture(); - if (year < -300000000000) return InfinitePast(); - const auto cz = cctz::time_zone(tz); - const auto cs = cctz::civil_second(year, mon, day, hour, min, sec); - const auto cl = cz.lookup(cs); - return MakeTimeWithOverflow(cl.pre, cs, cz); -} - -absl::Time TimeFromTimespec(timespec ts) { - return time_internal::FromUnixDuration(absl::DurationFromTimespec(ts)); -} - -absl::Time TimeFromTimeval(timeval tv) { - return time_internal::FromUnixDuration(absl::DurationFromTimeval(tv)); -} - absl::Time FromUDate(double udate) { return time_internal::FromUnixDuration(absl::Milliseconds(udate)); } @@ -283,10 +234,6 @@ absl::Time FromUniversal(int64_t universal) { return absl::UniversalEpoch() + 100 * absl::Nanoseconds(universal); } -// -// Conversion to other time types. -// - int64_t ToUnixNanos(Time t) { if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 && time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 33 == 0) { @@ -323,6 +270,23 @@ int64_t ToUnixSeconds(Time t) { time_t ToTimeT(Time t) { return absl::ToTimespec(t).tv_sec; } +double ToUDate(Time t) { + return absl::FDivDuration(time_internal::ToUnixDuration(t), + absl::Milliseconds(1)); +} + +int64_t ToUniversal(absl::Time t) { + return absl::FloorToUnit(t - absl::UniversalEpoch(), absl::Nanoseconds(100)); +} + +absl::Time TimeFromTimespec(timespec ts) { + return time_internal::FromUnixDuration(absl::DurationFromTimespec(ts)); +} + +absl::Time TimeFromTimeval(timeval tv) { + return time_internal::FromUnixDuration(absl::DurationFromTimeval(tv)); +} + timespec ToTimespec(Time t) { timespec ts; absl::Duration d = time_internal::ToUnixDuration(t); @@ -361,15 +325,6 @@ timeval ToTimeval(Time t) { return tv; } -double ToUDate(Time t) { - return absl::FDivDuration(time_internal::ToUnixDuration(t), - absl::Milliseconds(1)); -} - -int64_t ToUniversal(absl::Time t) { - return absl::FloorToUnit(t - absl::UniversalEpoch(), absl::Nanoseconds(100)); -} - Time FromChrono(const std::chrono::system_clock::time_point& tp) { return time_internal::FromUnixDuration(time_internal::FromChrono( tp - std::chrono::system_clock::from_time_t(0))); @@ -383,5 +338,150 @@ std::chrono::system_clock::time_point ToChronoTime(absl::Time t) { time_internal::ToChronoDuration<D>(d); } -} // inline namespace lts_2018_06_20 +// +// TimeZone +// + +absl::TimeZone::CivilInfo TimeZone::At(Time t) const { + if (t == absl::InfiniteFuture()) return InfiniteFutureCivilInfo(); + if (t == absl::InfinitePast()) return InfinitePastCivilInfo(); + + const auto ud = time_internal::ToUnixDuration(t); + const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(ud)); + const auto al = cz_.lookup(tp); + + TimeZone::CivilInfo ci; + ci.cs = CivilSecond(al.cs); + ci.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(ud)); + ci.offset = al.offset; + ci.is_dst = al.is_dst; + ci.zone_abbr = al.abbr; + return ci; +} + +absl::TimeZone::TimeInfo TimeZone::At(CivilSecond ct) const { + const cctz::civil_second cs(ct); + const auto cl = cz_.lookup(cs); + + TimeZone::TimeInfo ti; + switch (cl.kind) { + case cctz::time_zone::civil_lookup::UNIQUE: + ti.kind = TimeZone::TimeInfo::UNIQUE; + break; + case cctz::time_zone::civil_lookup::SKIPPED: + ti.kind = TimeZone::TimeInfo::SKIPPED; + break; + case cctz::time_zone::civil_lookup::REPEATED: + ti.kind = TimeZone::TimeInfo::REPEATED; + break; + } + ti.pre = MakeTimeWithOverflow(cl.pre, cs, cz_); + ti.trans = MakeTimeWithOverflow(cl.trans, cs, cz_); + ti.post = MakeTimeWithOverflow(cl.post, cs, cz_); + return ti; +} + +bool TimeZone::NextTransition(Time t, CivilTransition* trans) const { + return FindTransition(cz_, &cctz::time_zone::next_transition, t, trans); +} + +bool TimeZone::PrevTransition(Time t, CivilTransition* trans) const { + return FindTransition(cz_, &cctz::time_zone::prev_transition, t, trans); +} + +// +// Conversions involving time zones. +// + +absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, + int min, int sec, TimeZone tz) { + // Avoids years that are too extreme for CivilSecond to normalize. + if (year > 300000000000) return InfiniteFutureTimeConversion(); + if (year < -300000000000) return InfinitePastTimeConversion(); + + const CivilSecond cs(year, mon, day, hour, min, sec); + const auto ti = tz.At(cs); + + TimeConversion tc; + tc.pre = ti.pre; + tc.trans = ti.trans; + tc.post = ti.post; + switch (ti.kind) { + case TimeZone::TimeInfo::UNIQUE: + tc.kind = TimeConversion::UNIQUE; + break; + case TimeZone::TimeInfo::SKIPPED: + tc.kind = TimeConversion::SKIPPED; + break; + case TimeZone::TimeInfo::REPEATED: + tc.kind = TimeConversion::REPEATED; + break; + } + tc.normalized = false; + if (year != cs.year() || mon != cs.month() || day != cs.day() || + hour != cs.hour() || min != cs.minute() || sec != cs.second()) { + tc.normalized = true; + } + return tc; +} + +absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) { + const CivilSecond cs(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + const auto ti = tz.At(cs); + return tm.tm_isdst == 0 ? ti.post : ti.pre; +} + +struct tm ToTM(absl::Time t, absl::TimeZone tz) { + struct tm tm = {}; + + const auto ci = tz.At(t); + const auto& cs = ci.cs; + tm.tm_sec = cs.second(); + tm.tm_min = cs.minute(); + tm.tm_hour = cs.hour(); + tm.tm_mday = cs.day(); + tm.tm_mon = cs.month() - 1; + + // Saturates tm.tm_year in cases of over/underflow, accounting for the fact + // that tm.tm_year is years since 1900. + if (cs.year() < std::numeric_limits<int>::min() + 1900) { + tm.tm_year = std::numeric_limits<int>::min(); + } else if (cs.year() > std::numeric_limits<int>::max()) { + tm.tm_year = std::numeric_limits<int>::max() - 1900; + } else { + tm.tm_year = static_cast<int>(cs.year() - 1900); + } + + const CivilDay cd(cs); + switch (GetWeekday(cd)) { + case Weekday::sunday: + tm.tm_wday = 0; + break; + case Weekday::monday: + tm.tm_wday = 1; + break; + case Weekday::tuesday: + tm.tm_wday = 2; + break; + case Weekday::wednesday: + tm.tm_wday = 3; + break; + case Weekday::thursday: + tm.tm_wday = 4; + break; + case Weekday::friday: + tm.tm_wday = 5; + break; + case Weekday::saturday: + tm.tm_wday = 6; + break; + } + tm.tm_yday = GetYearDay(cd) - 1; + tm.tm_isdst = ci.is_dst ? 1 : 0; + + return tm; +} + +} // inline namespace lts_2018_12_18 } // namespace absl diff --git a/absl/time/time.h b/absl/time/time.h index 3b5739ff..3afec565 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -25,17 +25,29 @@ // * `absl::TimeZone` defines geopolitical time zone regions (as collected // within the IANA Time Zone database (https://www.iana.org/time-zones)). // +// Note: Absolute times are distinct from civil times, which refer to the +// human-scale time commonly represented by `YYYY-MM-DD hh:mm:ss`. The mapping +// between absolute and civil times can be specified by use of time zones +// (`absl::TimeZone` within this API). That is: +// +// Civil Time = F(Absolute Time, Time Zone) +// Absolute Time = G(Civil Time, Time Zone) +// +// See civil_time.h for abstractions related to constructing and manipulating +// civil time. +// // Example: // // absl::TimeZone nyc; -// -// // LoadTimeZone may fail so it's always better to check for success. +// // LoadTimeZone() may fail so it's always better to check for success. // if (!absl::LoadTimeZone("America/New_York", &nyc)) { // // handle error case // } // // // My flight leaves NYC on Jan 2, 2017 at 03:04:05 -// absl::Time takeoff = absl::FromDateTime(2017, 1, 2, 3, 4, 5, nyc); +// absl::CivilSecond cs(2017, 1, 2, 3, 4, 5); +// absl::Time takeoff = absl::FromCivil(cs, nyc); +// // absl::Duration flight_duration = absl::Hours(21) + absl::Minutes(35); // absl::Time landing = takeoff + flight_duration; // @@ -47,15 +59,17 @@ // "My flight will land in Sydney on %Y-%m-%d at %H:%M:%S", // landing, syd); // + #ifndef ABSL_TIME_TIME_H_ #define ABSL_TIME_TIME_H_ -#if !defined(_WIN32) +#if !defined(_MSC_VER) #include <sys/time.h> #else #include <winsock2.h> #endif #include <chrono> // NOLINT(build/c++11) +#include <cmath> #include <cstdint> #include <ctime> #include <ostream> @@ -65,10 +79,11 @@ #include "absl/base/port.h" // Needed for string vs std::string #include "absl/strings/string_view.h" +#include "absl/time/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { -inline namespace lts_2018_06_20 { +inline namespace lts_2018_12_18 { class Duration; // Defined below class Time; // Defined below @@ -82,6 +97,7 @@ constexpr int64_t GetRepHi(Duration d); constexpr uint32_t GetRepLo(Duration d); constexpr Duration MakeDuration(int64_t hi, uint32_t lo); constexpr Duration MakeDuration(int64_t hi, int64_t lo); +inline Duration MakePosDoubleDuration(double n); constexpr int64_t kTicksPerNanosecond = 4; constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond; template <std::intmax_t N> @@ -139,6 +155,16 @@ class Duration { // Value semantics. constexpr Duration() : rep_hi_(0), rep_lo_(0) {} // zero-length duration + // Copyable. +#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1910 + // Explicitly defining the constexpr copy constructor avoids an MSVC bug. + constexpr Duration(const Duration& d) + : rep_hi_(d.rep_hi_), rep_lo_(d.rep_lo_) {} +#else + constexpr Duration(const Duration& d) = default; +#endif + Duration& operator=(const Duration& d) = default; + // Compound assignment operators. Duration& operator+=(Duration d); Duration& operator-=(Duration d); @@ -162,6 +188,11 @@ class Duration { Duration& operator*=(float r) { return *this *= static_cast<double>(r); } Duration& operator/=(float r) { return *this /= static_cast<double>(r); } + template <typename H> + friend H AbslHashValue(H h, Duration d) { + return H::combine(std::move(h), d.rep_hi_, d.rep_lo_); + } + private: friend constexpr int64_t time_internal::GetRepHi(Duration d); friend constexpr uint32_t time_internal::GetRepLo(Duration d); @@ -296,6 +327,42 @@ Duration Floor(Duration d, Duration unit); // absl::Duration c = absl::Ceil(d, absl::Microseconds(1)); // 123457us Duration Ceil(Duration d, Duration unit); +// InfiniteDuration() +// +// Returns an infinite `Duration`. To get a `Duration` representing negative +// infinity, use `-InfiniteDuration()`. +// +// Duration arithmetic overflows to +/- infinity and saturates. In general, +// arithmetic with `Duration` infinities is similar to IEEE 754 infinities +// except where IEEE 754 NaN would be involved, in which case +/- +// `InfiniteDuration()` is used in place of a "nan" Duration. +// +// Examples: +// +// constexpr absl::Duration inf = absl::InfiniteDuration(); +// const absl::Duration d = ... any finite duration ... +// +// inf == inf + inf +// inf == inf + d +// inf == inf - inf +// -inf == d - inf +// +// inf == d * 1e100 +// inf == inf / 2 +// 0 == d / inf +// INT64_MAX == inf / d +// +// d < inf +// -inf < d +// +// // Division by zero returns infinity, or INT64_MIN/MAX where appropriate. +// inf == d / 0 +// INT64_MAX == d / absl::ZeroDuration() +// +// The examples involving the `/` operator above also apply to `IDivDuration()` +// and `FDivDuration()`. +constexpr Duration InfiniteDuration(); + // Nanoseconds() // Microseconds() // Milliseconds() @@ -306,11 +373,11 @@ Duration Ceil(Duration d, Duration unit); // Factory functions for constructing `Duration` values from an integral number // of the unit indicated by the factory function's name. // -// Note: no "Days()" factory function exists because "a day" is ambiguous. Civil -// days are not always 24 hours long, and a 24-hour duration often does not -// correspond with a civil day. If a 24-hour duration is needed, use -// `absl::Hours(24)`. -// +// Note: no "Days()" factory function exists because "a day" is ambiguous. +// Civil days are not always 24 hours long, and a 24-hour duration often does +// not correspond with a civil day. If a 24-hour duration is needed, use +// `absl::Hours(24)`. (If you actually want a civil day, use absl::CivilDay +// from civil_time.h.) // // Example: // @@ -329,6 +396,7 @@ constexpr Duration Hours(int64_t n); // factories, which should be preferred. // // Example: +// // auto a = absl::Seconds(1.5); // OK // auto b = absl::Milliseconds(1500); // BETTER template <typename T, time_internal::EnableIfFloat<T> = 0> @@ -345,7 +413,15 @@ Duration Milliseconds(T n) { } template <typename T, time_internal::EnableIfFloat<T> = 0> Duration Seconds(T n) { - return n * Seconds(1); + if (n >= 0) { // Note: `NaN >= 0` is false. + if (n >= (std::numeric_limits<int64_t>::max)()) return InfiniteDuration(); + return time_internal::MakePosDoubleDuration(n); + } else { + if (std::isnan(n)) + return std::signbit(n) ? -InfiniteDuration() : InfiniteDuration(); + if (n <= (std::numeric_limits<int64_t>::min)()) return -InfiniteDuration(); + return -time_internal::MakePosDoubleDuration(-n); + } } template <typename T, time_internal::EnableIfFloat<T> = 0> Duration Minutes(T n) { @@ -440,42 +516,9 @@ std::chrono::seconds ToChronoSeconds(Duration d); std::chrono::minutes ToChronoMinutes(Duration d); std::chrono::hours ToChronoHours(Duration d); -// InfiniteDuration() -// -// Returns an infinite `Duration`. To get a `Duration` representing negative -// infinity, use `-InfiniteDuration()`. -// -// Duration arithmetic overflows to +/- infinity and saturates. In general, -// arithmetic with `Duration` infinities is similar to IEEE 754 infinities -// except where IEEE 754 NaN would be involved, in which case +/- -// `InfiniteDuration()` is used in place of a "nan" Duration. -// -// Examples: -// -// constexpr absl::Duration inf = absl::InfiniteDuration(); -// const absl::Duration d = ... any finite duration ... -// -// inf == inf + inf -// inf == inf + d -// inf == inf - inf -// -inf == d - inf -// -// inf == d * 1e100 -// inf == inf / 2 -// 0 == d / inf -// INT64_MAX == inf / d -// -// // Division by zero returns infinity, or INT64_MIN/MAX where appropriate. -// inf == d / 0 -// INT64_MAX == d / absl::ZeroDuration() -// -// The examples involving the `/` operator above also apply to `IDivDuration()` -// and `FDivDuration()`. -constexpr Duration InfiniteDuration(); - // FormatDuration() // -// Returns a std::string representing the duration in the form "72h3m0.5s". +// Returns a string representing the duration in the form "72h3m0.5s". // Returns "inf" or "-inf" for +/- `InfiniteDuration()`. std::string FormatDuration(Duration d); @@ -486,19 +529,16 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) { // ParseDuration() // -// Parses a duration std::string consisting of a possibly signed sequence of +// Parses a duration string consisting of a possibly signed sequence of // decimal numbers, each with an optional fractional part and a unit // suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h". // Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as -// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. +// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. bool ParseDuration(const std::string& dur_string, Duration* d); -// ParseFlag() -// +// Support for flag values of type Duration. Duration flags must be specified +// in a format that is valid input for absl::ParseDuration(). bool ParseFlag(const std::string& text, Duration* dst, std::string* error); - -// UnparseFlag() -// std::string UnparseFlag(Duration d); // Time @@ -534,7 +574,7 @@ std::string UnparseFlag(Duration d); // // `absl::Time` uses a resolution that is high enough to avoid loss in // precision, and a range that is wide enough to avoid overflow, when -// converting between tick counts in most Google time scales (i.e., precision +// converting between tick counts in most Google time scales (i.e., resolution // of at least one nanosecond, and range +/-100 billion years). Conversions // between the time scales are performed by truncating (towards negative // infinity) to the nearest representable point. @@ -544,7 +584,6 @@ std::string UnparseFlag(Duration d); // absl::Time t1 = ...; // absl::Time t2 = t1 + absl::Minutes(2); // absl::Duration d = t2 - t1; // == absl::Minutes(2) -// absl::Time::Breakdown bd = t1.In(absl::LocalTimeZone()); // class Time { public: @@ -559,7 +598,11 @@ class Time { // absl::Time t = absl::Now(); // absl::Time t = absl::TimeFromTimeval(tv); // absl::Time t = absl::InfinitePast(); - constexpr Time() {} + constexpr Time() = default; + + // Copyable. + constexpr Time(const Time& t) = default; + Time& operator=(const Time& t) = default; // Assignment operators. Time& operator+=(Duration d) { @@ -578,7 +621,10 @@ class Time { // intended to represent an instant in time. So, rather than passing // a `Time::Breakdown` to a function, pass an `absl::Time` and an // `absl::TimeZone`. - struct Breakdown { + // + // Deprecated. Use `absl::TimeZone::CivilInfo`. + struct + Breakdown { int64_t year; // year (e.g., 2013) int month; // month of year [1:12] int day; // day of month [1:31] @@ -602,8 +648,15 @@ class Time { // Time::In() // // Returns the breakdown of this instant in the given TimeZone. + // + // Deprecated. Use `absl::TimeZone::At(Time)`. Breakdown In(TimeZone tz) const; + template <typename H> + friend H AbslHashValue(H h, Time t) { + return H::combine(std::move(h), t.rep_); + } + private: friend constexpr Time time_internal::FromUnixDuration(Duration d); friend constexpr Duration time_internal::ToUnixDuration(Time t); @@ -651,7 +704,7 @@ constexpr Time UniversalEpoch() { // Returns an `absl::Time` that is infinitely far in the future. constexpr Time InfiniteFuture() { return Time( - time_internal::MakeDuration(std::numeric_limits<int64_t>::max(), ~0U)); + time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U)); } // InfinitePast() @@ -659,125 +712,9 @@ constexpr Time InfiniteFuture() { // Returns an `absl::Time` that is infinitely far in the past. constexpr Time InfinitePast() { return Time( - time_internal::MakeDuration(std::numeric_limits<int64_t>::min(), ~0U)); + time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U)); } -// TimeConversion -// -// An `absl::TimeConversion` represents the conversion of year, month, day, -// hour, minute, and second values (i.e., a civil time), in a particular -// `absl::TimeZone`, to a time instant (an absolute time), as returned by -// `absl::ConvertDateTime()`. (Subseconds must be handled separately.) -// -// It is possible, though, for a caller to try to convert values that -// do not represent an actual or unique instant in time (due to a shift -// in UTC offset in the `absl::TimeZone`, which results in a discontinuity in -// the civil-time components). For example, a daylight-saving-time -// transition skips or repeats civil times---in the United States, March -// 13, 2011 02:15 never occurred, while November 6, 2011 01:15 occurred -// twice---so requests for such times are not well-defined. -// -// To account for these possibilities, `absl::TimeConversion` is richer -// than just a single `absl::Time`. When the civil time is skipped or -// repeated, `absl::ConvertDateTime()` returns times calculated using the -// pre-transition and post-transition UTC offsets, plus the transition -// time itself. -// -// Examples: -// -// absl::TimeZone lax; -// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { ... } -// -// // A unique civil time -// absl::TimeConversion jan01 = -// absl::ConvertDateTime(2011, 1, 1, 0, 0, 0, lax); -// // jan01.kind == TimeConversion::UNIQUE -// // jan01.pre is 2011/01/01 00:00:00 -0800 -// // jan01.trans is 2011/01/01 00:00:00 -0800 -// // jan01.post is 2011/01/01 00:00:00 -0800 -// -// // A Spring DST transition, when there is a gap in civil time -// absl::TimeConversion mar13 = -// absl::ConvertDateTime(2011, 3, 13, 2, 15, 0, lax); -// // mar13.kind == TimeConversion::SKIPPED -// // mar13.pre is 2011/03/13 03:15:00 -0700 -// // mar13.trans is 2011/03/13 03:00:00 -0700 -// // mar13.post is 2011/03/13 01:15:00 -0800 -// -// // A Fall DST transition, when civil times are repeated -// absl::TimeConversion nov06 = -// absl::ConvertDateTime(2011, 11, 6, 1, 15, 0, lax); -// // nov06.kind == TimeConversion::REPEATED -// // nov06.pre is 2011/11/06 01:15:00 -0700 -// // nov06.trans is 2011/11/06 01:00:00 -0800 -// // nov06.post is 2011/11/06 01:15:00 -0800 -// -// The input month, day, hour, minute, and second values can also be -// outside of their valid ranges, in which case they will be "normalized" -// during the conversion. -// -// Example: -// -// // "October 32" normalizes to "November 1". -// absl::TimeZone tz = absl::LocalTimeZone(); -// absl::TimeConversion tc = -// absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, tz); -// // tc.kind == TimeConversion::UNIQUE && tc.normalized == true -// // tc.pre.In(tz).month == 11 && tc.pre.In(tz).day == 1 -struct TimeConversion { - Time pre; // time calculated using the pre-transition offset - Time trans; // when the civil-time discontinuity occurred - Time post; // time calculated using the post-transition offset - - enum Kind { - UNIQUE, // the civil time was singular (pre == trans == post) - SKIPPED, // the civil time did not exist - REPEATED, // the civil time was ambiguous - }; - Kind kind; - - bool normalized; // input values were outside their valid ranges -}; - -// ConvertDateTime() -// -// The full generality of a civil time to absl::Time conversion. -TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, - int min, int sec, TimeZone tz); - -// FromDateTime() -// -// A convenience wrapper for `absl::ConvertDateTime()` that simply returns the -// "pre" `absl::Time`. That is, the unique result, or the instant that -// is correct using the pre-transition offset (as if the transition -// never happened). This is typically the answer that humans expected when -// faced with non-unique times, such as near daylight-saving time transitions. -// -// Example: -// -// absl::TimeZone seattle; -// if (!absl::LoadTimeZone("America/Los_Angeles", &seattle)) { ... } -// absl::Time t = absl::FromDateTime(2017, 9, 26, 9, 30, 0, seattle); -Time FromDateTime(int64_t year, int mon, int day, int hour, int min, int sec, - TimeZone tz); - -// FromTM() -// -// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and -// `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3) -// for a description of the expected values of the tm fields. IFF the indicated -// time instant is not unique (see `absl::ConvertDateTime()` above), the -// `tm_isdst` field is consulted to select the desired instant (`tm_isdst` > 0 -// means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0 means use the default -// like `absl::FromDateTime()`). -Time FromTM(const struct tm& tm, TimeZone tz); - -// ToTM() -// -// Converts the given `absl::Time` to a struct tm using the given time zone. -// See ctime(3) for a description of the values of the tm fields. -struct tm ToTM(Time t, TimeZone tz); - // FromUnixNanos() // FromUnixMicros() // FromUnixMillis() @@ -862,14 +799,390 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp); // // tp == std::chrono::system_clock::from_time_t(123); std::chrono::system_clock::time_point ToChronoTime(Time); +// Support for flag values of type Time. Time flags must be specified in a +// format that matches absl::RFC3339_full. For example: +// +// --start_time=2016-01-02T03:04:05.678+08:00 +// +// Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. +// +// Additionally, if you'd like to specify a time as a count of +// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag +// and add that duration to absl::UnixEpoch() to get an absl::Time. +bool ParseFlag(const std::string& text, Time* t, std::string* error); +std::string UnparseFlag(Time t); + +// TimeZone +// +// The `absl::TimeZone` is an opaque, small, value-type class representing a +// geo-political region within which particular rules are used for converting +// between absolute and civil times (see https://git.io/v59Ly). `absl::TimeZone` +// values are named using the TZ identifiers from the IANA Time Zone Database, +// such as "America/Los_Angeles" or "Australia/Sydney". `absl::TimeZone` values +// are created from factory functions such as `absl::LoadTimeZone()`. Note: +// strings like "PST" and "EDT" are not valid TZ identifiers. Prefer to pass by +// value rather than const reference. +// +// For more on the fundamental concepts of time zones, absolute times, and civil +// times, see https://github.com/google/cctz#fundamental-concepts +// +// Examples: +// +// absl::TimeZone utc = absl::UTCTimeZone(); +// absl::TimeZone pst = absl::FixedTimeZone(-8 * 60 * 60); +// absl::TimeZone loc = absl::LocalTimeZone(); +// absl::TimeZone lax; +// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { +// // handle error case +// } +// +// See also: +// - https://github.com/google/cctz +// - http://www.iana.org/time-zones +// - http://en.wikipedia.org/wiki/Zoneinfo +class TimeZone { + public: + explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {} + TimeZone() = default; // UTC, but prefer UTCTimeZone() to be explicit. + + // Copyable. + TimeZone(const TimeZone&) = default; + TimeZone& operator=(const TimeZone&) = default; + + explicit operator time_internal::cctz::time_zone() const { return cz_; } + + std::string name() const { return cz_.name(); } + + // TimeZone::CivilInfo + // + // Information about the civil time corresponding to an absolute time. + // This struct is not intended to represent an instant in time. So, rather + // than passing a `TimeZone::CivilInfo` to a function, pass an `absl::Time` + // and an `absl::TimeZone`. + struct CivilInfo { + CivilSecond cs; + Duration subsecond; + + // Note: The following fields exist for backward compatibility + // with older APIs. Accessing these fields directly is a sign of + // imprudent logic in the calling code. Modern time-related code + // should only access this data indirectly by way of FormatTime(). + // These fields are undefined for InfiniteFuture() and InfinitePast(). + int offset; // seconds east of UTC + bool is_dst; // is offset non-standard? + const char* zone_abbr; // time-zone abbreviation (e.g., "PST") + }; + + // TimeZone::At(Time) + // + // Returns the civil time for this TimeZone at a certain `absl::Time`. + // If the input time is infinite, the output civil second will be set to + // CivilSecond::max() or min(), and the subsecond will be infinite. + // + // Example: + // + // const auto epoch = lax.At(absl::UnixEpoch()); + // // epoch.cs == 1969-12-31 16:00:00 + // // epoch.subsecond == absl::ZeroDuration() + // // epoch.offset == -28800 + // // epoch.is_dst == false + // // epoch.abbr == "PST" + CivilInfo At(Time t) const; + + // TimeZone::TimeInfo + // + // Information about the absolute times corresponding to a civil time. + // (Subseconds must be handled separately.) + // + // It is possible for a caller to pass a civil-time value that does + // not represent an actual or unique instant in time (due to a shift + // in UTC offset in the TimeZone, which results in a discontinuity in + // the civil-time components). For example, a daylight-saving-time + // transition skips or repeats civil times---in the United States, + // March 13, 2011 02:15 never occurred, while November 6, 2011 01:15 + // occurred twice---so requests for such times are not well-defined. + // To account for these possibilities, `absl::TimeZone::TimeInfo` is + // richer than just a single `absl::Time`. + struct TimeInfo { + enum CivilKind { + UNIQUE, // the civil time was singular (pre == trans == post) + SKIPPED, // the civil time did not exist (pre >= trans > post) + REPEATED, // the civil time was ambiguous (pre < trans <= post) + } kind; + Time pre; // time calculated using the pre-transition offset + Time trans; // when the civil-time discontinuity occurred + Time post; // time calculated using the post-transition offset + }; + + // TimeZone::At(CivilSecond) + // + // Returns an `absl::TimeInfo` containing the absolute time(s) for this + // TimeZone at an `absl::CivilSecond`. When the civil time is skipped or + // repeated, returns times calculated using the pre-transition and post- + // transition UTC offsets, plus the transition time itself. + // + // Examples: + // + // // A unique civil time + // const auto jan01 = lax.At(absl::CivilSecond(2011, 1, 1, 0, 0, 0)); + // // jan01.kind == TimeZone::TimeInfo::UNIQUE + // // jan01.pre is 2011-01-01 00:00:00 -0800 + // // jan01.trans is 2011-01-01 00:00:00 -0800 + // // jan01.post is 2011-01-01 00:00:00 -0800 + // + // // A Spring DST transition, when there is a gap in civil time + // const auto mar13 = lax.At(absl::CivilSecond(2011, 3, 13, 2, 15, 0)); + // // mar13.kind == TimeZone::TimeInfo::SKIPPED + // // mar13.pre is 2011-03-13 03:15:00 -0700 + // // mar13.trans is 2011-03-13 03:00:00 -0700 + // // mar13.post is 2011-03-13 01:15:00 -0800 + // + // // A Fall DST transition, when civil times are repeated + // const auto nov06 = lax.At(absl::CivilSecond(2011, 11, 6, 1, 15, 0)); + // // nov06.kind == TimeZone::TimeInfo::REPEATED + // // nov06.pre is 2011-11-06 01:15:00 -0700 + // // nov06.trans is 2011-11-06 01:00:00 -0800 + // // nov06.post is 2011-11-06 01:15:00 -0800 + TimeInfo At(CivilSecond ct) const; + + // TimeZone::NextTransition() + // TimeZone::PrevTransition() + // + // Finds the time of the next/previous offset change in this time zone. + // + // By definition, `NextTransition(t, &trans)` returns false when `t` is + // `InfiniteFuture()`, and `PrevTransition(t, &trans)` returns false + // when `t` is `InfinitePast()`. If the zone has no transitions, the + // result will also be false no matter what the argument. + // + // Otherwise, when `t` is `InfinitePast()`, `NextTransition(t, &trans)` + // returns true and sets `trans` to the first recorded transition. Chains + // of calls to `NextTransition()/PrevTransition()` will eventually return + // false, but it is unspecified exactly when `NextTransition(t, &trans)` + // jumps to false, or what time is set by `PrevTransition(t, &trans)` for + // a very distant `t`. + // + // Note: Enumeration of time-zone transitions is for informational purposes + // only. Modern time-related code should not care about when offset changes + // occur. + // + // Example: + // absl::TimeZone nyc; + // if (!absl::LoadTimeZone("America/New_York", &nyc)) { ... } + // const auto now = absl::Now(); + // auto t = absl::InfinitePast(); + // absl::TimeZone::CivilTransition trans; + // while (t <= now && nyc.NextTransition(t, &trans)) { + // // transition: trans.from -> trans.to + // t = nyc.At(trans.to).trans; + // } + struct CivilTransition { + CivilSecond from; // the civil time we jump from + CivilSecond to; // the civil time we jump to + }; + bool NextTransition(Time t, CivilTransition* trans) const; + bool PrevTransition(Time t, CivilTransition* trans) const; + + template <typename H> + friend H AbslHashValue(H h, TimeZone tz) { + return H::combine(std::move(h), tz.cz_); + } + + private: + friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; } + friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; } + friend std::ostream& operator<<(std::ostream& os, TimeZone tz) { + return os << tz.name(); + } + + time_internal::cctz::time_zone cz_; +}; + +// LoadTimeZone() +// +// Loads the named zone. May perform I/O on the initial load of the named +// zone. If the name is invalid, or some other kind of error occurs, returns +// `false` and `*tz` is set to the UTC time zone. +inline bool LoadTimeZone(const std::string& name, TimeZone* tz) { + if (name == "localtime") { + *tz = TimeZone(time_internal::cctz::local_time_zone()); + return true; + } + time_internal::cctz::time_zone cz; + const bool b = time_internal::cctz::load_time_zone(name, &cz); + *tz = TimeZone(cz); + return b; +} + +// FixedTimeZone() +// +// Returns a TimeZone that is a fixed offset (seconds east) from UTC. +// Note: If the absolute value of the offset is greater than 24 hours +// you'll get UTC (i.e., no offset) instead. +inline TimeZone FixedTimeZone(int seconds) { + return TimeZone( + time_internal::cctz::fixed_time_zone(std::chrono::seconds(seconds))); +} + +// UTCTimeZone() +// +// Convenience method returning the UTC time zone. +inline TimeZone UTCTimeZone() { + return TimeZone(time_internal::cctz::utc_time_zone()); +} + +// LocalTimeZone() +// +// Convenience method returning the local time zone, or UTC if there is +// no configured local zone. Warning: Be wary of using LocalTimeZone(), +// and particularly so in a server process, as the zone configured for the +// local machine should be irrelevant. Prefer an explicit zone name. +inline TimeZone LocalTimeZone() { + return TimeZone(time_internal::cctz::local_time_zone()); +} + +// ToCivilSecond() +// ToCivilMinute() +// ToCivilHour() +// ToCivilDay() +// ToCivilMonth() +// ToCivilYear() +// +// Helpers for TimeZone::At(Time) to return particularly aligned civil times. +// +// Example: +// +// absl::Time t = ...; +// absl::TimeZone tz = ...; +// const auto cd = absl::ToCivilDay(t, tz); +inline CivilSecond ToCivilSecond(Time t, TimeZone tz) { + return tz.At(t).cs; // already a CivilSecond +} +inline CivilMinute ToCivilMinute(Time t, TimeZone tz) { + return CivilMinute(tz.At(t).cs); +} +inline CivilHour ToCivilHour(Time t, TimeZone tz) { + return CivilHour(tz.At(t).cs); +} +inline CivilDay ToCivilDay(Time t, TimeZone tz) { + return CivilDay(tz.At(t).cs); +} +inline CivilMonth ToCivilMonth(Time t, TimeZone tz) { + return CivilMonth(tz.At(t).cs); +} +inline CivilYear ToCivilYear(Time t, TimeZone tz) { + return CivilYear(tz.At(t).cs); +} + +// FromCivil() +// +// Helper for TimeZone::At(CivilSecond) that provides "order-preserving +// semantics." If the civil time maps to a unique time, that time is +// returned. If the civil time is repeated in the given time zone, the +// time using the pre-transition offset is returned. Otherwise, the +// civil time is skipped in the given time zone, and the transition time +// is returned. This means that for any two civil times, ct1 and ct2, +// (ct1 < ct2) => (FromCivil(ct1) <= FromCivil(ct2)), the equal case +// being when two non-existent civil times map to the same transition time. +// +// Note: Accepts civil times of any alignment. +inline Time FromCivil(CivilSecond ct, TimeZone tz) { + const auto ti = tz.At(ct); + if (ti.kind == TimeZone::TimeInfo::SKIPPED) return ti.trans; + return ti.pre; +} + +// TimeConversion +// +// An `absl::TimeConversion` represents the conversion of year, month, day, +// hour, minute, and second values (i.e., a civil time), in a particular +// `absl::TimeZone`, to a time instant (an absolute time), as returned by +// `absl::ConvertDateTime()`. Lecacy version of `absl::TimeZone::TimeInfo`. +// +// Deprecated. Use `absl::TimeZone::TimeInfo`. +struct + TimeConversion { + Time pre; // time calculated using the pre-transition offset + Time trans; // when the civil-time discontinuity occurred + Time post; // time calculated using the post-transition offset + + enum Kind { + UNIQUE, // the civil time was singular (pre == trans == post) + SKIPPED, // the civil time did not exist + REPEATED, // the civil time was ambiguous + }; + Kind kind; + + bool normalized; // input values were outside their valid ranges +}; + +// ConvertDateTime() +// +// Legacy version of `absl::TimeZone::At(absl::CivilSecond)` that takes +// the civil time as six, separate values (YMDHMS). +// +// The input month, day, hour, minute, and second values can be outside +// of their valid ranges, in which case they will be "normalized" during +// the conversion. +// +// Example: +// +// // "October 32" normalizes to "November 1". +// absl::TimeConversion tc = +// absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, lax); +// // tc.kind == TimeConversion::UNIQUE && tc.normalized == true +// // absl::ToCivilDay(tc.pre, tz).month() == 11 +// // absl::ToCivilDay(tc.pre, tz).day() == 1 +// +// Deprecated. Use `absl::TimeZone::At(CivilSecond)`. +TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, + int min, int sec, TimeZone tz); + +// FromDateTime() +// +// A convenience wrapper for `absl::ConvertDateTime()` that simply returns +// the "pre" `absl::Time`. That is, the unique result, or the instant that +// is correct using the pre-transition offset (as if the transition never +// happened). +// +// Example: +// +// absl::Time t = absl::FromDateTime(2017, 9, 26, 9, 30, 0, lax); +// // t = 2017-09-26 09:30:00 -0700 +// +// Deprecated. Use `absl::TimeZone::At(CivilSecond).pre`. +inline Time FromDateTime(int64_t year, int mon, int day, int hour, + int min, int sec, TimeZone tz) { + return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre; +} + +// FromTM() +// +// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and +// `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3) +// for a description of the expected values of the tm fields. If the indicated +// time instant is not unique (see `absl::TimeZone::At(absl::CivilSecond)` +// above), the `tm_isdst` field is consulted to select the desired instant +// (`tm_isdst` > 0 means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0 +// means use the post-transition offset). +Time FromTM(const struct tm& tm, TimeZone tz); + +// ToTM() +// +// Converts the given `absl::Time` to a struct tm using the given time zone. +// See ctime(3) for a description of the values of the tm fields. +struct tm ToTM(Time t, TimeZone tz); + // RFC3339_full // RFC3339_sec // // FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings, // with trailing zeros trimmed or with fractional seconds omitted altogether. // -// Note that RFC3339_sec[] matches an ISO 8601 extended format for date -// and time with UTC offset. +// Note that RFC3339_sec[] matches an ISO 8601 extended format for date and +// time with UTC offset. Also note the use of "%Y": RFC3339 mandates that +// years have exactly four digits, but we allow them to take their natural +// width. extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez @@ -883,7 +1196,7 @@ extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // FormatTime() // // Formats the given `absl::Time` in the `absl::TimeZone` according to the -// provided format std::string. Uses strftime()-like formatting options, with +// provided format string. Uses strftime()-like formatting options, with // the following extensions: // // - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) @@ -906,17 +1219,15 @@ extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // // Example: // -// absl::TimeZone lax; -// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { ... } -// absl::Time t = absl::FromDateTime(2013, 1, 2, 3, 4, 5, lax); -// -// std::string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05" +// absl::CivilSecond cs(2013, 1, 2, 3, 4, 5); +// absl::Time t = absl::FromCivil(cs, lax); +// string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05" // f = absl::FormatTime("%H:%M:%E3S", t, lax); // "03:04:05.000" // // Note: If the given `absl::Time` is `absl::InfiniteFuture()`, the returned -// std::string will be exactly "infinite-future". If the given `absl::Time` is -// `absl::InfinitePast()`, the returned std::string will be exactly "infinite-past". -// In both cases the given format std::string and `absl::TimeZone` are ignored. +// string will be exactly "infinite-future". If the given `absl::Time` is +// `absl::InfinitePast()`, the returned string will be exactly "infinite-past". +// In both cases the given format string and `absl::TimeZone` are ignored. // std::string FormatTime(const std::string& format, Time t, TimeZone tz); @@ -933,7 +1244,7 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // ParseTime() // -// Parses an input std::string according to the provided format std::string and +// Parses an input string according to the provided format string and // returns the corresponding `absl::Time`. Uses strftime()-like formatting // options, with the same extensions as FormatTime(), but with the // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez @@ -947,7 +1258,7 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // // "1970-01-01 00:00:00.0 +0000" // -// For example, parsing a std::string of "15:45" (%H:%M) will return an absl::Time +// For example, parsing a string of "15:45" (%H:%M) will return an absl::Time // that represents "1970-01-01 15:45:00.0 +0000". // // Note that since ParseTime() returns time instants, it makes the most sense @@ -960,7 +1271,7 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // in the conversion. // // Date and time fields that are out-of-range will be treated as errors -// rather than normalizing them like `absl::FromDateTime()` does. For example, +// rather than normalizing them like `absl::CivilSecond` does. For example, // it is an error to parse the date "Oct 32, 2013" because 32 is out of range. // // A leap second of ":60" is normalized to ":00" of the following minute @@ -974,130 +1285,24 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // Errors are indicated by returning false and assigning an error message // to the "err" out param if it is non-null. // -// Note: If the input std::string is exactly "infinite-future", the returned +// Note: If the input string is exactly "infinite-future", the returned // `absl::Time` will be `absl::InfiniteFuture()` and `true` will be returned. -// If the input std::string is "infinite-past", the returned `absl::Time` will be +// If the input string is "infinite-past", the returned `absl::Time` will be // `absl::InfinitePast()` and `true` will be returned. // bool ParseTime(const std::string& format, const std::string& input, Time* time, std::string* err); -// Like ParseTime() above, but if the format std::string does not contain a UTC +// Like ParseTime() above, but if the format string does not contain a UTC // offset specification (%z/%Ez/%E*z) then the input is interpreted in the // given TimeZone. This means that the input, by itself, does not identify a // unique instant. Being time-zone dependent, it also admits the possibility // of ambiguity or non-existence, in which case the "pre" time (as defined -// for ConvertDateTime()) is returned. For these reasons we recommend that +// by TimeZone::TimeInfo) is returned. For these reasons we recommend that // all date/time strings include a UTC offset so they're context independent. bool ParseTime(const std::string& format, const std::string& input, TimeZone tz, Time* time, std::string* err); -// ParseFlag() -// UnparseFlag() -// -// Support for flag values of type Time. Time flags must be specified in a -// format that matches absl::RFC3339_full. For example: -// -// --start_time=2016-01-02T03:04:05.678+08:00 -// -// Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. -// -// Additionally, if you'd like to specify a time as a count of -// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag -// and add that duration to absl::UnixEpoch() to get an absl::Time. -bool ParseFlag(const std::string& text, Time* t, std::string* error); -std::string UnparseFlag(Time t); - -// TimeZone -// -// The `absl::TimeZone` is an opaque, small, value-type class representing a -// geo-political region within which particular rules are used for converting -// between absolute and civil times (see https://git.io/v59Ly). `absl::TimeZone` -// values are named using the TZ identifiers from the IANA Time Zone Database, -// such as "America/Los_Angeles" or "Australia/Sydney". `absl::TimeZone` values -// are created from factory functions such as `absl::LoadTimeZone()`. Note: -// strings like "PST" and "EDT" are not valid TZ identifiers. Prefer to pass by -// value rather than const reference. -// -// For more on the fundamental concepts of time zones, absolute times, and civil -// times, see https://github.com/google/cctz#fundamental-concepts -// -// Examples: -// -// absl::TimeZone utc = absl::UTCTimeZone(); -// absl::TimeZone pst = absl::FixedTimeZone(-8 * 60 * 60); -// absl::TimeZone loc = absl::LocalTimeZone(); -// absl::TimeZone lax; -// if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { ... } -// -// See also: -// - https://github.com/google/cctz -// - http://www.iana.org/time-zones -// - http://en.wikipedia.org/wiki/Zoneinfo -class TimeZone { - public: - explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {} - TimeZone() = default; // UTC, but prefer UTCTimeZone() to be explicit. - TimeZone(const TimeZone&) = default; - TimeZone& operator=(const TimeZone&) = default; - - explicit operator time_internal::cctz::time_zone() const { return cz_; } - - std::string name() const { return cz_.name(); } - - private: - friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; } - friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; } - friend std::ostream& operator<<(std::ostream& os, TimeZone tz) { - return os << tz.name(); - } - - time_internal::cctz::time_zone cz_; -}; - -// LoadTimeZone() -// -// Loads the named zone. May perform I/O on the initial load of the named -// zone. If the name is invalid, or some other kind of error occurs, returns -// `false` and `*tz` is set to the UTC time zone. -inline bool LoadTimeZone(const std::string& name, TimeZone* tz) { - if (name == "localtime") { - *tz = TimeZone(time_internal::cctz::local_time_zone()); - return true; - } - time_internal::cctz::time_zone cz; - const bool b = time_internal::cctz::load_time_zone(name, &cz); - *tz = TimeZone(cz); - return b; -} - -// FixedTimeZone() -// -// Returns a TimeZone that is a fixed offset (seconds east) from UTC. -// Note: If the absolute value of the offset is greater than 24 hours -// you'll get UTC (i.e., no offset) instead. -inline TimeZone FixedTimeZone(int seconds) { - return TimeZone( - time_internal::cctz::fixed_time_zone(std::chrono::seconds(seconds))); -} - -// UTCTimeZone() -// -// Convenience method returning the UTC time zone. -inline TimeZone UTCTimeZone() { - return TimeZone(time_internal::cctz::utc_time_zone()); -} - -// LocalTimeZone() -// -// Convenience method returning the local time zone, or UTC if there is -// no configured local zone. Warning: Be wary of using LocalTimeZone(), -// and particularly so in a server process, as the zone configured for the -// local machine should be irrelevant. Prefer an explicit zone name. -inline TimeZone LocalTimeZone() { - return TimeZone(time_internal::cctz::local_time_zone()); -} - // ============================================================================ // Implementation Details Follow // ============================================================================ @@ -1115,6 +1320,18 @@ constexpr Duration MakeDuration(int64_t hi, int64_t lo) { return MakeDuration(hi, static_cast<uint32_t>(lo)); } +// Make a Duration value from a floating-point number, as long as that number +// is in the range [ 0 .. numeric_limits<int64_t>::max ), that is, as long as +// it's positive and can be converted to int64_t without risk of UB. +inline Duration MakePosDoubleDuration(double n) { + const int64_t int_secs = static_cast<int64_t>(n); + const uint32_t ticks = + static_cast<uint32_t>((n - int_secs) * kTicksPerSecond + 0.5); + return ticks < kTicksPerSecond + ? MakeDuration(int_secs, ticks) + : MakeDuration(int_secs + 1, ticks - kTicksPerSecond); +} + // Creates a normalized Duration from an almost-normalized (sec,ticks) // pair. sec may be positive or negative. ticks must be in the range // -kTicksPerSecond < *ticks < kTicksPerSecond. If ticks is negative it @@ -1123,17 +1340,20 @@ constexpr Duration MakeNormalizedDuration(int64_t sec, int64_t ticks) { return (ticks < 0) ? MakeDuration(sec - 1, ticks + kTicksPerSecond) : MakeDuration(sec, ticks); } + // Provide access to the Duration representation. constexpr int64_t GetRepHi(Duration d) { return d.rep_hi_; } constexpr uint32_t GetRepLo(Duration d) { return d.rep_lo_; } + +// Returns true iff d is positive or negative infinity. constexpr bool IsInfiniteDuration(Duration d) { return GetRepLo(d) == ~0U; } // Returns an infinite Duration with the opposite sign. // REQUIRES: IsInfiniteDuration(d) constexpr Duration OppositeInfinity(Duration d) { return GetRepHi(d) < 0 - ? MakeDuration(std::numeric_limits<int64_t>::max(), ~0U) - : MakeDuration(std::numeric_limits<int64_t>::min(), ~0U); + ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U) + : MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U); } // Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow. @@ -1158,14 +1378,14 @@ constexpr Duration FromInt64(int64_t v, std::ratio<1, N>) { v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N); } constexpr Duration FromInt64(int64_t v, std::ratio<60>) { - return (v <= std::numeric_limits<int64_t>::max() / 60 && - v >= std::numeric_limits<int64_t>::min() / 60) + return (v <= (std::numeric_limits<int64_t>::max)() / 60 && + v >= (std::numeric_limits<int64_t>::min)() / 60) ? MakeDuration(v * 60) : v > 0 ? InfiniteDuration() : -InfiniteDuration(); } constexpr Duration FromInt64(int64_t v, std::ratio<3600>) { - return (v <= std::numeric_limits<int64_t>::max() / 3600 && - v >= std::numeric_limits<int64_t>::min() / 3600) + return (v <= (std::numeric_limits<int64_t>::max)() / 3600 && + v >= (std::numeric_limits<int64_t>::min)() / 3600) ? MakeDuration(v * 3600) : v > 0 ? InfiniteDuration() : -InfiniteDuration(); } @@ -1224,8 +1444,8 @@ T ToChronoDuration(Duration d) { if (time_internal::IsInfiniteDuration(d)) return d < ZeroDuration() ? T::min() : T::max(); const auto v = ToInt64(d, Period{}); - if (v > std::numeric_limits<Rep>::max()) return T::max(); - if (v < std::numeric_limits<Rep>::min()) return T::min(); + if (v > (std::numeric_limits<Rep>::max)()) return T::max(); + if (v < (std::numeric_limits<Rep>::min)()) return T::min(); return T{v}; } @@ -1252,7 +1472,8 @@ constexpr Duration Hours(int64_t n) { constexpr bool operator<(Duration lhs, Duration rhs) { return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs) ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs) - : time_internal::GetRepHi(lhs) == std::numeric_limits<int64_t>::min() + : time_internal::GetRepHi(lhs) == + (std::numeric_limits<int64_t>::min)() ? time_internal::GetRepLo(lhs) + 1 < time_internal::GetRepLo(rhs) + 1 : time_internal::GetRepLo(lhs) < @@ -1277,7 +1498,8 @@ constexpr Duration operator-(Duration d) { // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1 // is safe). return time_internal::GetRepLo(d) == 0 - ? time_internal::GetRepHi(d) == std::numeric_limits<int64_t>::min() + ? time_internal::GetRepHi(d) == + (std::numeric_limits<int64_t>::min)() ? InfiniteDuration() : time_internal::MakeDuration(-time_internal::GetRepHi(d)) : time_internal::IsInfiniteDuration(d) @@ -1290,7 +1512,8 @@ constexpr Duration operator-(Duration d) { } constexpr Duration InfiniteDuration() { - return time_internal::MakeDuration(std::numeric_limits<int64_t>::max(), ~0U); + return time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), + ~0U); } constexpr Duration FromChrono(const std::chrono::nanoseconds& d) { @@ -1332,7 +1555,7 @@ constexpr Time FromTimeT(time_t t) { return time_internal::FromUnixDuration(Seconds(t)); } -} // inline namespace lts_2018_06_20 +} // inline namespace lts_2018_12_18 } // namespace absl #endif // ABSL_TIME_TIME_H_ diff --git a/absl/time/time_benchmark.cc b/absl/time/time_benchmark.cc index e1009946..9bbed6f8 100644 --- a/absl/time/time_benchmark.cc +++ b/absl/time/time_benchmark.cc @@ -169,32 +169,32 @@ void BM_Time_ToUnixSeconds(benchmark::State& state) { BENCHMARK(BM_Time_ToUnixSeconds); // -// FromDateTime +// FromCivil // -// In each "FromDateTime" benchmark we switch between two YMDhms -// values separated by at least one transition in order to defeat any -// internal caching of previous results (e.g., see time_local_hint_). +// In each "FromCivil" benchmark we switch between two YMDhms values +// separated by at least one transition in order to defeat any internal +// caching of previous results (e.g., see time_local_hint_). // // The "UTC" variants use UTC instead of the Google/local time zone. // The "Day0" variants require normalization of the day of month. // -void BM_Time_FromDateTime_Absl(benchmark::State& state) { +void BM_Time_FromCivil_Absl(benchmark::State& state) { const absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); int i = 0; while (state.KeepRunning()) { if ((i & 1) == 0) { - absl::FromDateTime(2014, 12, 18, 20, 16, 18, tz); + absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz); } else { - absl::FromDateTime(2013, 11, 15, 18, 30, 27, tz); + absl::FromCivil(absl::CivilSecond(2013, 11, 15, 18, 30, 27), tz); } ++i; } } -BENCHMARK(BM_Time_FromDateTime_Absl); +BENCHMARK(BM_Time_FromCivil_Absl); -void BM_Time_FromDateTime_Libc(benchmark::State& state) { +void BM_Time_FromCivil_Libc(benchmark::State& state) { // No timezone support, so just use localtime. int i = 0; while (state.KeepRunning()) { @@ -219,32 +219,32 @@ void BM_Time_FromDateTime_Libc(benchmark::State& state) { ++i; } } -BENCHMARK(BM_Time_FromDateTime_Libc); +BENCHMARK(BM_Time_FromCivil_Libc); -void BM_Time_FromDateTimeUTC_Absl(benchmark::State& state) { +void BM_Time_FromCivilUTC_Absl(benchmark::State& state) { const absl::TimeZone tz = absl::UTCTimeZone(); while (state.KeepRunning()) { - FromDateTime(2014, 12, 18, 20, 16, 18, tz); + absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz); } } -BENCHMARK(BM_Time_FromDateTimeUTC_Absl); +BENCHMARK(BM_Time_FromCivilUTC_Absl); -void BM_Time_FromDateTimeDay0_Absl(benchmark::State& state) { +void BM_Time_FromCivilDay0_Absl(benchmark::State& state) { const absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles"); int i = 0; while (state.KeepRunning()) { if ((i & 1) == 0) { - absl::FromDateTime(2014, 12, 0, 20, 16, 18, tz); + absl::FromCivil(absl::CivilSecond(2014, 12, 0, 20, 16, 18), tz); } else { - absl::FromDateTime(2013, 11, 0, 18, 30, 27, tz); + absl::FromCivil(absl::CivilSecond(2013, 11, 0, 18, 30, 27), tz); } ++i; } } -BENCHMARK(BM_Time_FromDateTimeDay0_Absl); +BENCHMARK(BM_Time_FromCivilDay0_Absl); -void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { +void BM_Time_FromCivilDay0_Libc(benchmark::State& state) { // No timezone support, so just use localtime. int i = 0; while (state.KeepRunning()) { @@ -269,7 +269,7 @@ void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { ++i; } } -BENCHMARK(BM_Time_FromDateTimeDay0_Libc); +BENCHMARK(BM_Time_FromCivilDay0_Libc); // // To/FromTimespec diff --git a/absl/time/time_norm_test.cc b/absl/time/time_norm_test.cc deleted file mode 100644 index 4436242e..00000000 --- a/absl/time/time_norm_test.cc +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// 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 -// -// http://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. - -// This file contains tests for FromDateTime() normalization, which is -// time-zone independent so we just use UTC throughout. - -#include <cstdint> -#include <limits> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/time/internal/test_util.h" -#include "absl/time/time.h" - -namespace { - -TEST(TimeNormCase, SimpleOverflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(2013, 11, 15, 16, 32, 59 + 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 16, 33, 0, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 59 + 1, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 17, 0, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 23 + 1, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 16, 0, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 30 + 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 12, 1, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 12 + 1, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2014, 1, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, SimpleUnderflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = ConvertDateTime(2013, 11, 15, 16, 32, 0 - 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 16, 31, 59, 0, false); - - tc = ConvertDateTime(2013, 11, 15, 16, 0 - 1, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 15, 15, 59, 14, 0, false); - - tc = ConvertDateTime(2013, 11, 15, 0 - 1, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 14, 23, 32, 14, 0, false); - - tc = ConvertDateTime(2013, 11, 1 - 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 10, 31, 16, 32, 14, 0, false); - - tc = ConvertDateTime(2013, 1 - 1, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2012, 12, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, MultipleOverflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::TimeConversion tc = ConvertDateTime(2013, 12, 31, 23, 59, 59 + 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2014, 1, 1, 0, 0, 0, 0, false); -} - -TEST(TimeNormCase, MultipleUnderflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::TimeConversion tc = absl::ConvertDateTime(2014, 1, 1, 0, 0, 0 - 1, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 12, 31, 23, 59, 59, 0, false); -} - -TEST(TimeNormCase, OverflowLimits) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::TimeConversion tc; - absl::Time::Breakdown bd; - - const int kintmax = std::numeric_limits<int>::max(); - tc = absl::ConvertDateTime(0, kintmax, kintmax, kintmax, kintmax, kintmax, - utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 185085715, 11, 27, 12, 21, 7, 0, false); - - const int kintmin = std::numeric_limits<int>::min(); - tc = absl::ConvertDateTime(0, kintmin, kintmin, kintmin, kintmin, kintmin, - utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, -185085717, 10, 31, 10, 37, 52, 0, false); - - const int64_t max_year = std::numeric_limits<int64_t>::max(); - tc = absl::ConvertDateTime(max_year, 12, 31, 23, 59, 59, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - EXPECT_EQ(absl::InfiniteFuture(), tc.pre); - - const int64_t min_year = std::numeric_limits<int64_t>::min(); - tc = absl::ConvertDateTime(min_year, 1, 1, 0, 0, 0, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - EXPECT_EQ(absl::InfinitePast(), tc.pre); -} - -TEST(TimeNormCase, ComplexOverflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - ConvertDateTime(2013, 11, 15, 16, 32, 14 + 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2017, 10, 14, 14, 5, 23, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 32 + 1234567, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2016, 3, 22, 0, 39, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16 + 123456, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2027, 12, 16, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15 + 1234, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2017, 4, 2, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11 + 123, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2024, 2, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, ComplexUnderflow) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(1999, 3, 0, 0, 0, 0, utc); // year 400 - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1999, 2, 28, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 32, 14 - 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2009, 12, 17, 18, 59, 5, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16, 32 - 1234567, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2011, 7, 12, 8, 25, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15, 16 - 123456, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1999, 10, 16, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11, 15 - 1234, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2010, 6, 30, 16, 32, 14, 0, false); - - tc = absl::ConvertDateTime(2013, 11 - 123, 15, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2003, 8, 15, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, Mishmash) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(2013, 11 - 123, 15 + 1234, 16 - 123456, - 32 + 1234567, 14 - 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1991, 5, 9, 3, 6, 5, 0, false); - - tc = absl::ConvertDateTime(2013, 11 + 123, 15 - 1234, 16 + 123456, - 32 - 1234567, 14 + 123456789, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2036, 5, 24, 5, 58, 23, 0, false); - - // Here is a normalization case we got wrong for a while. Because the - // day is converted to "1" within a 400-year (146097-day) period, we - // didn't need to roll the month and so we didn't mark it as normalized. - tc = absl::ConvertDateTime(2013, 11, -146097 + 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1613, 11, 1, 16, 32, 14, 0, false); - - // Even though the month overflow compensates for the day underflow, - // this should still be marked as normalized. - tc = absl::ConvertDateTime(2013, 11 + 400 * 12, -146097 + 1, 16, 32, 14, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 11, 1, 16, 32, 14, 0, false); -} - -TEST(TimeNormCase, LeapYears) { - const absl::TimeZone utc = absl::UTCTimeZone(); - - absl::TimeConversion tc = - absl::ConvertDateTime(2013, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - absl::Time::Breakdown bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2013, 3, 1, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(2012, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_FALSE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2012, 2, 29, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(2000, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_FALSE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 2000, 2, 29, 0, 0, 0, 0, false); - - tc = absl::ConvertDateTime(1900, 2, 28 + 1, 0, 0, 0, utc); - EXPECT_TRUE(tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - bd = tc.pre.In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, 1900, 3, 1, 0, 0, 0, 0, false); -} - -// Convert all the days from 1970-1-1 to 1970-1-146097 (aka 2369-12-31) -// and check that they normalize to the expected time. 146097 days span -// the 400-year Gregorian cycle used during normalization. -TEST(TimeNormCase, AllTheDays) { - const absl::TimeZone utc = absl::UTCTimeZone(); - absl::Time exp_time = absl::UnixEpoch(); - - for (int day = 1; day <= 146097; ++day) { - absl::TimeConversion tc = absl::ConvertDateTime(1970, 1, day, 0, 0, 0, utc); - EXPECT_EQ(day > 31, tc.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, tc.kind); - EXPECT_EQ(exp_time, tc.pre); - exp_time += absl::Hours(24); - } -} - -} // namespace diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index 4f8f58a6..4d710709 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc @@ -28,6 +28,27 @@ namespace { +#if GTEST_USES_SIMPLE_RE +const char kZoneAbbrRE[] = ".*"; // just punt +#else +const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?"; +#endif + +// This helper is a macro so that failed expectations show up with the +// correct line numbers. +#define EXPECT_CIVIL_INFO(ci, y, m, d, h, min, s, off, isdst) \ + do { \ + EXPECT_EQ(y, ci.cs.year()); \ + EXPECT_EQ(m, ci.cs.month()); \ + EXPECT_EQ(d, ci.cs.day()); \ + EXPECT_EQ(h, ci.cs.hour()); \ + EXPECT_EQ(min, ci.cs.minute()); \ + EXPECT_EQ(s, ci.cs.second()); \ + EXPECT_EQ(off, ci.offset); \ + EXPECT_EQ(isdst, ci.is_dst); \ + EXPECT_THAT(ci.zone_abbr, testing::MatchesRegex(kZoneAbbrRE)); \ + } while (0) + // A gMock matcher to match timespec values. Use this matcher like: // timespec ts1, ts2; // EXPECT_THAT(ts1, TimespecMatcher(ts2)); @@ -84,10 +105,10 @@ TEST(Time, ValueSemantics) { } TEST(Time, UnixEpoch) { - absl::Time::Breakdown bd = absl::UnixEpoch().In(absl::UTCTimeZone()); - ABSL_INTERNAL_EXPECT_TIME(bd, 1970, 1, 1, 0, 0, 0, 0, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); - EXPECT_EQ(4, bd.weekday); // Thursday + const auto ci = absl::UTCTimeZone().At(absl::UnixEpoch()); + EXPECT_EQ(absl::CivilSecond(1970, 1, 1, 0, 0, 0), ci.cs); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(absl::CivilDay(ci.cs))); } TEST(Time, Breakdown) { @@ -95,26 +116,26 @@ TEST(Time, Breakdown) { absl::Time t = absl::UnixEpoch(); // The Unix epoch as seen in NYC. - absl::Time::Breakdown bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 19, 0, 0, -18000, false); - EXPECT_EQ(absl::ZeroDuration(), bd.subsecond); - EXPECT_EQ(3, bd.weekday); // Wednesday + auto ci = tz.At(t); + EXPECT_CIVIL_INFO(ci, 1969, 12, 31, 19, 0, 0, -18000, false); + EXPECT_EQ(absl::ZeroDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(absl::CivilDay(ci.cs))); // Just before the epoch. t -= absl::Nanoseconds(1); - bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 18, 59, 59, -18000, false); - EXPECT_EQ(absl::Nanoseconds(999999999), bd.subsecond); - EXPECT_EQ(3, bd.weekday); // Wednesday + ci = tz.At(t); + EXPECT_CIVIL_INFO(ci, 1969, 12, 31, 18, 59, 59, -18000, false); + EXPECT_EQ(absl::Nanoseconds(999999999), ci.subsecond); + EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(absl::CivilDay(ci.cs))); // Some time later. t += absl::Hours(24) * 2735; t += absl::Hours(18) + absl::Minutes(30) + absl::Seconds(15) + absl::Nanoseconds(9); - bd = t.In(tz); - ABSL_INTERNAL_EXPECT_TIME(bd, 1977, 6, 28, 14, 30, 15, -14400, true); - EXPECT_EQ(8, bd.subsecond / absl::Nanoseconds(1)); - EXPECT_EQ(2, bd.weekday); // Tuesday + ci = tz.At(t); + EXPECT_CIVIL_INFO(ci, 1977, 6, 28, 14, 30, 15, -14400, true); + EXPECT_EQ(8, ci.subsecond / absl::Nanoseconds(1)); + EXPECT_EQ(absl::Weekday::tuesday, absl::GetWeekday(absl::CivilDay(ci.cs))); } TEST(Time, AdditiveOperators) { @@ -550,67 +571,63 @@ TEST(Time, ToChronoTime) { absl::ToChronoTime(absl::UnixEpoch() - tick)); } -TEST(Time, ConvertDateTime) { - const absl::TimeZone utc = absl::UTCTimeZone(); - const absl::TimeZone goog = - absl::time_internal::LoadTimeZone("America/Los_Angeles"); +TEST(Time, TimeZoneAt) { const absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York"); const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)"; - // A simple case of normalization. - absl::TimeConversion oct32 = ConvertDateTime(2013, 10, 32, 8, 30, 0, goog); - EXPECT_TRUE(oct32.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, oct32.kind); - absl::TimeConversion nov01 = ConvertDateTime(2013, 11, 1, 8, 30, 0, goog); - EXPECT_FALSE(nov01.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, nov01.kind); - EXPECT_EQ(oct32.pre, nov01.pre); - EXPECT_EQ("Fri, 1 Nov 2013 08:30:00 -0700 (PDT)", - absl::FormatTime(fmt, nov01.pre, goog)); + // A non-transition where the civil time is unique. + absl::CivilSecond nov01(2013, 11, 1, 8, 30, 0); + const auto nov01_ci = nyc.At(nov01); + EXPECT_EQ(absl::TimeZone::TimeInfo::UNIQUE, nov01_ci.kind); + EXPECT_EQ("Fri, 1 Nov 2013 08:30:00 -0400 (EDT)", + absl::FormatTime(fmt, nov01_ci.pre, nyc)); + EXPECT_EQ(nov01_ci.pre, nov01_ci.trans); + EXPECT_EQ(nov01_ci.pre, nov01_ci.post); + EXPECT_EQ(nov01_ci.pre, absl::FromCivil(nov01, nyc)); // A Spring DST transition, when there is a gap in civil time // and we prefer the later of the possible interpretations of a // non-existent time. - absl::TimeConversion mar13 = ConvertDateTime(2011, 3, 13, 2, 15, 0, nyc); - EXPECT_FALSE(mar13.normalized); - EXPECT_EQ(absl::TimeConversion::SKIPPED, mar13.kind); + absl::CivilSecond mar13(2011, 3, 13, 2, 15, 0); + const auto mar_ci = nyc.At(mar13); + EXPECT_EQ(absl::TimeZone::TimeInfo::SKIPPED, mar_ci.kind); EXPECT_EQ("Sun, 13 Mar 2011 03:15:00 -0400 (EDT)", - absl::FormatTime(fmt, mar13.pre, nyc)); + absl::FormatTime(fmt, mar_ci.pre, nyc)); EXPECT_EQ("Sun, 13 Mar 2011 03:00:00 -0400 (EDT)", - absl::FormatTime(fmt, mar13.trans, nyc)); + absl::FormatTime(fmt, mar_ci.trans, nyc)); EXPECT_EQ("Sun, 13 Mar 2011 01:15:00 -0500 (EST)", - absl::FormatTime(fmt, mar13.post, nyc)); - EXPECT_EQ(mar13.pre, absl::FromDateTime(2011, 3, 13, 2, 15, 0, nyc)); + absl::FormatTime(fmt, mar_ci.post, nyc)); + EXPECT_EQ(mar_ci.trans, absl::FromCivil(mar13, nyc)); // A Fall DST transition, when civil times are repeated and // we prefer the earlier of the possible interpretations of an // ambiguous time. - absl::TimeConversion nov06 = ConvertDateTime(2011, 11, 6, 1, 15, 0, nyc); - EXPECT_FALSE(nov06.normalized); - EXPECT_EQ(absl::TimeConversion::REPEATED, nov06.kind); + absl::CivilSecond nov06(2011, 11, 6, 1, 15, 0); + const auto nov06_ci = nyc.At(nov06); + EXPECT_EQ(absl::TimeZone::TimeInfo::REPEATED, nov06_ci.kind); EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0400 (EDT)", - absl::FormatTime(fmt, nov06.pre, nyc)); + absl::FormatTime(fmt, nov06_ci.pre, nyc)); EXPECT_EQ("Sun, 6 Nov 2011 01:00:00 -0500 (EST)", - absl::FormatTime(fmt, nov06.trans, nyc)); + absl::FormatTime(fmt, nov06_ci.trans, nyc)); EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0500 (EST)", - absl::FormatTime(fmt, nov06.post, nyc)); - EXPECT_EQ(nov06.pre, absl::FromDateTime(2011, 11, 6, 1, 15, 0, nyc)); + absl::FormatTime(fmt, nov06_ci.post, nyc)); + EXPECT_EQ(nov06_ci.pre, absl::FromCivil(nov06, nyc)); // Check that (time_t) -1 is handled correctly. - absl::TimeConversion minus1 = ConvertDateTime(1969, 12, 31, 18, 59, 59, nyc); - EXPECT_FALSE(minus1.normalized); - EXPECT_EQ(absl::TimeConversion::UNIQUE, minus1.kind); - EXPECT_EQ(-1, absl::ToTimeT(minus1.pre)); + absl::CivilSecond minus1(1969, 12, 31, 18, 59, 59); + const auto minus1_cl = nyc.At(minus1); + EXPECT_EQ(absl::TimeZone::TimeInfo::UNIQUE, minus1_cl.kind); + EXPECT_EQ(-1, absl::ToTimeT(minus1_cl.pre)); EXPECT_EQ("Wed, 31 Dec 1969 18:59:59 -0500 (EST)", - absl::FormatTime(fmt, minus1.pre, nyc)); + absl::FormatTime(fmt, minus1_cl.pre, nyc)); EXPECT_EQ("Wed, 31 Dec 1969 23:59:59 +0000 (UTC)", - absl::FormatTime(fmt, minus1.pre, utc)); + absl::FormatTime(fmt, minus1_cl.pre, absl::UTCTimeZone())); } -// FromDateTime(year, mon, day, hour, min, sec, UTCTimeZone()) has -// a specialized fastpath implementation which we exercise here. -TEST(Time, FromDateTimeUTC) { +// FromCivil(CivilSecond(year, mon, day, hour, min, sec), UTCTimeZone()) +// has a specialized fastpath implementation, which we exercise here. +TEST(Time, FromCivilUTC) { const absl::TimeZone utc = absl::UTCTimeZone(); const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)"; const int kMax = std::numeric_limits<int>::max(); @@ -618,65 +635,36 @@ TEST(Time, FromDateTimeUTC) { absl::Time t; // 292091940881 is the last positive year to use the fastpath. - t = absl::FromDateTime(292091940881, kMax, kMax, kMax, kMax, kMax, utc); + t = absl::FromCivil( + absl::CivilSecond(292091940881, kMax, kMax, kMax, kMax, kMax), utc); EXPECT_EQ("Fri, 25 Nov 292277026596 12:21:07 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(292091940882, kMax, kMax, kMax, kMax, kMax, utc); - EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow - t = absl::FromDateTime( - std::numeric_limits<int64_t>::max(), kMax, kMax, kMax, kMax, kMax, utc); + t = absl::FromCivil( + absl::CivilSecond(292091940882, kMax, kMax, kMax, kMax, kMax), utc); EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow // -292091936940 is the last negative year to use the fastpath. - t = absl::FromDateTime(-292091936940, kMin, kMin, kMin, kMin, kMin, utc); + t = absl::FromCivil( + absl::CivilSecond(-292091936940, kMin, kMin, kMin, kMin, kMin), utc); EXPECT_EQ("Fri, 1 Nov -292277022657 10:37:52 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(-292091936941, kMin, kMin, kMin, kMin, kMin, utc); + t = absl::FromCivil( + absl::CivilSecond(-292091936941, kMin, kMin, kMin, kMin, kMin), utc); EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no underflow - t = absl::FromDateTime( - std::numeric_limits<int64_t>::min(), kMin, kMin, kMin, kMin, kMin, utc); - EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no overflow // Check that we're counting leap years correctly. - t = absl::FromDateTime(1900, 2, 28, 23, 59, 59, utc); + t = absl::FromCivil(absl::CivilSecond(1900, 2, 28, 23, 59, 59), utc); EXPECT_EQ("Wed, 28 Feb 1900 23:59:59 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(1900, 3, 1, 0, 0, 0, utc); + t = absl::FromCivil(absl::CivilSecond(1900, 3, 1, 0, 0, 0), utc); EXPECT_EQ("Thu, 1 Mar 1900 00:00:00 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(2000, 2, 29, 23, 59, 59, utc); + t = absl::FromCivil(absl::CivilSecond(2000, 2, 29, 23, 59, 59), utc); EXPECT_EQ("Tue, 29 Feb 2000 23:59:59 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - t = absl::FromDateTime(2000, 3, 1, 0, 0, 0, utc); + t = absl::FromCivil(absl::CivilSecond(2000, 3, 1, 0, 0, 0), utc); EXPECT_EQ("Wed, 1 Mar 2000 00:00:00 +0000 (UTC)", absl::FormatTime(fmt, t, utc)); - - // Check normalization. - const std::string ymdhms = "%Y-%m-%d %H:%M:%S"; - t = absl::FromDateTime(2015, 1, 1, 0, 0, 60, utc); - EXPECT_EQ("2015-01-01 00:01:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 0, 60, 0, utc); - EXPECT_EQ("2015-01-01 01:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 24, 0, 0, utc); - EXPECT_EQ("2015-01-02 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 32, 0, 0, 0, utc); - EXPECT_EQ("2015-02-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 13, 1, 0, 0, 0, utc); - EXPECT_EQ("2016-01-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 13, 32, 60, 60, 60, utc); - EXPECT_EQ("2016-02-03 13:01:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 0, 0, -1, utc); - EXPECT_EQ("2014-12-31 23:59:59", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, 0, -1, 0, utc); - EXPECT_EQ("2014-12-31 23:59:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, 1, -1, 0, 0, utc); - EXPECT_EQ("2014-12-31 23:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, 1, -1, 0, 0, 0, utc); - EXPECT_EQ("2014-12-30 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, -1, 1, 0, 0, 0, utc); - EXPECT_EQ("2014-11-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); - t = absl::FromDateTime(2015, -1, -1, -1, -1, -1, utc); - EXPECT_EQ("2014-10-29 22:58:59", absl::FormatTime(ymdhms, t, utc)); } TEST(Time, ToTM) { @@ -684,8 +672,10 @@ TEST(Time, ToTM) { // Compares the results of ToTM() to gmtime_r() for lots of times over the // course of a few days. - const absl::Time start = absl::FromDateTime(2014, 1, 2, 3, 4, 5, utc); - const absl::Time end = absl::FromDateTime(2014, 1, 5, 3, 4, 5, utc); + const absl::Time start = + absl::FromCivil(absl::CivilSecond(2014, 1, 2, 3, 4, 5), utc); + const absl::Time end = + absl::FromCivil(absl::CivilSecond(2014, 1, 5, 3, 4, 5), utc); for (absl::Time t = start; t < end; t += absl::Seconds(30)) { const struct tm tm_bt = ToTM(t, utc); const time_t tt = absl::ToTimeT(t); @@ -711,12 +701,12 @@ TEST(Time, ToTM) { // Checks that the tm_isdst field is correct when in standard time. const absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York"); - absl::Time t = absl::FromDateTime(2014, 3, 1, 0, 0, 0, nyc); + absl::Time t = absl::FromCivil(absl::CivilSecond(2014, 3, 1, 0, 0, 0), nyc); struct tm tm = ToTM(t, nyc); EXPECT_FALSE(tm.tm_isdst); // Checks that the tm_isdst field is correct when in daylight time. - t = absl::FromDateTime(2014, 4, 1, 0, 0, 0, nyc); + t = absl::FromCivil(absl::CivilSecond(2014, 4, 1, 0, 0, 0), nyc); tm = ToTM(t, nyc); EXPECT_TRUE(tm.tm_isdst); @@ -808,8 +798,8 @@ TEST(Time, TMRoundTrip) { absl::time_internal::LoadTimeZone("America/New_York"); // Test round-tripping across a skipped transition - absl::Time start = absl::FromDateTime(2014, 3, 9, 0, 0, 0, nyc); - absl::Time end = absl::FromDateTime(2014, 3, 9, 4, 0, 0, nyc); + absl::Time start = absl::FromCivil(absl::CivilHour(2014, 3, 9, 0), nyc); + absl::Time end = absl::FromCivil(absl::CivilHour(2014, 3, 9, 4), nyc); for (absl::Time t = start; t < end; t += absl::Minutes(1)) { struct tm tm = ToTM(t, nyc); absl::Time rt = FromTM(tm, nyc); @@ -817,8 +807,8 @@ TEST(Time, TMRoundTrip) { } // Test round-tripping across an ambiguous transition - start = absl::FromDateTime(2014, 11, 2, 0, 0, 0, nyc); - end = absl::FromDateTime(2014, 11, 2, 4, 0, 0, nyc); + start = absl::FromCivil(absl::CivilHour(2014, 11, 2, 0), nyc); + end = absl::FromCivil(absl::CivilHour(2014, 11, 2, 4), nyc); for (absl::Time t = start; t < end; t += absl::Minutes(1)) { struct tm tm = ToTM(t, nyc); absl::Time rt = FromTM(tm, nyc); @@ -826,8 +816,8 @@ TEST(Time, TMRoundTrip) { } // Test round-tripping of unique instants crossing a day boundary - start = absl::FromDateTime(2014, 6, 27, 22, 0, 0, nyc); - end = absl::FromDateTime(2014, 6, 28, 4, 0, 0, nyc); + start = absl::FromCivil(absl::CivilHour(2014, 6, 27, 22), nyc); + end = absl::FromCivil(absl::CivilHour(2014, 6, 28, 4), nyc); for (absl::Time t = start; t < end; t += absl::Minutes(1)) { struct tm tm = ToTM(t, nyc); absl::Time rt = FromTM(tm, nyc); @@ -980,27 +970,27 @@ TEST(Time, ConversionSaturation) { EXPECT_EQ(min_timespec_sec, ts.tv_sec); EXPECT_EQ(0, ts.tv_nsec); - // Checks how Time::In() saturates on infinities. - absl::Time::Breakdown bd = absl::InfiniteFuture().In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::max(), 12, 31, 23, + // Checks how TimeZone::At() saturates on infinities. + auto ci = utc.At(absl::InfiniteFuture()); + EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, 0, false); - EXPECT_EQ(absl::InfiniteDuration(), bd.subsecond); - EXPECT_EQ(4, bd.weekday); // Thursday - EXPECT_EQ(365, bd.yearday); - EXPECT_STREQ("-00", bd.zone_abbr); // artifact of absl::Time::In() - bd = absl::InfinitePast().In(utc); - ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0, + EXPECT_EQ(absl::InfiniteDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(absl::CivilDay(ci.cs))); + EXPECT_EQ(365, absl::GetYearDay(absl::CivilDay(ci.cs))); + EXPECT_STREQ("-00", ci.zone_abbr); // artifact of TimeZone::At() + ci = utc.At(absl::InfinitePast()); + EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0, 0, 0, false); - EXPECT_EQ(-absl::InfiniteDuration(), bd.subsecond); - EXPECT_EQ(7, bd.weekday); // Sunday - EXPECT_EQ(1, bd.yearday); - EXPECT_STREQ("-00", bd.zone_abbr); // artifact of absl::Time::In() + EXPECT_EQ(-absl::InfiniteDuration(), ci.subsecond); + EXPECT_EQ(absl::Weekday::sunday, absl::GetWeekday(absl::CivilDay(ci.cs))); + EXPECT_EQ(1, absl::GetYearDay(absl::CivilDay(ci.cs))); + EXPECT_STREQ("-00", ci.zone_abbr); // artifact of TimeZone::At() // Approach the maximal Time value from below. - t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 6, utc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 6), utc); EXPECT_EQ("292277026596-12-04T15:30:06+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); - t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 7, utc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 7), utc); EXPECT_EQ("292277026596-12-04T15:30:07+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); EXPECT_EQ( @@ -1008,21 +998,21 @@ TEST(Time, ConversionSaturation) { // Checks that we can also get the maximal Time value for a far-east zone. const absl::TimeZone plus14 = absl::FixedTimeZone(14 * 60 * 60); - t = absl::FromDateTime(292277026596, 12, 5, 5, 30, 7, plus14); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 5, 30, 7), plus14); EXPECT_EQ("292277026596-12-05T05:30:07+14:00", absl::FormatTime(absl::RFC3339_full, t, plus14)); EXPECT_EQ( absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t); // One second later should push us to infinity. - t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 8, utc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 8), utc); EXPECT_EQ("infinite-future", absl::FormatTime(absl::RFC3339_full, t, utc)); // Approach the minimal Time value from above. - t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 53, utc); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 53), utc); EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); - t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 52, utc); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 52), utc); EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); EXPECT_EQ( @@ -1030,14 +1020,15 @@ TEST(Time, ConversionSaturation) { // Checks that we can also get the minimal Time value for a far-west zone. const absl::TimeZone minus12 = absl::FixedTimeZone(-12 * 60 * 60); - t = absl::FromDateTime(-292277022657, 1, 26, 20, 29, 52, minus12); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 26, 20, 29, 52), + minus12); EXPECT_EQ("-292277022657-01-26T20:29:52-12:00", absl::FormatTime(absl::RFC3339_full, t, minus12)); EXPECT_EQ( absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t); // One second before should push us to -infinity. - t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 51, utc); + t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 51), utc); EXPECT_EQ("infinite-past", absl::FormatTime(absl::RFC3339_full, t, utc)); } @@ -1051,38 +1042,160 @@ TEST(Time, ExtendedConversionSaturation) { absl::time_internal::LoadTimeZone("America/New_York"); const absl::Time max = absl::FromUnixSeconds(std::numeric_limits<int64_t>::max()); - absl::Time::Breakdown bd; + absl::TimeZone::CivilInfo ci; absl::Time t; // The maximal time converted in each zone. - bd = max.In(syd); - ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 5, 2, 30, 7, 39600, true); - t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 7, syd); + ci = syd.At(max); + EXPECT_CIVIL_INFO(ci, 292277026596, 12, 5, 2, 30, 7, 39600, true); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 7), syd); EXPECT_EQ(max, t); - bd = max.In(nyc); - ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 4, 10, 30, 7, -18000, false); - t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 7, nyc); + ci = nyc.At(max); + EXPECT_CIVIL_INFO(ci, 292277026596, 12, 4, 10, 30, 7, -18000, false); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 7), nyc); EXPECT_EQ(max, t); // One second later should push us to infinity. - t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 8, syd); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 8), syd); EXPECT_EQ(absl::InfiniteFuture(), t); - t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 8, nyc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 8), nyc); EXPECT_EQ(absl::InfiniteFuture(), t); // And we should stick there. - t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 9, syd); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 5, 2, 30, 9), syd); EXPECT_EQ(absl::InfiniteFuture(), t); - t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 9, nyc); + t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 10, 30, 9), nyc); EXPECT_EQ(absl::InfiniteFuture(), t); // All the way up to a saturated date/time, without overflow. - t = absl::FromDateTime( - std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, syd); + t = absl::FromCivil(absl::CivilSecond::max(), syd); EXPECT_EQ(absl::InfiniteFuture(), t); - t = absl::FromDateTime( - std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, nyc); + t = absl::FromCivil(absl::CivilSecond::max(), nyc); EXPECT_EQ(absl::InfiniteFuture(), t); } +TEST(Time, FromCivilAlignment) { + const absl::TimeZone utc = absl::UTCTimeZone(); + const absl::CivilSecond cs(2015, 2, 3, 4, 5, 6); + absl::Time t = absl::FromCivil(cs, utc); + EXPECT_EQ("2015-02-03T04:05:06+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilMinute(cs), utc); + EXPECT_EQ("2015-02-03T04:05:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilHour(cs), utc); + EXPECT_EQ("2015-02-03T04:00:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilDay(cs), utc); + EXPECT_EQ("2015-02-03T00:00:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilMonth(cs), utc); + EXPECT_EQ("2015-02-01T00:00:00+00:00", absl::FormatTime(t, utc)); + t = absl::FromCivil(absl::CivilYear(cs), utc); + EXPECT_EQ("2015-01-01T00:00:00+00:00", absl::FormatTime(t, utc)); +} + +TEST(Time, LegacyDateTime) { + const absl::TimeZone utc = absl::UTCTimeZone(); + const std::string ymdhms = "%Y-%m-%d %H:%M:%S"; + const int kMax = std::numeric_limits<int>::max(); + const int kMin = std::numeric_limits<int>::min(); + absl::Time t; + + t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::max(), + kMax, kMax, kMax, kMax, kMax, utc); + EXPECT_EQ("infinite-future", + absl::FormatTime(ymdhms, t, utc)); // no overflow + t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::min(), + kMin, kMin, kMin, kMin, kMin, utc); + EXPECT_EQ("infinite-past", + absl::FormatTime(ymdhms, t, utc)); // no overflow + + // Check normalization. + EXPECT_TRUE(absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, utc).normalized); + t = absl::FromDateTime(2015, 1, 1, 0, 0, 60, utc); + EXPECT_EQ("2015-01-01 00:01:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 0, 60, 0, utc); + EXPECT_EQ("2015-01-01 01:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 24, 0, 0, utc); + EXPECT_EQ("2015-01-02 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 32, 0, 0, 0, utc); + EXPECT_EQ("2015-02-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 13, 1, 0, 0, 0, utc); + EXPECT_EQ("2016-01-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 13, 32, 60, 60, 60, utc); + EXPECT_EQ("2016-02-03 13:01:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 0, 0, -1, utc); + EXPECT_EQ("2014-12-31 23:59:59", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, 0, -1, 0, utc); + EXPECT_EQ("2014-12-31 23:59:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, 1, -1, 0, 0, utc); + EXPECT_EQ("2014-12-31 23:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, 1, -1, 0, 0, 0, utc); + EXPECT_EQ("2014-12-30 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, -1, 1, 0, 0, 0, utc); + EXPECT_EQ("2014-11-01 00:00:00", absl::FormatTime(ymdhms, t, utc)); + t = absl::FromDateTime(2015, -1, -1, -1, -1, -1, utc); + EXPECT_EQ("2014-10-29 22:58:59", absl::FormatTime(ymdhms, t, utc)); +} + +TEST(Time, NextTransitionUTC) { + const auto tz = absl::UTCTimeZone(); + absl::TimeZone::CivilTransition trans; + + auto t = absl::InfinitePast(); + EXPECT_FALSE(tz.NextTransition(t, &trans)); + + t = absl::InfiniteFuture(); + EXPECT_FALSE(tz.NextTransition(t, &trans)); +} + +TEST(Time, PrevTransitionUTC) { + const auto tz = absl::UTCTimeZone(); + absl::TimeZone::CivilTransition trans; + + auto t = absl::InfiniteFuture(); + EXPECT_FALSE(tz.PrevTransition(t, &trans)); + + t = absl::InfinitePast(); + EXPECT_FALSE(tz.PrevTransition(t, &trans)); +} + +TEST(Time, NextTransitionNYC) { + const auto tz = absl::time_internal::LoadTimeZone("America/New_York"); + absl::TimeZone::CivilTransition trans; + + auto t = absl::FromCivil(absl::CivilSecond(2018, 6, 30, 0, 0, 0), tz); + EXPECT_TRUE(tz.NextTransition(t, &trans)); + EXPECT_EQ(absl::CivilSecond(2018, 11, 4, 2, 0, 0), trans.from); + EXPECT_EQ(absl::CivilSecond(2018, 11, 4, 1, 0, 0), trans.to); + + t = absl::InfiniteFuture(); + EXPECT_FALSE(tz.NextTransition(t, &trans)); + + t = absl::InfinitePast(); + EXPECT_TRUE(tz.NextTransition(t, &trans)); + if (trans.from == absl::CivilSecond(1918, 03, 31, 2, 0, 0)) { + // It looks like the tzdata is only 32 bit (probably macOS), + // which bottoms out at 1901-12-13T20:45:52+00:00. + EXPECT_EQ(absl::CivilSecond(1918, 3, 31, 3, 0, 0), trans.to); + } else { + EXPECT_EQ(absl::CivilSecond(1883, 11, 18, 12, 3, 58), trans.from); + EXPECT_EQ(absl::CivilSecond(1883, 11, 18, 12, 0, 0), trans.to); + } +} + +TEST(Time, PrevTransitionNYC) { + const auto tz = absl::time_internal::LoadTimeZone("America/New_York"); + absl::TimeZone::CivilTransition trans; + + auto t = absl::FromCivil(absl::CivilSecond(2018, 6, 30, 0, 0, 0), tz); + EXPECT_TRUE(tz.PrevTransition(t, &trans)); + EXPECT_EQ(absl::CivilSecond(2018, 3, 11, 2, 0, 0), trans.from); + EXPECT_EQ(absl::CivilSecond(2018, 3, 11, 3, 0, 0), trans.to); + + t = absl::InfinitePast(); + EXPECT_FALSE(tz.PrevTransition(t, &trans)); + + t = absl::InfiniteFuture(); + EXPECT_TRUE(tz.PrevTransition(t, &trans)); + // We have a transition but we don't know which one. +} + } // namespace diff --git a/absl/time/time_zone_test.cc b/absl/time/time_zone_test.cc index 7138560a..43d91904 100644 --- a/absl/time/time_zone_test.cc +++ b/absl/time/time_zone_test.cc @@ -59,7 +59,7 @@ TEST(TimeZone, DefaultTimeZones) { TEST(TimeZone, FixedTimeZone) { const absl::TimeZone tz = absl::FixedTimeZone(123); - const cctz::time_zone cz = cctz::fixed_time_zone(cctz::sys_seconds(123)); + const cctz::time_zone cz = cctz::fixed_time_zone(cctz::seconds(123)); EXPECT_EQ(tz, absl::TimeZone(cz)); } |