summaryrefslogtreecommitdiff
path: root/absl/time
diff options
context:
space:
mode:
Diffstat (limited to 'absl/time')
-rw-r--r--absl/time/BUILD.bazel1
-rw-r--r--absl/time/time_test.cc45
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");