diff options
author | gavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-04 08:14:54 +0000 |
---|---|---|
committer | gavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-04 08:14:54 +0000 |
commit | ca4dd6057fe882d29c9988689613c0d76c669205 (patch) | |
tree | 5c1acd3e0413e95e8b6d0676bce20befdbd4ae68 /base/time | |
parent | 79538f128532a231a9b7f19d130ce57ed473a66c (diff) | |
download | chromium_src-ca4dd6057fe882d29c9988689613c0d76c669205.zip chromium_src-ca4dd6057fe882d29c9988689613c0d76c669205.tar.gz chromium_src-ca4dd6057fe882d29c9988689613c0d76c669205.tar.bz2 |
Reland "Add base::TimeDelta::Max()"
Media was exposing max timedeltas to JSON, which wasn't working with
infinity.
R=scherkus@chromium.org
TBR=ajwong@chromium.org,jar@chromium.org,jamesr@chomium.org,acolwell@chromium.org,nick@chromium.org
BUG=None
Review URL: https://codereview.chromium.org/183763011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254717 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/time')
-rw-r--r-- | base/time/time.cc | 41 | ||||
-rw-r--r-- | base/time/time.h | 40 | ||||
-rw-r--r-- | base/time/time_unittest.cc | 40 |
3 files changed, 115 insertions, 6 deletions
diff --git a/base/time/time.cc b/base/time/time.cc index 4605d56..2c63886 100644 --- a/base/time/time.cc +++ b/base/time/time.cc @@ -17,40 +17,81 @@ namespace base { // TimeDelta ------------------------------------------------------------------ +// static +TimeDelta TimeDelta::Max() { + return TimeDelta(std::numeric_limits<int64>::max()); +} + int TimeDelta::InDays() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<int>::max(); + } return static_cast<int>(delta_ / Time::kMicrosecondsPerDay); } int TimeDelta::InHours() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<int>::max(); + } return static_cast<int>(delta_ / Time::kMicrosecondsPerHour); } int TimeDelta::InMinutes() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<int>::max(); + } return static_cast<int>(delta_ / Time::kMicrosecondsPerMinute); } double TimeDelta::InSecondsF() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<double>::infinity(); + } return static_cast<double>(delta_) / Time::kMicrosecondsPerSecond; } int64 TimeDelta::InSeconds() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<int64>::max(); + } return delta_ / Time::kMicrosecondsPerSecond; } double TimeDelta::InMillisecondsF() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<double>::infinity(); + } return static_cast<double>(delta_) / Time::kMicrosecondsPerMillisecond; } int64 TimeDelta::InMilliseconds() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<int64>::max(); + } return delta_ / Time::kMicrosecondsPerMillisecond; } int64 TimeDelta::InMillisecondsRoundedUp() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<int64>::max(); + } return (delta_ + Time::kMicrosecondsPerMillisecond - 1) / Time::kMicrosecondsPerMillisecond; } int64 TimeDelta::InMicroseconds() const { + if (is_max()) { + // Preserve max to prevent overflow. + return std::numeric_limits<int64>::max(); + } return delta_; } diff --git a/base/time/time.h b/base/time/time.h index 40566b9..69a1324 100644 --- a/base/time/time.h +++ b/base/time/time.h @@ -61,9 +61,9 @@ class BASE_EXPORT TimeDelta { } // Converts units of time to TimeDeltas. - static TimeDelta FromDays(int64 days); - static TimeDelta FromHours(int64 hours); - static TimeDelta FromMinutes(int64 minutes); + static TimeDelta FromDays(int days); + static TimeDelta FromHours(int hours); + static TimeDelta FromMinutes(int minutes); static TimeDelta FromSeconds(int64 secs); static TimeDelta FromMilliseconds(int64 ms); static TimeDelta FromMicroseconds(int64 us); @@ -79,6 +79,11 @@ class BASE_EXPORT TimeDelta { return TimeDelta(delta); } + // Returns the maximum time delta, which should be greater than any reasonable + // time delta we might compare it to. Adding or subtracting the maximum time + // delta to a time or another time delta has an undefined result. + static TimeDelta Max(); + // Returns the internal numeric value of the TimeDelta object. Please don't // use this and do arithmetic on it, as it is more error prone than using the // provided operators. @@ -87,6 +92,11 @@ class BASE_EXPORT TimeDelta { return delta_; } + // Returns true if the time delta is the maximum time delta. + bool is_max() const { + return delta_ == std::numeric_limits<int64>::max(); + } + #if defined(OS_POSIX) struct timespec ToTimeSpec() const; #endif @@ -493,32 +503,50 @@ class BASE_EXPORT Time { // Inline the TimeDelta factory methods, for fast TimeDelta construction. // static -inline TimeDelta TimeDelta::FromDays(int64 days) { +inline TimeDelta TimeDelta::FromDays(int days) { + // Preserve max to prevent overflow. + if (days == std::numeric_limits<int>::max()) + return Max(); return TimeDelta(days * Time::kMicrosecondsPerDay); } // static -inline TimeDelta TimeDelta::FromHours(int64 hours) { +inline TimeDelta TimeDelta::FromHours(int hours) { + // Preserve max to prevent overflow. + if (hours == std::numeric_limits<int>::max()) + return Max(); return TimeDelta(hours * Time::kMicrosecondsPerHour); } // static -inline TimeDelta TimeDelta::FromMinutes(int64 minutes) { +inline TimeDelta TimeDelta::FromMinutes(int minutes) { + // Preserve max to prevent overflow. + if (minutes == std::numeric_limits<int>::max()) + return Max(); return TimeDelta(minutes * Time::kMicrosecondsPerMinute); } // static inline TimeDelta TimeDelta::FromSeconds(int64 secs) { + // Preserve max to prevent overflow. + if (secs == std::numeric_limits<int64>::max()) + return Max(); return TimeDelta(secs * Time::kMicrosecondsPerSecond); } // static inline TimeDelta TimeDelta::FromMilliseconds(int64 ms) { + // Preserve max to prevent overflow. + if (ms == std::numeric_limits<int64>::max()) + return Max(); return TimeDelta(ms * Time::kMicrosecondsPerMillisecond); } // static inline TimeDelta TimeDelta::FromMicroseconds(int64 us) { + // Preserve max to prevent overflow. + if (us == std::numeric_limits<int64>::max()) + return Max(); return TimeDelta(us); } diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc index b5d2493..40d7bd4 100644 --- a/base/time/time_unittest.cc +++ b/base/time/time_unittest.cc @@ -481,6 +481,46 @@ TEST_F(TimeTest, ExplodeBeforeUnixEpoch) { EXPECT_EQ(1, exploded.millisecond); } +TEST_F(TimeTest, TimeDeltaMax) { + TimeDelta max = TimeDelta::Max(); + EXPECT_TRUE(max.is_max()); + EXPECT_EQ(max, TimeDelta::Max()); + EXPECT_GT(max, TimeDelta::FromDays(100 * 365)); + EXPECT_GT(max, TimeDelta()); +} + +TEST_F(TimeTest, TimeDeltaMaxConversions) { + TimeDelta t = TimeDelta::Max(); + EXPECT_EQ(std::numeric_limits<int64>::max(), t.ToInternalValue()); + + EXPECT_EQ(std::numeric_limits<int>::max(), t.InDays()); + EXPECT_EQ(std::numeric_limits<int>::max(), t.InHours()); + EXPECT_EQ(std::numeric_limits<int>::max(), t.InMinutes()); + EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InSecondsF()); + EXPECT_EQ(std::numeric_limits<int64>::max(), t.InSeconds()); + EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InMillisecondsF()); + EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMilliseconds()); + EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMillisecondsRoundedUp()); + + t = TimeDelta::FromDays(std::numeric_limits<int>::max()); + EXPECT_TRUE(t.is_max()); + + t = TimeDelta::FromHours(std::numeric_limits<int>::max()); + EXPECT_TRUE(t.is_max()); + + t = TimeDelta::FromMinutes(std::numeric_limits<int>::max()); + EXPECT_TRUE(t.is_max()); + + t = TimeDelta::FromSeconds(std::numeric_limits<int64>::max()); + EXPECT_TRUE(t.is_max()); + + t = TimeDelta::FromMilliseconds(std::numeric_limits<int64>::max()); + EXPECT_TRUE(t.is_max()); + + t = TimeDelta::FromMicroseconds(std::numeric_limits<int64>::max()); + EXPECT_TRUE(t.is_max()); +} + TEST_F(TimeTest, Max) { Time max = Time::Max(); EXPECT_TRUE(max.is_max()); |