diff options
Diffstat (limited to 'absl/time')
-rw-r--r-- | absl/time/BUILD.bazel | 1 | ||||
-rw-r--r-- | absl/time/time_test.cc | 45 |
2 files changed, 46 insertions, 0 deletions
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index a615152f..9ab2adb8 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel @@ -93,6 +93,7 @@ cc_test( ":time", "//absl/base:config", "//absl/base:core_headers", + "//absl/numeric:int128", "//absl/time/internal/cctz:time_zone", "@com_google_googletest//:gtest_main", ], diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index 9c4709e6..6f89672c 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc @@ -27,6 +27,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/numeric/int128.h" #include "absl/time/clock.h" #include "absl/time/internal/test_util.h" @@ -575,6 +576,50 @@ TEST(Time, ToChronoTime) { absl::ToChronoTime(absl::UnixEpoch() - tick)); } +// Check that absl::int128 works as a std::chrono::duration representation. +TEST(Time, Chrono128) { + // Define a std::chrono::time_point type whose time[sic]_since_epoch() is + // a signed 128-bit count of attoseconds. This has a range and resolution + // (currently) beyond those of absl::Time, and undoubtedly also beyond those + // of std::chrono::system_clock::time_point. + // + // Note: The to/from-chrono support should probably be updated to handle + // such wide representations. + using Timestamp = + std::chrono::time_point<std::chrono::system_clock, + std::chrono::duration<absl::int128, std::atto>>; + + // Expect that we can round-trip the std::chrono::system_clock::time_point + // extremes through both absl::Time and Timestamp, and that Timestamp can + // handle the (current) absl::Time extremes. + // + // Note: We should use std::chrono::floor() instead of time_point_cast(), + // but floor() is only available since c++17. + for (const auto tp : {std::chrono::system_clock::time_point::min(), + std::chrono::system_clock::time_point::max()}) { + EXPECT_EQ(tp, absl::ToChronoTime(absl::FromChrono(tp))); + EXPECT_EQ(tp, std::chrono::time_point_cast< + std::chrono::system_clock::time_point::duration>( + std::chrono::time_point_cast<Timestamp::duration>(tp))); + } + Timestamp::duration::rep v = std::numeric_limits<int64_t>::min(); + v *= Timestamp::duration::period::den; + auto ts = Timestamp(Timestamp::duration(v)); + ts += std::chrono::duration<int64_t, std::atto>(0); + EXPECT_EQ(std::numeric_limits<int64_t>::min(), + ts.time_since_epoch().count() / Timestamp::duration::period::den); + EXPECT_EQ(0, + ts.time_since_epoch().count() % Timestamp::duration::period::den); + v = std::numeric_limits<int64_t>::max(); + v *= Timestamp::duration::period::den; + ts = Timestamp(Timestamp::duration(v)); + ts += std::chrono::duration<int64_t, std::atto>(999999999750000000); + EXPECT_EQ(std::numeric_limits<int64_t>::max(), + ts.time_since_epoch().count() / Timestamp::duration::period::den); + EXPECT_EQ(999999999750000000, + ts.time_since_epoch().count() % Timestamp::duration::period::den); +} + TEST(Time, TimeZoneAt) { const absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York"); |