summaryrefslogtreecommitdiff
path: root/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc')
-rw-r--r--abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc134
1 files changed, 110 insertions, 24 deletions
diff --git a/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
index 9a1a8d6..4884c32 100644
--- a/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -21,10 +21,14 @@
#include <thread>
#include <vector>
-#include "gtest/gtest.h"
#include "absl/base/config.h"
-#include "absl/time/internal/cctz/include/cctz/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
+#if defined(__linux__)
+#include <features.h>
+#endif
+
+#include "gtest/gtest.h"
+#include "absl/time/internal/cctz/include/cctz/civil_time.h"
namespace chrono = std::chrono;
@@ -131,6 +135,7 @@ const char* const kTimeZoneNames[] = {"Africa/Abidjan",
"America/Cayman",
"America/Chicago",
"America/Chihuahua",
+ "America/Ciudad_Juarez",
"America/Coral_Harbour",
"America/Cordoba",
"America/Costa_Rica",
@@ -485,6 +490,7 @@ const char* const kTimeZoneNames[] = {"Africa/Abidjan",
"Europe/Kaliningrad",
"Europe/Kiev",
"Europe/Kirov",
+ "Europe/Kyiv",
"Europe/Lisbon",
"Europe/Ljubljana",
"Europe/London",
@@ -524,6 +530,7 @@ const char* const kTimeZoneNames[] = {"Africa/Abidjan",
"Europe/Zagreb",
"Europe/Zaporozhye",
"Europe/Zurich",
+ "Factory",
"GB",
"GB-Eire",
"GMT",
@@ -579,6 +586,7 @@ const char* const kTimeZoneNames[] = {"Africa/Abidjan",
"Pacific/Guam",
"Pacific/Honolulu",
"Pacific/Johnston",
+ "Pacific/Kanton",
"Pacific/Kiritimati",
"Pacific/Kosrae",
"Pacific/Kwajalein",
@@ -717,6 +725,22 @@ TEST(TimeZones, LoadZonesConcurrently) {
}
#endif
+TEST(TimeZone, UTC) {
+ const time_zone utc = utc_time_zone();
+
+ time_zone loaded_utc;
+ EXPECT_TRUE(load_time_zone("UTC", &loaded_utc));
+ EXPECT_EQ(loaded_utc, utc);
+
+ time_zone loaded_utc0;
+ EXPECT_TRUE(load_time_zone("UTC0", &loaded_utc0));
+ EXPECT_EQ(loaded_utc0, utc);
+
+ time_zone loaded_bad;
+ EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &loaded_bad));
+ EXPECT_EQ(loaded_bad, utc);
+}
+
TEST(TimeZone, NamedTimeZones) {
const time_zone utc = utc_time_zone();
EXPECT_EQ("UTC", utc.name());
@@ -892,19 +916,19 @@ TEST(MakeTime, TimePointResolution) {
const time_zone utc = utc_time_zone();
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));
+ EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_ns, utc));
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));
+ EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_us, utc));
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));
+ EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_ms, utc));
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));
+ EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_s, utc));
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));
+ EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_s64, utc));
// These next two require chrono::time_point_cast because the conversion
// from a resolution of seconds (the return value of convert()) to a
@@ -912,10 +936,10 @@ TEST(MakeTime, TimePointResolution) {
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));
+ EXPECT_EQ("04:00", absl::time_internal::cctz::format("%M:%E*S", tp_m, utc));
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));
+ EXPECT_EQ("00:00", absl::time_internal::cctz::format("%M:%E*S", tp_h, utc));
}
TEST(MakeTime, Normalization) {
@@ -941,9 +965,11 @@ TEST(MakeTime, SysSecondsLimits) {
// 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));
+ EXPECT_EQ("292277026596-12-04T15:30:06+00:00",
+ absl::time_internal::cctz::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("292277026596-12-04T15:30:07+00:00",
+ absl::time_internal::cctz::format(RFC3339, tp, utc));
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<absl::time_internal::cctz::seconds>::max(), tp);
@@ -952,7 +978,8 @@ TEST(MakeTime, SysSecondsLimits) {
// 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("292277026596-12-05T05:30:07+14:00",
+ absl::time_internal::cctz::format(RFC3339, tp, east));
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<absl::time_internal::cctz::seconds>::max(), tp);
@@ -961,7 +988,8 @@ TEST(MakeTime, SysSecondsLimits) {
// 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("292277026596-12-04T01:30:07-14:00",
+ absl::time_internal::cctz::format(RFC3339, tp, west));
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<absl::time_internal::cctz::seconds>::max(), tp);
@@ -970,9 +998,11 @@ TEST(MakeTime, SysSecondsLimits) {
// 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));
+ EXPECT_EQ("-292277022657-01-27T08:29:53+00:00",
+ absl::time_internal::cctz::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("-292277022657-01-27T08:29:52+00:00",
+ absl::time_internal::cctz::format(RFC3339, tp, utc));
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<absl::time_internal::cctz::seconds>::min(), tp);
@@ -981,7 +1011,8 @@ TEST(MakeTime, SysSecondsLimits) {
// 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("-292277022657-01-27T22:29:52+14:00",
+ absl::time_internal::cctz::format(RFC3339, tp, east));
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<absl::time_internal::cctz::seconds>::min(), tp);
@@ -990,7 +1021,8 @@ TEST(MakeTime, SysSecondsLimits) {
// 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("-292277022657-01-26T18:29:52-14:00",
+ absl::time_internal::cctz::format(RFC3339, tp, west));
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<absl::time_internal::cctz::seconds>::min(), tp);
@@ -1007,14 +1039,20 @@ TEST(MakeTime, SysSecondsLimits) {
const time_zone cut = 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), cut);
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
- // The BSD gmtime_r() fails on extreme positive tm_year values.
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
+ // Some gmtime_r() impls fail on extreme positive values.
#else
- EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, cut));
+ EXPECT_EQ("2147485547-12-31T23:59:59+00:00",
+ absl::time_internal::cctz::format(RFC3339, tp, cut));
#endif
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), cut);
- EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, cut));
+#if defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
+ // Some gmtime_r() impls fail on extreme negative values (fxbug.dev/78527).
+#else
+ EXPECT_EQ("-2147481748-01-01T00:00:00+00:00",
+ absl::time_internal::cctz::format(RFC3339, tp, cut));
+#endif
#endif
}
}
@@ -1026,7 +1064,7 @@ TEST(MakeTime, LocalTimeLibC) {
// 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__) && !defined(__ANDROID__)
+#if defined(__linux__) && defined(__GLIBC__) && !defined(__ANDROID__)
const char* const ep = getenv("TZ");
std::string tz_name = (ep != nullptr) ? ep : "";
for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) {
@@ -1039,7 +1077,7 @@ TEST(MakeTime, LocalTimeLibC) {
tp = zi.lookup(transition.to).trans) {
const auto fcl = zi.lookup(transition.from);
const auto tcl = zi.lookup(transition.to);
- civil_second cs; // compare cs in zi and lc
+ civil_second cs, us; // compare cs and us 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.
@@ -1055,12 +1093,14 @@ TEST(MakeTime, LocalTimeLibC) {
}
ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind);
cs = transition.to;
+ us = transition.from;
} else {
ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind);
ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind);
cs = transition.from;
+ us = transition.to;
}
- if (cs.year() > 2037) break; // limit test time (and to 32-bit time_t)
+ if (us.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
@@ -1092,6 +1132,13 @@ TEST(MakeTime, LocalTimeLibC) {
EXPECT_EQ(cl_zi.pre, cl_lc.pre);
EXPECT_EQ(cl_zi.trans, cl_lc.trans);
EXPECT_EQ(cl_zi.post, cl_lc.post);
+ const auto ucl_zi = zi.lookup(us);
+ const auto ucl_lc = lc.lookup(us);
+ SCOPED_TRACE(testing::Message() << "For " << us << " in " << *np);
+ EXPECT_EQ(ucl_zi.kind, ucl_lc.kind);
+ EXPECT_EQ(ucl_zi.pre, ucl_lc.pre);
+ EXPECT_EQ(ucl_zi.trans, ucl_lc.trans);
+ EXPECT_EQ(ucl_zi.post, ucl_lc.post);
}
}
if (ep == nullptr) {
@@ -1165,6 +1212,45 @@ TEST(PrevTransition, AmericaNewYork) {
// We have a transition but we don't know which one.
}
+TEST(NextTransition, Scan) {
+ for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) {
+ SCOPED_TRACE(testing::Message() << "In " << *np);
+ time_zone tz;
+ // EXPECT_TRUE(load_time_zone(*np, &tz));
+ if (!load_time_zone(*np, &tz)) {
+ continue; // tolerate kTimeZoneNames/zoneinfo skew
+ }
+
+ auto tp = time_point<absl::time_internal::cctz::seconds>::min();
+ time_zone::civil_transition trans;
+ while (tz.next_transition(tp, &trans)) {
+ time_zone::civil_lookup from_cl = tz.lookup(trans.from);
+ EXPECT_NE(from_cl.kind, time_zone::civil_lookup::REPEATED);
+ time_zone::civil_lookup to_cl = tz.lookup(trans.to);
+ EXPECT_NE(to_cl.kind, time_zone::civil_lookup::SKIPPED);
+
+ auto trans_tp = to_cl.trans;
+ time_zone::absolute_lookup trans_al = tz.lookup(trans_tp);
+ EXPECT_EQ(trans_al.cs, trans.to);
+ auto pre_trans_tp = trans_tp - absl::time_internal::cctz::seconds(1);
+ time_zone::absolute_lookup pre_trans_al = tz.lookup(pre_trans_tp);
+ EXPECT_EQ(pre_trans_al.cs + 1, trans.from);
+
+ auto offset_delta = trans_al.offset - pre_trans_al.offset;
+ EXPECT_EQ(offset_delta, trans.to - trans.from);
+ if (offset_delta == 0) {
+ // This "transition" is only an is_dst or abbr change.
+ EXPECT_EQ(to_cl.kind, time_zone::civil_lookup::UNIQUE);
+ if (trans_al.is_dst == pre_trans_al.is_dst) {
+ EXPECT_STRNE(trans_al.abbr, pre_trans_al.abbr);
+ }
+ }
+
+ tp = trans_tp; // continue scan from transition
+ }
+ }
+}
+
TEST(TimeZoneEdgeCase, AmericaNewYork) {
const time_zone tz = LoadZone("America/New_York");