Commit 145fb4de authored by Quentin Fiard's avatar Quentin Fiard Committed by Commit Bot

Fixes to TimeDelta::InX methods

- Improve the documentation of TimeDelta::InXYZ methods to clarify that they return a truncated value (aka rounded towards zero).
- Add a new InDaysFloored method to convert a TimeDelta into a floored number of days.
- Fix the implementation of InMillisecondsRoundedUp for negative time deltas.

Bug: 831545
Change-Id: I4afd256308f6f28ff459925772059fdfc5824995
Reviewed-on: https://chromium-review.googlesource.com/1049906Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Commit-Queue: Quentin Fiard <qfiard@google.com>
Cr-Commit-Position: refs/heads/master@{#561334}
parent 0b1781e5
...@@ -45,6 +45,19 @@ int TimeDelta::InDays() const { ...@@ -45,6 +45,19 @@ int TimeDelta::InDays() const {
return static_cast<int>(delta_ / Time::kMicrosecondsPerDay); return static_cast<int>(delta_ / Time::kMicrosecondsPerDay);
} }
int TimeDelta::InDaysFloored() const {
if (is_max()) {
// Preserve max to prevent overflow.
return std::numeric_limits<int>::max();
}
int result = delta_ / Time::kMicrosecondsPerDay;
int64_t remainder = delta_ - (result * Time::kMicrosecondsPerDay);
if (remainder < 0) {
--result; // Use floor(), not trunc() rounding behavior.
}
return result;
}
int TimeDelta::InHours() const { int TimeDelta::InHours() const {
if (is_max()) { if (is_max()) {
// Preserve max to prevent overflow. // Preserve max to prevent overflow.
...@@ -98,8 +111,12 @@ int64_t TimeDelta::InMillisecondsRoundedUp() const { ...@@ -98,8 +111,12 @@ int64_t TimeDelta::InMillisecondsRoundedUp() const {
// Preserve max to prevent overflow. // Preserve max to prevent overflow.
return std::numeric_limits<int64_t>::max(); return std::numeric_limits<int64_t>::max();
} }
return (delta_ + Time::kMicrosecondsPerMillisecond - 1) / int64_t result = delta_ / Time::kMicrosecondsPerMillisecond;
Time::kMicrosecondsPerMillisecond; int64_t remainder = delta_ - (result * Time::kMicrosecondsPerMillisecond);
if (remainder > 0) {
++result; // Use ceil(), not trunc() rounding behavior.
}
return result;
} }
int64_t TimeDelta::InMicroseconds() const { int64_t TimeDelta::InMicroseconds() const {
......
...@@ -181,12 +181,13 @@ class BASE_EXPORT TimeDelta { ...@@ -181,12 +181,13 @@ class BASE_EXPORT TimeDelta {
struct timespec ToTimeSpec() const; struct timespec ToTimeSpec() const;
#endif #endif
// Returns the time delta in some unit. The F versions return a floating // Returns the time delta in some unit. The InXYZF versions return a floating
// point value, the "regular" versions return a rounded-down value. // point value. The InXYZ versions return a truncated value (aka rounded
// // towards zero, std::trunc() behavior). The InXYZFloored() versions round to
// InMillisecondsRoundedUp() instead returns an integer that is rounded up // lesser integers (std::floor() behavior). The XYZRoundedUp() versions round
// to the next full millisecond. // up to greater integers (std::ceil() behavior).
int InDays() const; int InDays() const;
int InDaysFloored() const;
int InHours() const; int InHours() const;
int InMinutes() const; int InMinutes() const;
double InSecondsF() const; double InSecondsF() const;
......
...@@ -1129,6 +1129,47 @@ TEST(TimeDelta, FromAndIn) { ...@@ -1129,6 +1129,47 @@ TEST(TimeDelta, FromAndIn) {
EXPECT_EQ(TimeDelta::FromNanosecondsD(12345.678).InNanoseconds(), 12000); EXPECT_EQ(TimeDelta::FromNanosecondsD(12345.678).InNanoseconds(), 12000);
} }
TEST(TimeDelta, InRoundsTowardsZero) {
EXPECT_EQ(TimeDelta::FromHours(23).InDays(), 0);
EXPECT_EQ(TimeDelta::FromHours(-23).InDays(), 0);
EXPECT_EQ(TimeDelta::FromMinutes(59).InHours(), 0);
EXPECT_EQ(TimeDelta::FromMinutes(-59).InHours(), 0);
EXPECT_EQ(TimeDelta::FromSeconds(59).InMinutes(), 0);
EXPECT_EQ(TimeDelta::FromSeconds(-59).InMinutes(), 0);
EXPECT_EQ(TimeDelta::FromMilliseconds(999).InSeconds(), 0);
EXPECT_EQ(TimeDelta::FromMilliseconds(-999).InSeconds(), 0);
EXPECT_EQ(TimeDelta::FromMicroseconds(999).InMilliseconds(), 0);
EXPECT_EQ(TimeDelta::FromMicroseconds(-999).InMilliseconds(), 0);
}
TEST(TimeDelta, InDaysFloored) {
EXPECT_EQ(TimeDelta::FromHours(-25).InDaysFloored(), -2);
EXPECT_EQ(TimeDelta::FromHours(-24).InDaysFloored(), -1);
EXPECT_EQ(TimeDelta::FromHours(-23).InDaysFloored(), -1);
EXPECT_EQ(TimeDelta::FromHours(-1).InDaysFloored(), -1);
EXPECT_EQ(TimeDelta::FromHours(0).InDaysFloored(), 0);
EXPECT_EQ(TimeDelta::FromHours(1).InDaysFloored(), 0);
EXPECT_EQ(TimeDelta::FromHours(23).InDaysFloored(), 0);
EXPECT_EQ(TimeDelta::FromHours(24).InDaysFloored(), 1);
EXPECT_EQ(TimeDelta::FromHours(25).InDaysFloored(), 1);
}
TEST(TimeDelta, InMillisecondsRoundedUp) {
EXPECT_EQ(TimeDelta::FromMicroseconds(-1001).InMillisecondsRoundedUp(), -1);
EXPECT_EQ(TimeDelta::FromMicroseconds(-1000).InMillisecondsRoundedUp(), -1);
EXPECT_EQ(TimeDelta::FromMicroseconds(-999).InMillisecondsRoundedUp(), 0);
EXPECT_EQ(TimeDelta::FromMicroseconds(-1).InMillisecondsRoundedUp(), 0);
EXPECT_EQ(TimeDelta::FromMicroseconds(0).InMillisecondsRoundedUp(), 0);
EXPECT_EQ(TimeDelta::FromMicroseconds(1).InMillisecondsRoundedUp(), 1);
EXPECT_EQ(TimeDelta::FromMicroseconds(999).InMillisecondsRoundedUp(), 1);
EXPECT_EQ(TimeDelta::FromMicroseconds(1000).InMillisecondsRoundedUp(), 1);
EXPECT_EQ(TimeDelta::FromMicroseconds(1001).InMillisecondsRoundedUp(), 2);
}
#if defined(OS_POSIX) || defined(OS_FUCHSIA) #if defined(OS_POSIX) || defined(OS_FUCHSIA)
TEST(TimeDelta, TimeSpecConversion) { TEST(TimeDelta, TimeSpecConversion) {
TimeDelta delta = TimeDelta::FromSeconds(0); TimeDelta delta = TimeDelta::FromSeconds(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment