about summary refs log tree commit diff
path: root/absl/time/duration_test.cc
diff options
context:
space:
mode:
authormisterg <misterg@google.com>2017-09-19T20·54-0400
committermisterg <misterg@google.com>2017-09-19T20·54-0400
commitc2e754829628d1e9b7a16b3389cfdace76950fdf (patch)
tree5a7f056f44e27c30e10025113b644f0b3b5801fc /absl/time/duration_test.cc
Initial Commit
Diffstat (limited to 'absl/time/duration_test.cc')
-rw-r--r--absl/time/duration_test.cc1530
1 files changed, 1530 insertions, 0 deletions
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc
new file mode 100644
index 000000000000..eed96e3e18f4
--- /dev/null
+++ b/absl/time/duration_test.cc
@@ -0,0 +1,1530 @@
+// 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.
+
+#include <cmath>
+#include <cstdint>
+#include <ctime>
+#include <limits>
+#include <string>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/time/time.h"
+
+namespace {
+
+constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
+constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
+
+// Approximates the given number of years. This is only used to make some test
+// code more readable.
+absl::Duration ApproxYears(int64_t n) { return absl::Hours(n) * 365 * 24; }
+
+// A gMock matcher to match timespec values. Use this matcher like:
+// timespec ts1, ts2;
+// EXPECT_THAT(ts1, TimespecMatcher(ts2));
+MATCHER_P(TimespecMatcher, ts, "") {
+  if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec)
+    return true;
+  *result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} ";
+  *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}";
+  return false;
+}
+
+// A gMock matcher to match timeval values. Use this matcher like:
+// timeval tv1, tv2;
+// EXPECT_THAT(tv1, TimevalMatcher(tv2));
+MATCHER_P(TimevalMatcher, tv, "") {
+  if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec)
+    return true;
+  *result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} ";
+  *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}";
+  return false;
+}
+
+TEST(Duration, ValueSemantics) {
+  // If this compiles, the test passes.
+  constexpr absl::Duration a;      // Default construction
+  constexpr absl::Duration b = a;  // Copy construction
+  constexpr absl::Duration c(b);   // Copy construction (again)
+
+  absl::Duration d;
+  d = c;  // Assignment
+}
+
+TEST(Duration, Factories) {
+  constexpr absl::Duration zero = absl::ZeroDuration();
+  constexpr absl::Duration nano = absl::Nanoseconds(1);
+  constexpr absl::Duration micro = absl::Microseconds(1);
+  constexpr absl::Duration milli = absl::Milliseconds(1);
+  constexpr absl::Duration sec = absl::Seconds(1);
+  constexpr absl::Duration min = absl::Minutes(1);
+  constexpr absl::Duration hour = absl::Hours(1);
+
+  EXPECT_EQ(zero, absl::Duration());
+  EXPECT_EQ(zero, absl::Seconds(0));
+  EXPECT_EQ(nano, absl::Nanoseconds(1));
+  EXPECT_EQ(micro, absl::Nanoseconds(1000));
+  EXPECT_EQ(milli, absl::Microseconds(1000));
+  EXPECT_EQ(sec, absl::Milliseconds(1000));
+  EXPECT_EQ(min, absl::Seconds(60));
+  EXPECT_EQ(hour, absl::Minutes(60));
+
+  // Tests factory limits
+  const absl::Duration inf = absl::InfiniteDuration();
+
+  EXPECT_GT(inf, absl::Seconds(kint64max));
+  EXPECT_LT(-inf, absl::Seconds(kint64min));
+  EXPECT_LT(-inf, absl::Seconds(-kint64max));
+
+  EXPECT_EQ(inf, absl::Minutes(kint64max));
+  EXPECT_EQ(-inf, absl::Minutes(kint64min));
+  EXPECT_EQ(-inf, absl::Minutes(-kint64max));
+  EXPECT_GT(inf, absl::Minutes(kint64max / 60));
+  EXPECT_LT(-inf, absl::Minutes(kint64min / 60));
+  EXPECT_LT(-inf, absl::Minutes(-kint64max / 60));
+
+  EXPECT_EQ(inf, absl::Hours(kint64max));
+  EXPECT_EQ(-inf, absl::Hours(kint64min));
+  EXPECT_EQ(-inf, absl::Hours(-kint64max));
+  EXPECT_GT(inf, absl::Hours(kint64max / 3600));
+  EXPECT_LT(-inf, absl::Hours(kint64min / 3600));
+  EXPECT_LT(-inf, absl::Hours(-kint64max / 3600));
+}
+
+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));                  \
+  } while (0)
+
+  TEST_DURATION_CONVERSION(Nanoseconds);
+  TEST_DURATION_CONVERSION(Microseconds);
+  TEST_DURATION_CONVERSION(Milliseconds);
+  TEST_DURATION_CONVERSION(Seconds);
+  TEST_DURATION_CONVERSION(Minutes);
+  TEST_DURATION_CONVERSION(Hours);
+
+#undef TEST_DURATION_CONVERSION
+}
+
+template <int64_t n>
+void TestToConversion() {
+  constexpr absl::Duration nano = absl::Nanoseconds(n);
+  EXPECT_EQ(n, absl::ToInt64Nanoseconds(nano));
+  EXPECT_EQ(0, absl::ToInt64Microseconds(nano));
+  EXPECT_EQ(0, absl::ToInt64Milliseconds(nano));
+  EXPECT_EQ(0, absl::ToInt64Seconds(nano));
+  EXPECT_EQ(0, absl::ToInt64Minutes(nano));
+  EXPECT_EQ(0, absl::ToInt64Hours(nano));
+  const absl::Duration micro = absl::Microseconds(n);
+  EXPECT_EQ(n * 1000, absl::ToInt64Nanoseconds(micro));
+  EXPECT_EQ(n, absl::ToInt64Microseconds(micro));
+  EXPECT_EQ(0, absl::ToInt64Milliseconds(micro));
+  EXPECT_EQ(0, absl::ToInt64Seconds(micro));
+  EXPECT_EQ(0, absl::ToInt64Minutes(micro));
+  EXPECT_EQ(0, absl::ToInt64Hours(micro));
+  const absl::Duration milli = absl::Milliseconds(n);
+  EXPECT_EQ(n * 1000 * 1000, absl::ToInt64Nanoseconds(milli));
+  EXPECT_EQ(n * 1000, absl::ToInt64Microseconds(milli));
+  EXPECT_EQ(n, absl::ToInt64Milliseconds(milli));
+  EXPECT_EQ(0, absl::ToInt64Seconds(milli));
+  EXPECT_EQ(0, absl::ToInt64Minutes(milli));
+  EXPECT_EQ(0, absl::ToInt64Hours(milli));
+  const absl::Duration sec = absl::Seconds(n);
+  EXPECT_EQ(n * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(sec));
+  EXPECT_EQ(n * 1000 * 1000, absl::ToInt64Microseconds(sec));
+  EXPECT_EQ(n * 1000, absl::ToInt64Milliseconds(sec));
+  EXPECT_EQ(n, absl::ToInt64Seconds(sec));
+  EXPECT_EQ(0, absl::ToInt64Minutes(sec));
+  EXPECT_EQ(0, absl::ToInt64Hours(sec));
+  const absl::Duration min = absl::Minutes(n);
+  EXPECT_EQ(n * 60 * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(min));
+  EXPECT_EQ(n * 60 * 1000 * 1000, absl::ToInt64Microseconds(min));
+  EXPECT_EQ(n * 60 * 1000, absl::ToInt64Milliseconds(min));
+  EXPECT_EQ(n * 60, absl::ToInt64Seconds(min));
+  EXPECT_EQ(n, absl::ToInt64Minutes(min));
+  EXPECT_EQ(0, absl::ToInt64Hours(min));
+  const absl::Duration hour = absl::Hours(n);
+  EXPECT_EQ(n * 60 * 60 * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(hour));
+  EXPECT_EQ(n * 60 * 60 * 1000 * 1000, absl::ToInt64Microseconds(hour));
+  EXPECT_EQ(n * 60 * 60 * 1000, absl::ToInt64Milliseconds(hour));
+  EXPECT_EQ(n * 60 * 60, absl::ToInt64Seconds(hour));
+  EXPECT_EQ(n * 60, absl::ToInt64Minutes(hour));
+  EXPECT_EQ(n, absl::ToInt64Hours(hour));
+}
+
+TEST(Duration, ToConversionDeprecated) {
+  TestToConversion<43>();
+  TestToConversion<1>();
+  TestToConversion<0>();
+  TestToConversion<-1>();
+  TestToConversion<-43>();
+}
+
+// Used for testing the factory overloads.
+template <typename T>
+struct ImplicitlyConvertible {
+  T n_;
+  explicit ImplicitlyConvertible(T n) : n_(n) {}
+  // Marking this conversion operator with 'explicit' will cause the test to
+  // fail (as desired).
+  operator T() { return n_; }
+};
+
+TEST(Duration, FactoryOverloads) {
+#define TEST_FACTORY_OVERLOADS(NAME)                                          \
+  EXPECT_EQ(1, NAME(static_cast<int8_t>(1)) / NAME(1));                       \
+  EXPECT_EQ(1, NAME(static_cast<int16_t>(1)) / NAME(1));                      \
+  EXPECT_EQ(1, NAME(static_cast<int32_t>(1)) / NAME(1));                      \
+  EXPECT_EQ(1, NAME(static_cast<int64_t>(1)) / NAME(1));                      \
+  EXPECT_EQ(1, NAME(static_cast<uint8_t>(1)) / NAME(1));                      \
+  EXPECT_EQ(1, NAME(static_cast<uint16_t>(1)) / NAME(1));                     \
+  EXPECT_EQ(1, NAME(static_cast<uint32_t>(1)) / NAME(1));                     \
+  EXPECT_EQ(1, NAME(static_cast<uint64_t>(1)) / NAME(1));                     \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<int8_t>(1)) / NAME(1));             \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<int16_t>(1)) / NAME(1));            \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<int32_t>(1)) / NAME(1));            \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<int64_t>(1)) / NAME(1));            \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint8_t>(1)) / NAME(1));            \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint16_t>(1)) / NAME(1));           \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint32_t>(1)) / NAME(1));           \
+  EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint64_t>(1)) / NAME(1));           \
+  EXPECT_EQ(NAME(1) / 2, NAME(static_cast<float>(0.5)));                      \
+  EXPECT_EQ(NAME(1) / 2, NAME(static_cast<double>(0.5)));                     \
+  EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast<float>(1.5)), NAME(1))); \
+  EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast<double>(1.5)), NAME(1)));
+
+  TEST_FACTORY_OVERLOADS(absl::Nanoseconds);
+  TEST_FACTORY_OVERLOADS(absl::Microseconds);
+  TEST_FACTORY_OVERLOADS(absl::Milliseconds);
+  TEST_FACTORY_OVERLOADS(absl::Seconds);
+  TEST_FACTORY_OVERLOADS(absl::Minutes);
+  TEST_FACTORY_OVERLOADS(absl::Hours);
+
+#undef TEST_FACTORY_OVERLOADS
+
+  EXPECT_EQ(absl::Milliseconds(1500), absl::Seconds(1.5));
+  EXPECT_LT(absl::Nanoseconds(1), absl::Nanoseconds(1.5));
+  EXPECT_GT(absl::Nanoseconds(2), absl::Nanoseconds(1.5));
+
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+  EXPECT_EQ(absl::InfiniteDuration(), absl::Nanoseconds(dbl_inf));
+  EXPECT_EQ(absl::InfiniteDuration(), absl::Microseconds(dbl_inf));
+  EXPECT_EQ(absl::InfiniteDuration(), absl::Milliseconds(dbl_inf));
+  EXPECT_EQ(absl::InfiniteDuration(), absl::Seconds(dbl_inf));
+  EXPECT_EQ(absl::InfiniteDuration(), absl::Minutes(dbl_inf));
+  EXPECT_EQ(absl::InfiniteDuration(), absl::Hours(dbl_inf));
+  EXPECT_EQ(-absl::InfiniteDuration(), absl::Nanoseconds(-dbl_inf));
+  EXPECT_EQ(-absl::InfiniteDuration(), absl::Microseconds(-dbl_inf));
+  EXPECT_EQ(-absl::InfiniteDuration(), absl::Milliseconds(-dbl_inf));
+  EXPECT_EQ(-absl::InfiniteDuration(), absl::Seconds(-dbl_inf));
+  EXPECT_EQ(-absl::InfiniteDuration(), absl::Minutes(-dbl_inf));
+  EXPECT_EQ(-absl::InfiniteDuration(), absl::Hours(-dbl_inf));
+}
+
+TEST(Duration, InfinityExamples) {
+  // These examples are used in the documentation in //base/time.h. They are
+  // written so that they can be copy-n-pasted easily.
+
+  constexpr absl::Duration inf = absl::InfiniteDuration();
+  constexpr absl::Duration d = absl::Seconds(1);  // Any finite duration
+
+  EXPECT_TRUE(inf == inf + inf);
+  EXPECT_TRUE(inf == inf + d);
+  EXPECT_TRUE(inf == inf - inf);
+  EXPECT_TRUE(-inf == d - inf);
+
+  EXPECT_TRUE(inf == d * 1e100);
+  EXPECT_TRUE(0 == d / inf);  // NOLINT(readability/check)
+
+  // Division by zero returns infinity, or kint64min/MAX where necessary.
+  EXPECT_TRUE(inf == d / 0);
+  EXPECT_TRUE(kint64max == d / absl::ZeroDuration());
+}
+
+TEST(Duration, InfinityComparison) {
+  const absl::Duration inf = absl::InfiniteDuration();
+  const absl::Duration any_dur = absl::Seconds(1);
+
+  // Equality
+  EXPECT_EQ(inf, inf);
+  EXPECT_EQ(-inf, -inf);
+  EXPECT_NE(inf, -inf);
+  EXPECT_NE(any_dur, inf);
+  EXPECT_NE(any_dur, -inf);
+
+  // Relational
+  EXPECT_GT(inf, any_dur);
+  EXPECT_LT(-inf, any_dur);
+  EXPECT_LT(-inf, inf);
+  EXPECT_GT(inf, -inf);
+}
+
+TEST(Duration, InfinityAddition) {
+  const absl::Duration sec_max = absl::Seconds(kint64max);
+  const absl::Duration sec_min = absl::Seconds(kint64min);
+  const absl::Duration any_dur = absl::Seconds(1);
+  const absl::Duration inf = absl::InfiniteDuration();
+
+  // Addition
+  EXPECT_EQ(inf, inf + inf);
+  EXPECT_EQ(inf, inf + -inf);
+  EXPECT_EQ(-inf, -inf + inf);
+  EXPECT_EQ(-inf, -inf + -inf);
+
+  EXPECT_EQ(inf, inf + any_dur);
+  EXPECT_EQ(inf, any_dur + inf);
+  EXPECT_EQ(-inf, -inf + any_dur);
+  EXPECT_EQ(-inf, any_dur + -inf);
+
+  // Interesting case
+  absl::Duration almost_inf = sec_max + absl::Nanoseconds(999999999);
+  EXPECT_GT(inf, almost_inf);
+  almost_inf += -absl::Nanoseconds(999999999);
+  EXPECT_GT(inf, almost_inf);
+
+  // Addition overflow/underflow
+  EXPECT_EQ(inf, sec_max + absl::Seconds(1));
+  EXPECT_EQ(inf, sec_max + sec_max);
+  EXPECT_EQ(-inf, sec_min + -absl::Seconds(1));
+  EXPECT_EQ(-inf, sec_min + -sec_max);
+
+  // For reference: IEEE 754 behavior
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+  EXPECT_TRUE(isinf(dbl_inf + dbl_inf));
+  EXPECT_TRUE(isnan(dbl_inf + -dbl_inf));  // We return inf
+  EXPECT_TRUE(isnan(-dbl_inf + dbl_inf));  // We return inf
+  EXPECT_TRUE(isinf(-dbl_inf + -dbl_inf));
+}
+
+TEST(Duration, InfinitySubtraction) {
+  const absl::Duration sec_max = absl::Seconds(kint64max);
+  const absl::Duration sec_min = absl::Seconds(kint64min);
+  const absl::Duration any_dur = absl::Seconds(1);
+  const absl::Duration inf = absl::InfiniteDuration();
+
+  // Subtraction
+  EXPECT_EQ(inf, inf - inf);
+  EXPECT_EQ(inf, inf - -inf);
+  EXPECT_EQ(-inf, -inf - inf);
+  EXPECT_EQ(-inf, -inf - -inf);
+
+  EXPECT_EQ(inf, inf - any_dur);
+  EXPECT_EQ(-inf, any_dur - inf);
+  EXPECT_EQ(-inf, -inf - any_dur);
+  EXPECT_EQ(inf, any_dur - -inf);
+
+  // Subtraction overflow/underflow
+  EXPECT_EQ(inf, sec_max - -absl::Seconds(1));
+  EXPECT_EQ(inf, sec_max - -sec_max);
+  EXPECT_EQ(-inf, sec_min - absl::Seconds(1));
+  EXPECT_EQ(-inf, sec_min - sec_max);
+
+  // Interesting case
+  absl::Duration almost_neg_inf = sec_min;
+  EXPECT_LT(-inf, almost_neg_inf);
+  almost_neg_inf -= -absl::Nanoseconds(1);
+  EXPECT_LT(-inf, almost_neg_inf);
+
+  // For reference: IEEE 754 behavior
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+  EXPECT_TRUE(isnan(dbl_inf - dbl_inf));  // We return inf
+  EXPECT_TRUE(isinf(dbl_inf - -dbl_inf));
+  EXPECT_TRUE(isinf(-dbl_inf - dbl_inf));
+  EXPECT_TRUE(isnan(-dbl_inf - -dbl_inf));  // We return inf
+}
+
+TEST(Duration, InfinityMultiplication) {
+  const absl::Duration sec_max = absl::Seconds(kint64max);
+  const absl::Duration sec_min = absl::Seconds(kint64min);
+  const absl::Duration inf = absl::InfiniteDuration();
+
+#define TEST_INF_MUL_WITH_TYPE(T)                                     \
+  EXPECT_EQ(inf, inf * static_cast<T>(2));                            \
+  EXPECT_EQ(-inf, inf * static_cast<T>(-2));                          \
+  EXPECT_EQ(-inf, -inf * static_cast<T>(2));                          \
+  EXPECT_EQ(inf, -inf * static_cast<T>(-2));                          \
+  EXPECT_EQ(inf, inf * static_cast<T>(0));                            \
+  EXPECT_EQ(-inf, -inf * static_cast<T>(0));                          \
+  EXPECT_EQ(inf, sec_max * static_cast<T>(2));                        \
+  EXPECT_EQ(inf, sec_min * static_cast<T>(-2));                       \
+  EXPECT_EQ(inf, (sec_max / static_cast<T>(2)) * static_cast<T>(3));  \
+  EXPECT_EQ(-inf, sec_max * static_cast<T>(-2));                      \
+  EXPECT_EQ(-inf, sec_min * static_cast<T>(2));                       \
+  EXPECT_EQ(-inf, (sec_min / static_cast<T>(2)) * static_cast<T>(3));
+
+  TEST_INF_MUL_WITH_TYPE(int64_t);  // NOLINT(readability/function)
+  TEST_INF_MUL_WITH_TYPE(double);   // NOLINT(readability/function)
+
+#undef TEST_INF_MUL_WITH_TYPE
+
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+  EXPECT_EQ(inf, inf * dbl_inf);
+  EXPECT_EQ(-inf, -inf * dbl_inf);
+  EXPECT_EQ(-inf, inf * -dbl_inf);
+  EXPECT_EQ(inf, -inf * -dbl_inf);
+
+  const absl::Duration any_dur = absl::Seconds(1);
+  EXPECT_EQ(inf, any_dur * dbl_inf);
+  EXPECT_EQ(-inf, -any_dur * dbl_inf);
+  EXPECT_EQ(-inf, any_dur * -dbl_inf);
+  EXPECT_EQ(inf, -any_dur * -dbl_inf);
+
+  // Fixed-point multiplication will produce a finite value, whereas floating
+  // point fuzziness will overflow to inf.
+  EXPECT_NE(absl::InfiniteDuration(), absl::Seconds(1) * kint64max);
+  EXPECT_EQ(inf, absl::Seconds(1) * static_cast<double>(kint64max));
+  EXPECT_NE(-absl::InfiniteDuration(), absl::Seconds(1) * kint64min);
+  EXPECT_EQ(-inf, absl::Seconds(1) * static_cast<double>(kint64min));
+
+  // Note that sec_max * or / by 1.0 overflows to inf due to the 53-bit
+  // limitations of double.
+  EXPECT_NE(inf, sec_max);
+  EXPECT_NE(inf, sec_max / 1);
+  EXPECT_EQ(inf, sec_max / 1.0);
+  EXPECT_NE(inf, sec_max * 1);
+  EXPECT_EQ(inf, sec_max * 1.0);
+}
+
+TEST(Duration, InfinityDivision) {
+  const absl::Duration sec_max = absl::Seconds(kint64max);
+  const absl::Duration sec_min = absl::Seconds(kint64min);
+  const absl::Duration inf = absl::InfiniteDuration();
+
+  // Division of Duration by a double
+#define TEST_INF_DIV_WITH_TYPE(T)            \
+  EXPECT_EQ(inf, inf / static_cast<T>(2));   \
+  EXPECT_EQ(-inf, inf / static_cast<T>(-2)); \
+  EXPECT_EQ(-inf, -inf / static_cast<T>(2)); \
+  EXPECT_EQ(inf, -inf / static_cast<T>(-2));
+
+  TEST_INF_DIV_WITH_TYPE(int64_t);  // NOLINT(readability/function)
+  TEST_INF_DIV_WITH_TYPE(double);   // NOLINT(readability/function)
+
+#undef TEST_INF_DIV_WITH_TYPE
+
+  // Division of Duration by a double overflow/underflow
+  EXPECT_EQ(inf, sec_max / 0.5);
+  EXPECT_EQ(inf, sec_min / -0.5);
+  EXPECT_EQ(inf, ((sec_max / 0.5) + absl::Seconds(1)) / 0.5);
+  EXPECT_EQ(-inf, sec_max / -0.5);
+  EXPECT_EQ(-inf, sec_min / 0.5);
+  EXPECT_EQ(-inf, ((sec_min / 0.5) - absl::Seconds(1)) / 0.5);
+
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+  EXPECT_EQ(inf, inf / dbl_inf);
+  EXPECT_EQ(-inf, inf / -dbl_inf);
+  EXPECT_EQ(-inf, -inf / dbl_inf);
+  EXPECT_EQ(inf, -inf / -dbl_inf);
+
+  const absl::Duration any_dur = absl::Seconds(1);
+  EXPECT_EQ(absl::ZeroDuration(), any_dur / dbl_inf);
+  EXPECT_EQ(absl::ZeroDuration(), any_dur / -dbl_inf);
+  EXPECT_EQ(absl::ZeroDuration(), -any_dur / dbl_inf);
+  EXPECT_EQ(absl::ZeroDuration(), -any_dur / -dbl_inf);
+}
+
+TEST(Duration, InfinityModulus) {
+  const absl::Duration sec_max = absl::Seconds(kint64max);
+  const absl::Duration any_dur = absl::Seconds(1);
+  const absl::Duration inf = absl::InfiniteDuration();
+
+  EXPECT_EQ(inf, inf % inf);
+  EXPECT_EQ(inf, inf % -inf);
+  EXPECT_EQ(-inf, -inf % -inf);
+  EXPECT_EQ(-inf, -inf % inf);
+
+  EXPECT_EQ(any_dur, any_dur % inf);
+  EXPECT_EQ(any_dur, any_dur % -inf);
+  EXPECT_EQ(-any_dur, -any_dur % inf);
+  EXPECT_EQ(-any_dur, -any_dur % -inf);
+
+  EXPECT_EQ(inf, inf % -any_dur);
+  EXPECT_EQ(inf, inf % any_dur);
+  EXPECT_EQ(-inf, -inf % -any_dur);
+  EXPECT_EQ(-inf, -inf % any_dur);
+
+  // Remainder isn't affected by overflow.
+  EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Seconds(1));
+  EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Milliseconds(1));
+  EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Microseconds(1));
+  EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Nanoseconds(1));
+  EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Nanoseconds(1) / 4);
+}
+
+TEST(Duration, InfinityIDiv) {
+  const absl::Duration sec_max = absl::Seconds(kint64max);
+  const absl::Duration any_dur = absl::Seconds(1);
+  const absl::Duration inf = absl::InfiniteDuration();
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+
+  // IDivDuration (int64_t return value + a remainer)
+  absl::Duration rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64max, absl::IDivDuration(inf, inf, &rem));
+  EXPECT_EQ(inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64max, absl::IDivDuration(-inf, -inf, &rem));
+  EXPECT_EQ(-inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64max, absl::IDivDuration(inf, any_dur, &rem));
+  EXPECT_EQ(inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(0, absl::IDivDuration(any_dur, inf, &rem));
+  EXPECT_EQ(any_dur, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64max, absl::IDivDuration(-inf, -any_dur, &rem));
+  EXPECT_EQ(-inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(0, absl::IDivDuration(-any_dur, -inf, &rem));
+  EXPECT_EQ(-any_dur, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64min, absl::IDivDuration(-inf, inf, &rem));
+  EXPECT_EQ(-inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64min, absl::IDivDuration(inf, -inf, &rem));
+  EXPECT_EQ(inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64min, absl::IDivDuration(-inf, any_dur, &rem));
+  EXPECT_EQ(-inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(0, absl::IDivDuration(-any_dur, inf, &rem));
+  EXPECT_EQ(-any_dur, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(kint64min, absl::IDivDuration(inf, -any_dur, &rem));
+  EXPECT_EQ(inf, rem);
+
+  rem = absl::ZeroDuration();
+  EXPECT_EQ(0, absl::IDivDuration(any_dur, -inf, &rem));
+  EXPECT_EQ(any_dur, rem);
+
+  // IDivDuration overflow/underflow
+  rem = any_dur;
+  EXPECT_EQ(kint64max,
+            absl::IDivDuration(sec_max, absl::Nanoseconds(1) / 4, &rem));
+  EXPECT_EQ(sec_max - absl::Nanoseconds(kint64max) / 4, rem);
+
+  rem = any_dur;
+  EXPECT_EQ(kint64max,
+            absl::IDivDuration(sec_max, absl::Milliseconds(1), &rem));
+  EXPECT_EQ(sec_max - absl::Milliseconds(kint64max), rem);
+
+  rem = any_dur;
+  EXPECT_EQ(kint64max,
+            absl::IDivDuration(-sec_max, -absl::Milliseconds(1), &rem));
+  EXPECT_EQ(-sec_max + absl::Milliseconds(kint64max), rem);
+
+  rem = any_dur;
+  EXPECT_EQ(kint64min,
+            absl::IDivDuration(-sec_max, absl::Milliseconds(1), &rem));
+  EXPECT_EQ(-sec_max - absl::Milliseconds(kint64min), rem);
+
+  rem = any_dur;
+  EXPECT_EQ(kint64min,
+            absl::IDivDuration(sec_max, -absl::Milliseconds(1), &rem));
+  EXPECT_EQ(sec_max + absl::Milliseconds(kint64min), rem);
+
+  //
+  // operator/(Duration, Duration) is a wrapper for IDivDuration().
+  //
+
+  // IEEE 754 says inf / inf should be nan, but int64_t doesn't have
+  // nan so we'll return kint64max/kint64min instead.
+  EXPECT_TRUE(isnan(dbl_inf / dbl_inf));
+  EXPECT_EQ(kint64max, inf / inf);
+  EXPECT_EQ(kint64max, -inf / -inf);
+  EXPECT_EQ(kint64min, -inf / inf);
+  EXPECT_EQ(kint64min, inf / -inf);
+
+  EXPECT_TRUE(isinf(dbl_inf / 2.0));
+  EXPECT_EQ(kint64max, inf / any_dur);
+  EXPECT_EQ(kint64max, -inf / -any_dur);
+  EXPECT_EQ(kint64min, -inf / any_dur);
+  EXPECT_EQ(kint64min, inf / -any_dur);
+
+  EXPECT_EQ(0.0, 2.0 / dbl_inf);
+  EXPECT_EQ(0, any_dur / inf);
+  EXPECT_EQ(0, any_dur / -inf);
+  EXPECT_EQ(0, -any_dur / inf);
+  EXPECT_EQ(0, -any_dur / -inf);
+  EXPECT_EQ(0, absl::ZeroDuration() / inf);
+
+  // Division of Duration by a Duration overflow/underflow
+  EXPECT_EQ(kint64max, sec_max / absl::Milliseconds(1));
+  EXPECT_EQ(kint64max, -sec_max / -absl::Milliseconds(1));
+  EXPECT_EQ(kint64min, -sec_max / absl::Milliseconds(1));
+  EXPECT_EQ(kint64min, sec_max / -absl::Milliseconds(1));
+}
+
+TEST(Duration, InfinityFDiv) {
+  const absl::Duration any_dur = absl::Seconds(1);
+  const absl::Duration inf = absl::InfiniteDuration();
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+
+  EXPECT_EQ(dbl_inf, absl::FDivDuration(inf, inf));
+  EXPECT_EQ(dbl_inf, absl::FDivDuration(-inf, -inf));
+  EXPECT_EQ(dbl_inf, absl::FDivDuration(inf, any_dur));
+  EXPECT_EQ(0.0, absl::FDivDuration(any_dur, inf));
+  EXPECT_EQ(dbl_inf, absl::FDivDuration(-inf, -any_dur));
+  EXPECT_EQ(0.0, absl::FDivDuration(-any_dur, -inf));
+
+  EXPECT_EQ(-dbl_inf, absl::FDivDuration(-inf, inf));
+  EXPECT_EQ(-dbl_inf, absl::FDivDuration(inf, -inf));
+  EXPECT_EQ(-dbl_inf, absl::FDivDuration(-inf, any_dur));
+  EXPECT_EQ(0.0, absl::FDivDuration(-any_dur, inf));
+  EXPECT_EQ(-dbl_inf, absl::FDivDuration(inf, -any_dur));
+  EXPECT_EQ(0.0, absl::FDivDuration(any_dur, -inf));
+}
+
+TEST(Duration, DivisionByZero) {
+  const absl::Duration zero = absl::ZeroDuration();
+  const absl::Duration inf = absl::InfiniteDuration();
+  const absl::Duration any_dur = absl::Seconds(1);
+  const double dbl_inf = std::numeric_limits<double>::infinity();
+  const double dbl_denorm = std::numeric_limits<double>::denorm_min();
+
+  // IEEE 754 behavior
+  double z = 0.0, two = 2.0;
+  EXPECT_TRUE(isinf(two / z));
+  EXPECT_TRUE(isnan(z / z));  // We'll return inf
+
+  // Operator/(Duration, double)
+  EXPECT_EQ(inf, zero / 0.0);
+  EXPECT_EQ(-inf, zero / -0.0);
+  EXPECT_EQ(inf, any_dur / 0.0);
+  EXPECT_EQ(-inf, any_dur / -0.0);
+  EXPECT_EQ(-inf, -any_dur / 0.0);
+  EXPECT_EQ(inf, -any_dur / -0.0);
+
+  // Tests dividing by a number very close to, but not quite zero.
+  EXPECT_EQ(zero, zero / dbl_denorm);
+  EXPECT_EQ(zero, zero / -dbl_denorm);
+  EXPECT_EQ(inf, any_dur / dbl_denorm);
+  EXPECT_EQ(-inf, any_dur / -dbl_denorm);
+  EXPECT_EQ(-inf, -any_dur / dbl_denorm);
+  EXPECT_EQ(inf, -any_dur / -dbl_denorm);
+
+  // IDiv
+  absl::Duration rem = zero;
+  EXPECT_EQ(kint64max, absl::IDivDuration(zero, zero, &rem));
+  EXPECT_EQ(inf, rem);
+
+  rem = zero;
+  EXPECT_EQ(kint64max, absl::IDivDuration(any_dur, zero, &rem));
+  EXPECT_EQ(inf, rem);
+
+  rem = zero;
+  EXPECT_EQ(kint64min, absl::IDivDuration(-any_dur, zero, &rem));
+  EXPECT_EQ(-inf, rem);
+
+  // Operator/(Duration, Duration)
+  EXPECT_EQ(kint64max, zero / zero);
+  EXPECT_EQ(kint64max, any_dur / zero);
+  EXPECT_EQ(kint64min, -any_dur / zero);
+
+  // FDiv
+  EXPECT_EQ(dbl_inf, absl::FDivDuration(zero, zero));
+  EXPECT_EQ(dbl_inf, absl::FDivDuration(any_dur, zero));
+  EXPECT_EQ(-dbl_inf, absl::FDivDuration(-any_dur, zero));
+}
+
+TEST(Duration, Range) {
+  const absl::Duration range = ApproxYears(100 * 1e9);
+  const absl::Duration range_future = range;
+  const absl::Duration range_past = -range;
+
+  EXPECT_LT(range_future, absl::InfiniteDuration());
+  EXPECT_GT(range_past, -absl::InfiniteDuration());
+
+  const absl::Duration full_range = range_future - range_past;
+  EXPECT_GT(full_range, absl::ZeroDuration());
+  EXPECT_LT(full_range, absl::InfiniteDuration());
+
+  const absl::Duration neg_full_range = range_past - range_future;
+  EXPECT_LT(neg_full_range, absl::ZeroDuration());
+  EXPECT_GT(neg_full_range, -absl::InfiniteDuration());
+
+  EXPECT_LT(neg_full_range, full_range);
+  EXPECT_EQ(neg_full_range, -full_range);
+}
+
+TEST(Duration, RelationalOperators) {
+#define TEST_REL_OPS(UNIT)               \
+  static_assert(UNIT(2) == UNIT(2), ""); \
+  static_assert(UNIT(1) != UNIT(2), ""); \
+  static_assert(UNIT(1) < UNIT(2), "");  \
+  static_assert(UNIT(3) > UNIT(2), "");  \
+  static_assert(UNIT(1) <= UNIT(2), ""); \
+  static_assert(UNIT(2) <= UNIT(2), ""); \
+  static_assert(UNIT(3) >= UNIT(2), ""); \
+  static_assert(UNIT(2) >= UNIT(2), "");
+
+  TEST_REL_OPS(absl::Nanoseconds);
+  TEST_REL_OPS(absl::Microseconds);
+  TEST_REL_OPS(absl::Milliseconds);
+  TEST_REL_OPS(absl::Seconds);
+  TEST_REL_OPS(absl::Minutes);
+  TEST_REL_OPS(absl::Hours);
+
+#undef TEST_REL_OPS
+}
+
+TEST(Duration, Addition) {
+#define TEST_ADD_OPS(UNIT)                  \
+  do {                                      \
+    EXPECT_EQ(UNIT(2), UNIT(1) + UNIT(1));  \
+    EXPECT_EQ(UNIT(1), UNIT(2) - UNIT(1));  \
+    EXPECT_EQ(UNIT(0), UNIT(2) - UNIT(2));  \
+    EXPECT_EQ(UNIT(-1), UNIT(1) - UNIT(2)); \
+    EXPECT_EQ(UNIT(-2), UNIT(0) - UNIT(2)); \
+    EXPECT_EQ(UNIT(-2), UNIT(1) - UNIT(3)); \
+    absl::Duration a = UNIT(1);             \
+    a += UNIT(1);                           \
+    EXPECT_EQ(UNIT(2), a);                  \
+    a -= UNIT(1);                           \
+    EXPECT_EQ(UNIT(1), a);                  \
+  } while (0)
+
+  TEST_ADD_OPS(absl::Nanoseconds);
+  TEST_ADD_OPS(absl::Microseconds);
+  TEST_ADD_OPS(absl::Milliseconds);
+  TEST_ADD_OPS(absl::Seconds);
+  TEST_ADD_OPS(absl::Minutes);
+  TEST_ADD_OPS(absl::Hours);
+
+#undef TEST_ADD_OPS
+
+  EXPECT_EQ(absl::Seconds(2), absl::Seconds(3) - 2 * absl::Milliseconds(500));
+  EXPECT_EQ(absl::Seconds(2) + absl::Milliseconds(500),
+            absl::Seconds(3) - absl::Milliseconds(500));
+
+  EXPECT_EQ(absl::Seconds(1) + absl::Milliseconds(998),
+            absl::Milliseconds(999) + absl::Milliseconds(999));
+
+  EXPECT_EQ(absl::Milliseconds(-1),
+            absl::Milliseconds(998) - absl::Milliseconds(999));
+
+  // Tests fractions of a nanoseconds. These are implementation details only.
+  EXPECT_GT(absl::Nanoseconds(1), absl::Nanoseconds(1) / 2);
+  EXPECT_EQ(absl::Nanoseconds(1),
+            absl::Nanoseconds(1) / 2 + absl::Nanoseconds(1) / 2);
+  EXPECT_GT(absl::Nanoseconds(1) / 4, absl::Nanoseconds(0));
+  EXPECT_EQ(absl::Nanoseconds(1) / 8, absl::Nanoseconds(0));
+
+  // Tests subtraction that will cause wrap around of the rep_lo_ bits.
+  absl::Duration d_7_5 = absl::Seconds(7) + absl::Milliseconds(500);
+  absl::Duration d_3_7 = absl::Seconds(3) + absl::Milliseconds(700);
+  absl::Duration ans_3_8 = absl::Seconds(3) + absl::Milliseconds(800);
+  EXPECT_EQ(ans_3_8, d_7_5 - d_3_7);
+
+  // Subtracting min_duration
+  absl::Duration min_dur = absl::Seconds(kint64min);
+  EXPECT_EQ(absl::Seconds(0), min_dur - min_dur);
+  EXPECT_EQ(absl::Seconds(kint64max), absl::Seconds(-1) - min_dur);
+}
+
+TEST(Duration, Negation) {
+  // By storing negations of various values in constexpr variables we
+  // verify that the initializers are constant expressions.
+  constexpr absl::Duration negated_zero_duration = -absl::ZeroDuration();
+  EXPECT_EQ(negated_zero_duration, absl::ZeroDuration());
+
+  constexpr absl::Duration negated_infinite_duration =
+      -absl::InfiniteDuration();
+  EXPECT_NE(negated_infinite_duration, absl::InfiniteDuration());
+  EXPECT_EQ(-negated_infinite_duration, absl::InfiniteDuration());
+
+  // The public APIs to check if a duration is infinite depend on using
+  // -InfiniteDuration(), but we're trying to test operator- here, so we
+  // need to use the lower-level internal query IsInfiniteDuration.
+  EXPECT_TRUE(
+      absl::time_internal::IsInfiniteDuration(negated_infinite_duration));
+
+  // The largest Duration is kint64max seconds and kTicksPerSecond - 1 ticks.
+  // Using the absl::time_internal::MakeDuration API is the cleanest way to
+  // construct that Duration.
+  constexpr absl::Duration max_duration = absl::time_internal::MakeDuration(
+      kint64max, absl::time_internal::kTicksPerSecond - 1);
+  constexpr absl::Duration negated_max_duration = -max_duration;
+  // The largest negatable value is one tick above the minimum representable;
+  // it's the negation of max_duration.
+  constexpr absl::Duration nearly_min_duration =
+      absl::time_internal::MakeDuration(kint64min, int64_t{1});
+  constexpr absl::Duration negated_nearly_min_duration = -nearly_min_duration;
+
+  EXPECT_EQ(negated_max_duration, nearly_min_duration);
+  EXPECT_EQ(negated_nearly_min_duration, max_duration);
+  EXPECT_EQ(-(-max_duration), max_duration);
+
+  constexpr absl::Duration min_duration =
+      absl::time_internal::MakeDuration(kint64min);
+  constexpr absl::Duration negated_min_duration = -min_duration;
+  EXPECT_EQ(negated_min_duration, absl::InfiniteDuration());
+}
+
+TEST(Duration, AbsoluteValue) {
+  EXPECT_EQ(absl::ZeroDuration(), AbsDuration(absl::ZeroDuration()));
+  EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(1)));
+  EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(-1)));
+
+  EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(absl::InfiniteDuration()));
+  EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(-absl::InfiniteDuration()));
+
+  absl::Duration max_dur =
+      absl::Seconds(kint64max) + (absl::Seconds(1) - absl::Nanoseconds(1) / 4);
+  EXPECT_EQ(max_dur, AbsDuration(max_dur));
+
+  absl::Duration min_dur = absl::Seconds(kint64min);
+  EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(min_dur));
+  EXPECT_EQ(max_dur, AbsDuration(min_dur + absl::Nanoseconds(1) / 4));
+}
+
+TEST(Duration, Multiplication) {
+#define TEST_MUL_OPS(UNIT)                                    \
+  do {                                                        \
+    EXPECT_EQ(UNIT(5), UNIT(2) * 2.5);                        \
+    EXPECT_EQ(UNIT(2), UNIT(5) / 2.5);                        \
+    EXPECT_EQ(UNIT(-5), UNIT(-2) * 2.5);                      \
+    EXPECT_EQ(UNIT(-5), -UNIT(2) * 2.5);                      \
+    EXPECT_EQ(UNIT(-5), UNIT(2) * -2.5);                      \
+    EXPECT_EQ(UNIT(-2), UNIT(-5) / 2.5);                      \
+    EXPECT_EQ(UNIT(-2), -UNIT(5) / 2.5);                      \
+    EXPECT_EQ(UNIT(-2), UNIT(5) / -2.5);                      \
+    EXPECT_EQ(UNIT(2), UNIT(11) % UNIT(3));                   \
+    absl::Duration a = UNIT(2);                               \
+    a *= 2.5;                                                 \
+    EXPECT_EQ(UNIT(5), a);                                    \
+    a /= 2.5;                                                 \
+    EXPECT_EQ(UNIT(2), a);                                    \
+    a %= UNIT(1);                                             \
+    EXPECT_EQ(UNIT(0), a);                                    \
+    absl::Duration big = UNIT(1000000000);                    \
+    big *= 3;                                                 \
+    big /= 3;                                                 \
+    EXPECT_EQ(UNIT(1000000000), big);                         \
+    EXPECT_EQ(-UNIT(2), -UNIT(2));                            \
+    EXPECT_EQ(-UNIT(2), UNIT(2) * -1);                        \
+    EXPECT_EQ(-UNIT(2), -1 * UNIT(2));                        \
+    EXPECT_EQ(-UNIT(-2), UNIT(2));                            \
+    EXPECT_EQ(2, UNIT(2) / UNIT(1));                          \
+    absl::Duration rem;                                       \
+    EXPECT_EQ(2, absl::IDivDuration(UNIT(2), UNIT(1), &rem)); \
+    EXPECT_EQ(2.0, absl::FDivDuration(UNIT(2), UNIT(1)));     \
+  } while (0)
+
+  TEST_MUL_OPS(absl::Nanoseconds);
+  TEST_MUL_OPS(absl::Microseconds);
+  TEST_MUL_OPS(absl::Milliseconds);
+  TEST_MUL_OPS(absl::Seconds);
+  TEST_MUL_OPS(absl::Minutes);
+  TEST_MUL_OPS(absl::Hours);
+
+#undef TEST_MUL_OPS
+
+  // Ensures that multiplication and division by 1 with a maxed-out durations
+  // doesn't lose precision.
+  absl::Duration max_dur =
+      absl::Seconds(kint64max) + (absl::Seconds(1) - absl::Nanoseconds(1) / 4);
+  absl::Duration min_dur = absl::Seconds(kint64min);
+  EXPECT_EQ(max_dur, max_dur * 1);
+  EXPECT_EQ(max_dur, max_dur / 1);
+  EXPECT_EQ(min_dur, min_dur * 1);
+  EXPECT_EQ(min_dur, min_dur / 1);
+
+  // Tests division on a Duration with a large number of significant digits.
+  // Tests when the digits span hi and lo as well as only in hi.
+  absl::Duration sigfigs = absl::Seconds(2000000000) + absl::Nanoseconds(3);
+  EXPECT_EQ(absl::Seconds(666666666) + absl::Nanoseconds(666666667) +
+                absl::Nanoseconds(1) / 2,
+            sigfigs / 3);
+  sigfigs = absl::Seconds(7000000000LL);
+  EXPECT_EQ(absl::Seconds(2333333333) + absl::Nanoseconds(333333333) +
+                absl::Nanoseconds(1) / 4,
+            sigfigs / 3);
+
+  EXPECT_EQ(absl::Seconds(7) + absl::Milliseconds(500), absl::Seconds(3) * 2.5);
+  EXPECT_EQ(absl::Seconds(8) * -1 + absl::Milliseconds(300),
+            (absl::Seconds(2) + absl::Milliseconds(200)) * -3.5);
+  EXPECT_EQ(-absl::Seconds(8) + absl::Milliseconds(300),
+            (absl::Seconds(2) + absl::Milliseconds(200)) * -3.5);
+  EXPECT_EQ(absl::Seconds(1) + absl::Milliseconds(875),
+            (absl::Seconds(7) + absl::Milliseconds(500)) / 4);
+  EXPECT_EQ(absl::Seconds(30),
+            (absl::Seconds(7) + absl::Milliseconds(500)) / 0.25);
+  EXPECT_EQ(absl::Seconds(3),
+            (absl::Seconds(7) + absl::Milliseconds(500)) / 2.5);
+
+  // Tests division remainder.
+  EXPECT_EQ(absl::Nanoseconds(0), absl::Nanoseconds(7) % absl::Nanoseconds(1));
+  EXPECT_EQ(absl::Nanoseconds(0), absl::Nanoseconds(0) % absl::Nanoseconds(10));
+  EXPECT_EQ(absl::Nanoseconds(2), absl::Nanoseconds(7) % absl::Nanoseconds(5));
+  EXPECT_EQ(absl::Nanoseconds(2), absl::Nanoseconds(2) % absl::Nanoseconds(5));
+
+  EXPECT_EQ(absl::Nanoseconds(1), absl::Nanoseconds(10) % absl::Nanoseconds(3));
+  EXPECT_EQ(absl::Nanoseconds(1),
+            absl::Nanoseconds(10) % absl::Nanoseconds(-3));
+  EXPECT_EQ(absl::Nanoseconds(-1),
+            absl::Nanoseconds(-10) % absl::Nanoseconds(3));
+  EXPECT_EQ(absl::Nanoseconds(-1),
+            absl::Nanoseconds(-10) % absl::Nanoseconds(-3));
+
+  EXPECT_EQ(absl::Milliseconds(100),
+            absl::Seconds(1) % absl::Milliseconds(300));
+  EXPECT_EQ(
+      absl::Milliseconds(300),
+      (absl::Seconds(3) + absl::Milliseconds(800)) % absl::Milliseconds(500));
+
+  EXPECT_EQ(absl::Nanoseconds(1), absl::Nanoseconds(1) % absl::Seconds(1));
+  EXPECT_EQ(absl::Nanoseconds(-1), absl::Nanoseconds(-1) % absl::Seconds(1));
+  EXPECT_EQ(0, absl::Nanoseconds(-1) / absl::Seconds(1));  // Actual -1e-9
+
+  // Tests identity a = (a/b)*b + a%b
+#define TEST_MOD_IDENTITY(a, b) \
+  EXPECT_EQ((a), ((a) / (b))*(b) + ((a)%(b)))
+
+  TEST_MOD_IDENTITY(absl::Seconds(0), absl::Seconds(2));
+  TEST_MOD_IDENTITY(absl::Seconds(1), absl::Seconds(1));
+  TEST_MOD_IDENTITY(absl::Seconds(1), absl::Seconds(2));
+  TEST_MOD_IDENTITY(absl::Seconds(2), absl::Seconds(1));
+
+  TEST_MOD_IDENTITY(absl::Seconds(-2), absl::Seconds(1));
+  TEST_MOD_IDENTITY(absl::Seconds(2), absl::Seconds(-1));
+  TEST_MOD_IDENTITY(absl::Seconds(-2), absl::Seconds(-1));
+
+  TEST_MOD_IDENTITY(absl::Nanoseconds(0), absl::Nanoseconds(2));
+  TEST_MOD_IDENTITY(absl::Nanoseconds(1), absl::Nanoseconds(1));
+  TEST_MOD_IDENTITY(absl::Nanoseconds(1), absl::Nanoseconds(2));
+  TEST_MOD_IDENTITY(absl::Nanoseconds(2), absl::Nanoseconds(1));
+
+  TEST_MOD_IDENTITY(absl::Nanoseconds(-2), absl::Nanoseconds(1));
+  TEST_MOD_IDENTITY(absl::Nanoseconds(2), absl::Nanoseconds(-1));
+  TEST_MOD_IDENTITY(absl::Nanoseconds(-2), absl::Nanoseconds(-1));
+
+  // Mixed seconds + subseconds
+  absl::Duration mixed_a = absl::Seconds(1) + absl::Nanoseconds(2);
+  absl::Duration mixed_b = absl::Seconds(1) + absl::Nanoseconds(3);
+
+  TEST_MOD_IDENTITY(absl::Seconds(0), mixed_a);
+  TEST_MOD_IDENTITY(mixed_a, mixed_a);
+  TEST_MOD_IDENTITY(mixed_a, mixed_b);
+  TEST_MOD_IDENTITY(mixed_b, mixed_a);
+
+  TEST_MOD_IDENTITY(-mixed_a, mixed_b);
+  TEST_MOD_IDENTITY(mixed_a, -mixed_b);
+  TEST_MOD_IDENTITY(-mixed_a, -mixed_b);
+
+#undef TEST_MOD_IDENTITY
+}
+
+TEST(Duration, Truncation) {
+  const absl::Duration d = absl::Nanoseconds(1234567890);
+  const absl::Duration inf = absl::InfiniteDuration();
+  for (int unit_sign : {1, -1}) {  // sign shouldn't matter
+    EXPECT_EQ(absl::Nanoseconds(1234567890),
+              Trunc(d, unit_sign * absl::Nanoseconds(1)));
+    EXPECT_EQ(absl::Microseconds(1234567),
+              Trunc(d, unit_sign * absl::Microseconds(1)));
+    EXPECT_EQ(absl::Milliseconds(1234),
+              Trunc(d, unit_sign * absl::Milliseconds(1)));
+    EXPECT_EQ(absl::Seconds(1), Trunc(d, unit_sign * absl::Seconds(1)));
+    EXPECT_EQ(inf, Trunc(inf, unit_sign * absl::Seconds(1)));
+
+    EXPECT_EQ(absl::Nanoseconds(-1234567890),
+              Trunc(-d, unit_sign * absl::Nanoseconds(1)));
+    EXPECT_EQ(absl::Microseconds(-1234567),
+              Trunc(-d, unit_sign * absl::Microseconds(1)));
+    EXPECT_EQ(absl::Milliseconds(-1234),
+              Trunc(-d, unit_sign * absl::Milliseconds(1)));
+    EXPECT_EQ(absl::Seconds(-1), Trunc(-d, unit_sign * absl::Seconds(1)));
+    EXPECT_EQ(-inf, Trunc(-inf, unit_sign * absl::Seconds(1)));
+  }
+}
+
+TEST(Duration, Flooring) {
+  const absl::Duration d = absl::Nanoseconds(1234567890);
+  const absl::Duration inf = absl::InfiniteDuration();
+  for (int unit_sign : {1, -1}) {  // sign shouldn't matter
+    EXPECT_EQ(absl::Nanoseconds(1234567890),
+              absl::Floor(d, unit_sign * absl::Nanoseconds(1)));
+    EXPECT_EQ(absl::Microseconds(1234567),
+              absl::Floor(d, unit_sign * absl::Microseconds(1)));
+    EXPECT_EQ(absl::Milliseconds(1234),
+              absl::Floor(d, unit_sign * absl::Milliseconds(1)));
+    EXPECT_EQ(absl::Seconds(1), absl::Floor(d, unit_sign * absl::Seconds(1)));
+    EXPECT_EQ(inf, absl::Floor(inf, unit_sign * absl::Seconds(1)));
+
+    EXPECT_EQ(absl::Nanoseconds(-1234567890),
+              absl::Floor(-d, unit_sign * absl::Nanoseconds(1)));
+    EXPECT_EQ(absl::Microseconds(-1234568),
+              absl::Floor(-d, unit_sign * absl::Microseconds(1)));
+    EXPECT_EQ(absl::Milliseconds(-1235),
+              absl::Floor(-d, unit_sign * absl::Milliseconds(1)));
+    EXPECT_EQ(absl::Seconds(-2), absl::Floor(-d, unit_sign * absl::Seconds(1)));
+    EXPECT_EQ(-inf, absl::Floor(-inf, unit_sign * absl::Seconds(1)));
+  }
+}
+
+TEST(Duration, Ceiling) {
+  const absl::Duration d = absl::Nanoseconds(1234567890);
+  const absl::Duration inf = absl::InfiniteDuration();
+  for (int unit_sign : {1, -1}) {  // // sign shouldn't matter
+    EXPECT_EQ(absl::Nanoseconds(1234567890),
+              absl::Ceil(d, unit_sign * absl::Nanoseconds(1)));
+    EXPECT_EQ(absl::Microseconds(1234568),
+              absl::Ceil(d, unit_sign * absl::Microseconds(1)));
+    EXPECT_EQ(absl::Milliseconds(1235),
+              absl::Ceil(d, unit_sign * absl::Milliseconds(1)));
+    EXPECT_EQ(absl::Seconds(2), absl::Ceil(d, unit_sign * absl::Seconds(1)));
+    EXPECT_EQ(inf, absl::Ceil(inf, unit_sign * absl::Seconds(1)));
+
+    EXPECT_EQ(absl::Nanoseconds(-1234567890),
+              absl::Ceil(-d, unit_sign * absl::Nanoseconds(1)));
+    EXPECT_EQ(absl::Microseconds(-1234567),
+              absl::Ceil(-d, unit_sign * absl::Microseconds(1)));
+    EXPECT_EQ(absl::Milliseconds(-1234),
+              absl::Ceil(-d, unit_sign * absl::Milliseconds(1)));
+    EXPECT_EQ(absl::Seconds(-1), absl::Ceil(-d, unit_sign * absl::Seconds(1)));
+    EXPECT_EQ(-inf, absl::Ceil(-inf, unit_sign * absl::Seconds(1)));
+  }
+}
+
+TEST(Duration, RoundTripUnits) {
+  const int kRange = 100000;
+
+#define ROUND_TRIP_UNIT(U, LOW, HIGH)          \
+  do {                                         \
+    for (int64_t i = LOW; i < HIGH; ++i) {     \
+      absl::Duration d = absl::U(i);           \
+      if (d == absl::InfiniteDuration())       \
+        EXPECT_EQ(kint64max, d / absl::U(1));  \
+      else if (d == -absl::InfiniteDuration()) \
+        EXPECT_EQ(kint64min, d / absl::U(1));  \
+      else                                     \
+        EXPECT_EQ(i, absl::U(i) / absl::U(1)); \
+    }                                          \
+  } while (0)
+
+  ROUND_TRIP_UNIT(Nanoseconds, kint64min, kint64min + kRange);
+  ROUND_TRIP_UNIT(Nanoseconds, -kRange, kRange);
+  ROUND_TRIP_UNIT(Nanoseconds, kint64max - kRange, kint64max);
+
+  ROUND_TRIP_UNIT(Microseconds, kint64min, kint64min + kRange);
+  ROUND_TRIP_UNIT(Microseconds, -kRange, kRange);
+  ROUND_TRIP_UNIT(Microseconds, kint64max - kRange, kint64max);
+
+  ROUND_TRIP_UNIT(Milliseconds, kint64min, kint64min + kRange);
+  ROUND_TRIP_UNIT(Milliseconds, -kRange, kRange);
+  ROUND_TRIP_UNIT(Milliseconds, kint64max - kRange, kint64max);
+
+  ROUND_TRIP_UNIT(Seconds, kint64min, kint64min + kRange);
+  ROUND_TRIP_UNIT(Seconds, -kRange, kRange);
+  ROUND_TRIP_UNIT(Seconds, kint64max - kRange, kint64max);
+
+  ROUND_TRIP_UNIT(Minutes, kint64min / 60, kint64min / 60 + kRange);
+  ROUND_TRIP_UNIT(Minutes, -kRange, kRange);
+  ROUND_TRIP_UNIT(Minutes, kint64max / 60 - kRange, kint64max / 60);
+
+  ROUND_TRIP_UNIT(Hours, kint64min / 3600, kint64min / 3600 + kRange);
+  ROUND_TRIP_UNIT(Hours, -kRange, kRange);
+  ROUND_TRIP_UNIT(Hours, kint64max / 3600 - kRange, kint64max / 3600);
+
+#undef ROUND_TRIP_UNIT
+}
+
+TEST(Duration, TruncConversions) {
+  // Tests ToTimespec()/DurationFromTimespec()
+  const struct {
+    absl::Duration d;
+    timespec ts;
+  } to_ts[] = {
+      {absl::Seconds(1) + absl::Nanoseconds(1), {1, 1}},
+      {absl::Seconds(1) + absl::Nanoseconds(1) / 2, {1, 0}},
+      {absl::Seconds(1) + absl::Nanoseconds(0), {1, 0}},
+      {absl::Seconds(0) + absl::Nanoseconds(0), {0, 0}},
+      {absl::Seconds(0) - absl::Nanoseconds(1) / 2, {0, 0}},
+      {absl::Seconds(0) - absl::Nanoseconds(1), {-1, 999999999}},
+      {absl::Seconds(-1) + absl::Nanoseconds(1), {-1, 1}},
+      {absl::Seconds(-1) + absl::Nanoseconds(1) / 2, {-1, 1}},
+      {absl::Seconds(-1) + absl::Nanoseconds(0), {-1, 0}},
+      {absl::Seconds(-1) - absl::Nanoseconds(1) / 2, {-1, 0}},
+  };
+  for (const auto& test : to_ts) {
+    EXPECT_THAT(absl::ToTimespec(test.d), TimespecMatcher(test.ts));
+  }
+  const struct {
+    timespec ts;
+    absl::Duration d;
+  } from_ts[] = {
+      {{1, 1}, absl::Seconds(1) + absl::Nanoseconds(1)},
+      {{1, 0}, absl::Seconds(1) + absl::Nanoseconds(0)},
+      {{0, 0}, absl::Seconds(0) + absl::Nanoseconds(0)},
+      {{0, -1}, absl::Seconds(0) - absl::Nanoseconds(1)},
+      {{-1, 999999999}, absl::Seconds(0) - absl::Nanoseconds(1)},
+      {{-1, 1}, absl::Seconds(-1) + absl::Nanoseconds(1)},
+      {{-1, 0}, absl::Seconds(-1) + absl::Nanoseconds(0)},
+      {{-1, -1}, absl::Seconds(-1) - absl::Nanoseconds(1)},
+      {{-2, 999999999}, absl::Seconds(-1) - absl::Nanoseconds(1)},
+  };
+  for (const auto& test : from_ts) {
+    EXPECT_EQ(test.d, absl::DurationFromTimespec(test.ts));
+  }
+
+  // Tests ToTimeval()/DurationFromTimeval() (same as timespec above)
+  const struct {
+    absl::Duration d;
+    timeval tv;
+  } to_tv[] = {
+      {absl::Seconds(1) + absl::Microseconds(1), {1, 1}},
+      {absl::Seconds(1) + absl::Microseconds(1) / 2, {1, 0}},
+      {absl::Seconds(1) + absl::Microseconds(0), {1, 0}},
+      {absl::Seconds(0) + absl::Microseconds(0), {0, 0}},
+      {absl::Seconds(0) - absl::Microseconds(1) / 2, {0, 0}},
+      {absl::Seconds(0) - absl::Microseconds(1), {-1, 999999}},
+      {absl::Seconds(-1) + absl::Microseconds(1), {-1, 1}},
+      {absl::Seconds(-1) + absl::Microseconds(1) / 2, {-1, 1}},
+      {absl::Seconds(-1) + absl::Microseconds(0), {-1, 0}},
+      {absl::Seconds(-1) - absl::Microseconds(1) / 2, {-1, 0}},
+  };
+  for (const auto& test : to_tv) {
+    EXPECT_THAT(absl::ToTimeval(test.d), TimevalMatcher(test.tv));
+  }
+  const struct {
+    timeval tv;
+    absl::Duration d;
+  } from_tv[] = {
+      {{1, 1}, absl::Seconds(1) + absl::Microseconds(1)},
+      {{1, 0}, absl::Seconds(1) + absl::Microseconds(0)},
+      {{0, 0}, absl::Seconds(0) + absl::Microseconds(0)},
+      {{0, -1}, absl::Seconds(0) - absl::Microseconds(1)},
+      {{-1, 999999}, absl::Seconds(0) - absl::Microseconds(1)},
+      {{-1, 1}, absl::Seconds(-1) + absl::Microseconds(1)},
+      {{-1, 0}, absl::Seconds(-1) + absl::Microseconds(0)},
+      {{-1, -1}, absl::Seconds(-1) - absl::Microseconds(1)},
+      {{-2, 999999}, absl::Seconds(-1) - absl::Microseconds(1)},
+  };
+  for (const auto& test : from_tv) {
+    EXPECT_EQ(test.d, absl::DurationFromTimeval(test.tv));
+  }
+}
+
+TEST(Duration, SmallConversions) {
+  // Special tests for conversions of small durations.
+
+  EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(0));
+  // TODO(bww): Is the next one OK?
+  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;
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(0)), TimespecMatcher(ts));
+  // TODO(bww): Are the next three OK?
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(1) / 4), TimespecMatcher(ts));
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(2) / 4), TimespecMatcher(ts));
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(3) / 4), TimespecMatcher(ts));
+  ts.tv_nsec = 1;
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(4) / 4), TimespecMatcher(ts));
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(5) / 4), TimespecMatcher(ts));
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(6) / 4), TimespecMatcher(ts));
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(7) / 4), TimespecMatcher(ts));
+  ts.tv_nsec = 2;
+  EXPECT_THAT(ToTimespec(absl::Nanoseconds(8) / 4), TimespecMatcher(ts));
+
+  timeval tv;
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+  EXPECT_THAT(ToTimeval(absl::Nanoseconds(0)), TimevalMatcher(tv));
+  // TODO(bww): Is the next one OK?
+  EXPECT_THAT(ToTimeval(absl::Nanoseconds(999)), TimevalMatcher(tv));
+  tv.tv_usec = 1;
+  EXPECT_THAT(ToTimeval(absl::Nanoseconds(1000)), TimevalMatcher(tv));
+  EXPECT_THAT(ToTimeval(absl::Nanoseconds(1999)), TimevalMatcher(tv));
+  tv.tv_usec = 2;
+  EXPECT_THAT(ToTimeval(absl::Nanoseconds(2000)), TimevalMatcher(tv));
+}
+
+TEST(Duration, ConversionSaturation) {
+  absl::Duration d;
+
+  const auto max_timeval_sec =
+      std::numeric_limits<decltype(timeval::tv_sec)>::max();
+  const auto min_timeval_sec =
+      std::numeric_limits<decltype(timeval::tv_sec)>::min();
+  timeval tv;
+  tv.tv_sec = max_timeval_sec;
+  tv.tv_usec = 999998;
+  d = absl::DurationFromTimeval(tv);
+  tv = ToTimeval(d);
+  EXPECT_EQ(max_timeval_sec, tv.tv_sec);
+  EXPECT_EQ(999998, tv.tv_usec);
+  d += absl::Microseconds(1);
+  tv = ToTimeval(d);
+  EXPECT_EQ(max_timeval_sec, tv.tv_sec);
+  EXPECT_EQ(999999, tv.tv_usec);
+  d += absl::Microseconds(1);  // no effect
+  tv = ToTimeval(d);
+  EXPECT_EQ(max_timeval_sec, tv.tv_sec);
+  EXPECT_EQ(999999, tv.tv_usec);
+
+  tv.tv_sec = min_timeval_sec;
+  tv.tv_usec = 1;
+  d = absl::DurationFromTimeval(tv);
+  tv = ToTimeval(d);
+  EXPECT_EQ(min_timeval_sec, tv.tv_sec);
+  EXPECT_EQ(1, tv.tv_usec);
+  d -= absl::Microseconds(1);
+  tv = ToTimeval(d);
+  EXPECT_EQ(min_timeval_sec, tv.tv_sec);
+  EXPECT_EQ(0, tv.tv_usec);
+  d -= absl::Microseconds(1);  // no effect
+  tv = ToTimeval(d);
+  EXPECT_EQ(min_timeval_sec, tv.tv_sec);
+  EXPECT_EQ(0, tv.tv_usec);
+
+  const auto max_timespec_sec =
+      std::numeric_limits<decltype(timespec::tv_sec)>::max();
+  const auto min_timespec_sec =
+      std::numeric_limits<decltype(timespec::tv_sec)>::min();
+  timespec ts;
+  ts.tv_sec = max_timespec_sec;
+  ts.tv_nsec = 999999998;
+  d = absl::DurationFromTimespec(ts);
+  ts = absl::ToTimespec(d);
+  EXPECT_EQ(max_timespec_sec, ts.tv_sec);
+  EXPECT_EQ(999999998, ts.tv_nsec);
+  d += absl::Nanoseconds(1);
+  ts = absl::ToTimespec(d);
+  EXPECT_EQ(max_timespec_sec, ts.tv_sec);
+  EXPECT_EQ(999999999, ts.tv_nsec);
+  d += absl::Nanoseconds(1);  // no effect
+  ts = absl::ToTimespec(d);
+  EXPECT_EQ(max_timespec_sec, ts.tv_sec);
+  EXPECT_EQ(999999999, ts.tv_nsec);
+
+  ts.tv_sec = min_timespec_sec;
+  ts.tv_nsec = 1;
+  d = absl::DurationFromTimespec(ts);
+  ts = absl::ToTimespec(d);
+  EXPECT_EQ(min_timespec_sec, ts.tv_sec);
+  EXPECT_EQ(1, ts.tv_nsec);
+  d -= absl::Nanoseconds(1);
+  ts = absl::ToTimespec(d);
+  EXPECT_EQ(min_timespec_sec, ts.tv_sec);
+  EXPECT_EQ(0, ts.tv_nsec);
+  d -= absl::Nanoseconds(1);  // no effect
+  ts = absl::ToTimespec(d);
+  EXPECT_EQ(min_timespec_sec, ts.tv_sec);
+  EXPECT_EQ(0, ts.tv_nsec);
+}
+
+TEST(Duration, FormatDuration) {
+  // Example from Go's docs.
+  EXPECT_EQ("72h3m0.5s",
+            absl::FormatDuration(absl::Hours(72) + absl::Minutes(3) +
+                                 absl::Milliseconds(500)));
+  // Go's largest time: 2540400h10m10.000000000s
+  EXPECT_EQ("2540400h10m10s",
+            absl::FormatDuration(absl::Hours(2540400) + absl::Minutes(10) +
+                                 absl::Seconds(10)));
+
+  EXPECT_EQ("0", absl::FormatDuration(absl::ZeroDuration()));
+  EXPECT_EQ("0", absl::FormatDuration(absl::Seconds(0)));
+  EXPECT_EQ("0", absl::FormatDuration(absl::Nanoseconds(0)));
+
+  EXPECT_EQ("1ns", absl::FormatDuration(absl::Nanoseconds(1)));
+  EXPECT_EQ("1us", absl::FormatDuration(absl::Microseconds(1)));
+  EXPECT_EQ("1ms", absl::FormatDuration(absl::Milliseconds(1)));
+  EXPECT_EQ("1s", absl::FormatDuration(absl::Seconds(1)));
+  EXPECT_EQ("1m", absl::FormatDuration(absl::Minutes(1)));
+  EXPECT_EQ("1h", absl::FormatDuration(absl::Hours(1)));
+
+  EXPECT_EQ("1h1m", absl::FormatDuration(absl::Hours(1) + absl::Minutes(1)));
+  EXPECT_EQ("1h1s", absl::FormatDuration(absl::Hours(1) + absl::Seconds(1)));
+  EXPECT_EQ("1m1s", absl::FormatDuration(absl::Minutes(1) + absl::Seconds(1)));
+
+  EXPECT_EQ("1h0.25s",
+            absl::FormatDuration(absl::Hours(1) + absl::Milliseconds(250)));
+  EXPECT_EQ("1m0.25s",
+            absl::FormatDuration(absl::Minutes(1) + absl::Milliseconds(250)));
+  EXPECT_EQ("1h1m0.25s",
+            absl::FormatDuration(absl::Hours(1) + absl::Minutes(1) +
+                                 absl::Milliseconds(250)));
+  EXPECT_EQ("1h0.0005s",
+            absl::FormatDuration(absl::Hours(1) + absl::Microseconds(500)));
+  EXPECT_EQ("1h0.0000005s",
+            absl::FormatDuration(absl::Hours(1) + absl::Nanoseconds(500)));
+
+  // Subsecond special case.
+  EXPECT_EQ("1.5ns", absl::FormatDuration(absl::Nanoseconds(1) +
+                                          absl::Nanoseconds(1) / 2));
+  EXPECT_EQ("1.25ns", absl::FormatDuration(absl::Nanoseconds(1) +
+                                           absl::Nanoseconds(1) / 4));
+  EXPECT_EQ("1ns", absl::FormatDuration(absl::Nanoseconds(1) +
+                                        absl::Nanoseconds(1) / 9));
+  EXPECT_EQ("1.2us", absl::FormatDuration(absl::Microseconds(1) +
+                                          absl::Nanoseconds(200)));
+  EXPECT_EQ("1.2ms", absl::FormatDuration(absl::Milliseconds(1) +
+                                          absl::Microseconds(200)));
+  EXPECT_EQ("1.0002ms", absl::FormatDuration(absl::Milliseconds(1) +
+                                             absl::Nanoseconds(200)));
+  EXPECT_EQ("1.00001ms", absl::FormatDuration(absl::Milliseconds(1) +
+                                              absl::Nanoseconds(10)));
+  EXPECT_EQ("1.000001ms",
+            absl::FormatDuration(absl::Milliseconds(1) + absl::Nanoseconds(1)));
+
+  // Negative durations.
+  EXPECT_EQ("-1ns", absl::FormatDuration(absl::Nanoseconds(-1)));
+  EXPECT_EQ("-1us", absl::FormatDuration(absl::Microseconds(-1)));
+  EXPECT_EQ("-1ms", absl::FormatDuration(absl::Milliseconds(-1)));
+  EXPECT_EQ("-1s", absl::FormatDuration(absl::Seconds(-1)));
+  EXPECT_EQ("-1m", absl::FormatDuration(absl::Minutes(-1)));
+  EXPECT_EQ("-1h", absl::FormatDuration(absl::Hours(-1)));
+
+  EXPECT_EQ("-1h1m",
+            absl::FormatDuration(-(absl::Hours(1) + absl::Minutes(1))));
+  EXPECT_EQ("-1h1s",
+            absl::FormatDuration(-(absl::Hours(1) + absl::Seconds(1))));
+  EXPECT_EQ("-1m1s",
+            absl::FormatDuration(-(absl::Minutes(1) + absl::Seconds(1))));
+
+  EXPECT_EQ("-1ns", absl::FormatDuration(absl::Nanoseconds(-1)));
+  EXPECT_EQ("-1.2us", absl::FormatDuration(
+                          -(absl::Microseconds(1) + absl::Nanoseconds(200))));
+  EXPECT_EQ("-1.2ms", absl::FormatDuration(
+                          -(absl::Milliseconds(1) + absl::Microseconds(200))));
+  EXPECT_EQ("-1.0002ms", absl::FormatDuration(-(absl::Milliseconds(1) +
+                                                absl::Nanoseconds(200))));
+  EXPECT_EQ("-1.00001ms", absl::FormatDuration(-(absl::Milliseconds(1) +
+                                                 absl::Nanoseconds(10))));
+  EXPECT_EQ("-1.000001ms", absl::FormatDuration(-(absl::Milliseconds(1) +
+                                                  absl::Nanoseconds(1))));
+
+  //
+  // Interesting corner cases.
+  //
+
+  const absl::Duration qns = absl::Nanoseconds(1) / 4;
+  const absl::Duration max_dur =
+      absl::Seconds(kint64max) + (absl::Seconds(1) - qns);
+  const absl::Duration min_dur = absl::Seconds(kint64min);
+
+  EXPECT_EQ("0.25ns", absl::FormatDuration(qns));
+  EXPECT_EQ("-0.25ns", absl::FormatDuration(-qns));
+  EXPECT_EQ("2562047788015215h30m7.99999999975s",
+            absl::FormatDuration(max_dur));
+  EXPECT_EQ("-2562047788015215h30m8s", absl::FormatDuration(min_dur));
+
+  // Tests printing full precision from units that print using FDivDuration
+  EXPECT_EQ("55.00000000025s", absl::FormatDuration(absl::Seconds(55) + qns));
+  EXPECT_EQ("55.00000025ms",
+            absl::FormatDuration(absl::Milliseconds(55) + qns));
+  EXPECT_EQ("55.00025us", absl::FormatDuration(absl::Microseconds(55) + qns));
+  EXPECT_EQ("55.25ns", absl::FormatDuration(absl::Nanoseconds(55) + qns));
+
+  // Formatting infinity
+  EXPECT_EQ("inf", absl::FormatDuration(absl::InfiniteDuration()));
+  EXPECT_EQ("-inf", absl::FormatDuration(-absl::InfiniteDuration()));
+
+  // Formatting approximately +/- 100 billion years
+  const absl::Duration huge_range = ApproxYears(100000000000);
+  EXPECT_EQ("876000000000000h", absl::FormatDuration(huge_range));
+  EXPECT_EQ("-876000000000000h", absl::FormatDuration(-huge_range));
+
+  EXPECT_EQ("876000000000000h0.999999999s",
+            absl::FormatDuration(huge_range +
+                                 (absl::Seconds(1) - absl::Nanoseconds(1))));
+  EXPECT_EQ("876000000000000h0.9999999995s",
+            absl::FormatDuration(
+                huge_range + (absl::Seconds(1) - absl::Nanoseconds(1) / 2)));
+  EXPECT_EQ("876000000000000h0.99999999975s",
+            absl::FormatDuration(
+                huge_range + (absl::Seconds(1) - absl::Nanoseconds(1) / 4)));
+
+  EXPECT_EQ("-876000000000000h0.999999999s",
+            absl::FormatDuration(-huge_range -
+                                 (absl::Seconds(1) - absl::Nanoseconds(1))));
+  EXPECT_EQ("-876000000000000h0.9999999995s",
+            absl::FormatDuration(
+                -huge_range - (absl::Seconds(1) - absl::Nanoseconds(1) / 2)));
+  EXPECT_EQ("-876000000000000h0.99999999975s",
+            absl::FormatDuration(
+                -huge_range - (absl::Seconds(1) - absl::Nanoseconds(1) / 4)));
+}
+
+TEST(Duration, ParseDuration) {
+  absl::Duration d;
+
+  // No specified unit. Should only work for zero and infinity.
+  EXPECT_TRUE(absl::ParseDuration("0", &d));
+  EXPECT_EQ(absl::ZeroDuration(), d);
+  EXPECT_TRUE(absl::ParseDuration("+0", &d));
+  EXPECT_EQ(absl::ZeroDuration(), d);
+  EXPECT_TRUE(absl::ParseDuration("-0", &d));
+  EXPECT_EQ(absl::ZeroDuration(), d);
+
+  EXPECT_TRUE(absl::ParseDuration("inf", &d));
+  EXPECT_EQ(absl::InfiniteDuration(), d);
+  EXPECT_TRUE(absl::ParseDuration("+inf", &d));
+  EXPECT_EQ(absl::InfiniteDuration(), d);
+  EXPECT_TRUE(absl::ParseDuration("-inf", &d));
+  EXPECT_EQ(-absl::InfiniteDuration(), d);
+  EXPECT_FALSE(absl::ParseDuration("infBlah", &d));
+
+  // Illegal input forms.
+  EXPECT_FALSE(absl::ParseDuration("", &d));
+  EXPECT_FALSE(absl::ParseDuration("0.0", &d));
+  EXPECT_FALSE(absl::ParseDuration(".0", &d));
+  EXPECT_FALSE(absl::ParseDuration(".", &d));
+  EXPECT_FALSE(absl::ParseDuration("01", &d));
+  EXPECT_FALSE(absl::ParseDuration("1", &d));
+  EXPECT_FALSE(absl::ParseDuration("-1", &d));
+  EXPECT_FALSE(absl::ParseDuration("2", &d));
+  EXPECT_FALSE(absl::ParseDuration("2 s", &d));
+  EXPECT_FALSE(absl::ParseDuration(".s", &d));
+  EXPECT_FALSE(absl::ParseDuration("-.s", &d));
+  EXPECT_FALSE(absl::ParseDuration("s", &d));
+  EXPECT_FALSE(absl::ParseDuration(" 2s", &d));
+  EXPECT_FALSE(absl::ParseDuration("2s ", &d));
+  EXPECT_FALSE(absl::ParseDuration(" 2s ", &d));
+  EXPECT_FALSE(absl::ParseDuration("2mt", &d));
+
+  // One unit type.
+  EXPECT_TRUE(absl::ParseDuration("1ns", &d));
+  EXPECT_EQ(absl::Nanoseconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1us", &d));
+  EXPECT_EQ(absl::Microseconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1ms", &d));
+  EXPECT_EQ(absl::Milliseconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1s", &d));
+  EXPECT_EQ(absl::Seconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("2m", &d));
+  EXPECT_EQ(absl::Minutes(2), d);
+  EXPECT_TRUE(absl::ParseDuration("2h", &d));
+  EXPECT_EQ(absl::Hours(2), d);
+
+  // Multiple units.
+  EXPECT_TRUE(absl::ParseDuration("2h3m4s", &d));
+  EXPECT_EQ(absl::Hours(2) + absl::Minutes(3) + absl::Seconds(4), d);
+  EXPECT_TRUE(absl::ParseDuration("3m4s5us", &d));
+  EXPECT_EQ(absl::Minutes(3) + absl::Seconds(4) + absl::Microseconds(5), d);
+  EXPECT_TRUE(absl::ParseDuration("2h3m4s5ms6us7ns", &d));
+  EXPECT_EQ(absl::Hours(2) + absl::Minutes(3) + absl::Seconds(4) +
+                absl::Milliseconds(5) + absl::Microseconds(6) +
+                absl::Nanoseconds(7),
+            d);
+
+  // Multiple units out of order.
+  EXPECT_TRUE(absl::ParseDuration("2us3m4s5h", &d));
+  EXPECT_EQ(absl::Hours(5) + absl::Minutes(3) + absl::Seconds(4) +
+                absl::Microseconds(2),
+            d);
+
+  // Fractional values of units.
+  EXPECT_TRUE(absl::ParseDuration("1.5ns", &d));
+  EXPECT_EQ(1.5 * absl::Nanoseconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1.5us", &d));
+  EXPECT_EQ(1.5 * absl::Microseconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1.5ms", &d));
+  EXPECT_EQ(1.5 * absl::Milliseconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1.5s", &d));
+  EXPECT_EQ(1.5 * absl::Seconds(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1.5m", &d));
+  EXPECT_EQ(1.5 * absl::Minutes(1), d);
+  EXPECT_TRUE(absl::ParseDuration("1.5h", &d));
+  EXPECT_EQ(1.5 * absl::Hours(1), d);
+
+  // Negative durations.
+  EXPECT_TRUE(absl::ParseDuration("-1s", &d));
+  EXPECT_EQ(absl::Seconds(-1), d);
+  EXPECT_TRUE(absl::ParseDuration("-1m", &d));
+  EXPECT_EQ(absl::Minutes(-1), d);
+  EXPECT_TRUE(absl::ParseDuration("-1h", &d));
+  EXPECT_EQ(absl::Hours(-1), d);
+
+  EXPECT_TRUE(absl::ParseDuration("-1h2s", &d));
+  EXPECT_EQ(-(absl::Hours(1) + absl::Seconds(2)), d);
+  EXPECT_FALSE(absl::ParseDuration("1h-2s", &d));
+  EXPECT_FALSE(absl::ParseDuration("-1h-2s", &d));
+  EXPECT_FALSE(absl::ParseDuration("-1h -2s", &d));
+}
+
+TEST(Duration, FormatParseRoundTrip) {
+#define TEST_PARSE_ROUNDTRIP(d)                \
+  do {                                         \
+    std::string s = absl::FormatDuration(d);        \
+    absl::Duration dur;                        \
+    EXPECT_TRUE(absl::ParseDuration(s, &dur)); \
+    EXPECT_EQ(d, dur);                         \
+  } while (0)
+
+  TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(1));
+  TEST_PARSE_ROUNDTRIP(absl::Microseconds(1));
+  TEST_PARSE_ROUNDTRIP(absl::Milliseconds(1));
+  TEST_PARSE_ROUNDTRIP(absl::Seconds(1));
+  TEST_PARSE_ROUNDTRIP(absl::Minutes(1));
+  TEST_PARSE_ROUNDTRIP(absl::Hours(1));
+  TEST_PARSE_ROUNDTRIP(absl::Hours(1) + absl::Nanoseconds(2));
+
+  TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(-1));
+  TEST_PARSE_ROUNDTRIP(absl::Microseconds(-1));
+  TEST_PARSE_ROUNDTRIP(absl::Milliseconds(-1));
+  TEST_PARSE_ROUNDTRIP(absl::Seconds(-1));
+  TEST_PARSE_ROUNDTRIP(absl::Minutes(-1));
+  TEST_PARSE_ROUNDTRIP(absl::Hours(-1));
+
+  TEST_PARSE_ROUNDTRIP(absl::Hours(-1) + absl::Nanoseconds(2));
+  TEST_PARSE_ROUNDTRIP(absl::Hours(1) + absl::Nanoseconds(-2));
+  TEST_PARSE_ROUNDTRIP(absl::Hours(-1) + absl::Nanoseconds(-2));
+
+  TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(1) +
+                       absl::Nanoseconds(1) / 4);  // 1.25ns
+
+  const absl::Duration huge_range = ApproxYears(100000000000);
+  TEST_PARSE_ROUNDTRIP(huge_range);
+  TEST_PARSE_ROUNDTRIP(huge_range + (absl::Seconds(1) - absl::Nanoseconds(1)));
+
+#undef TEST_PARSE_ROUNDTRIP
+}
+}  // namespace