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 {
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 {
if (is_max()) {
// Preserve max to prevent overflow.
......@@ -98,8 +111,12 @@ int64_t TimeDelta::InMillisecondsRoundedUp() const {
// Preserve max to prevent overflow.
return std::numeric_limits<int64_t>::max();
}
return (delta_ + Time::kMicrosecondsPerMillisecond - 1) /
Time::kMicrosecondsPerMillisecond;
int64_t result = delta_ / 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 {
......
......@@ -181,12 +181,13 @@ class BASE_EXPORT TimeDelta {
struct timespec ToTimeSpec() const;
#endif
// Returns the time delta in some unit. The F versions return a floating
// point value, the "regular" versions return a rounded-down value.
//
// InMillisecondsRoundedUp() instead returns an integer that is rounded up
// to the next full millisecond.
// Returns the time delta in some unit. The InXYZF versions return a floating
// point value. The InXYZ versions return a truncated value (aka rounded
// towards zero, std::trunc() behavior). The InXYZFloored() versions round to
// lesser integers (std::floor() behavior). The XYZRoundedUp() versions round
// up to greater integers (std::ceil() behavior).
int InDays() const;
int InDaysFloored() const;
int InHours() const;
int InMinutes() const;
double InSecondsF() const;
......
......@@ -1129,6 +1129,47 @@ TEST(TimeDelta, FromAndIn) {
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)
TEST(TimeDelta, TimeSpecConversion) {
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