1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/time/time.h"
6
7 #include <stdint.h>
8 #include <time.h>
9
10 #include <limits>
11 #include <string>
12
13 #include "base/build_time.h"
14 #include "base/check_op.h"
15 #include "base/compiler_specific.h"
16 #include "base/environment.h"
17 #include "base/test/gtest_util.h"
18 #include "base/threading/platform_thread.h"
19 #include "base/time/time_override.h"
20 #include "build/build_config.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/abseil-cpp/absl/types/optional.h"
24 #include "third_party/icu/source/common/unicode/utypes.h"
25 #include "third_party/icu/source/i18n/unicode/timezone.h"
26
27 #if BUILDFLAG(IS_ANDROID)
28 #include "base/android/jni_android.h"
29 #elif BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMEOS)
30 #include "base/test/icu_test_util.h"
31 #elif BUILDFLAG(IS_WIN)
32 #include <windows.h>
33 #endif
34
35 namespace base {
36
37 namespace {
38
39 #if BUILDFLAG(IS_FUCHSIA)
40 // Hawaii does not observe daylight saving time, which is useful for having a
41 // constant offset when faking the time zone.
42 const char kHonoluluTimeZoneId[] = "Pacific/Honolulu";
43 const int kHonoluluOffsetHours = -10;
44 const int kHonoluluOffsetSeconds = kHonoluluOffsetHours * 60 * 60;
45 #endif
46
47 #if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMEOS)
48
49 const char kThaiLocale[] = "th-TH";
50 const char kBangkokTimeZoneId[] = "Asia/Bangkok";
51
52 // Returns the total offset (including Daylight Saving Time) of the timezone
53 // with |timezone_id| at |time|, or absl::nullopt in case of failure.
GetTimeZoneOffsetAtTime(const char * timezone_id,Time time)54 absl::optional<base::TimeDelta> GetTimeZoneOffsetAtTime(const char* timezone_id,
55 Time time) {
56 std::unique_ptr<icu::TimeZone> tz(icu::TimeZone::createTimeZone(timezone_id));
57 if (*tz == icu::TimeZone::getUnknown()) {
58 return {};
59 }
60 int32_t raw_offset = 0;
61 int32_t dst_offset = 0;
62 UErrorCode ec = U_ZERO_ERROR;
63 tz->getOffset(time.ToDoubleT(), false, raw_offset, dst_offset, ec);
64 if (!U_SUCCESS(ec)) {
65 return {};
66 }
67 return base::Milliseconds(raw_offset + dst_offset);
68 }
69
TimePassedAfterMidnight(const Time::Exploded & time)70 TimeDelta TimePassedAfterMidnight(const Time::Exploded& time) {
71 return base::Hours(time.hour) + base::Minutes(time.minute) +
72 base::Seconds(time.second) + base::Milliseconds(time.millisecond);
73 }
74
75 // Timezone environment variable
76
77 class ScopedLibcTZ {
78 public:
ScopedLibcTZ(const std::string & timezone)79 explicit ScopedLibcTZ(const std::string& timezone) {
80 auto env = base::Environment::Create();
81 std::string old_timezone_value;
82 if (env->GetVar(kTZ, &old_timezone_value)) {
83 old_timezone_ = old_timezone_value;
84 }
85 if (!env->SetVar(kTZ, timezone)) {
86 success_ = false;
87 }
88 tzset();
89 }
90
~ScopedLibcTZ()91 ~ScopedLibcTZ() {
92 auto env = base::Environment::Create();
93 if (old_timezone_.has_value()) {
94 CHECK(env->SetVar(kTZ, old_timezone_.value()));
95 } else {
96 CHECK(env->UnSetVar(kTZ));
97 }
98 }
99
100 ScopedLibcTZ(const ScopedLibcTZ& other) = delete;
101 ScopedLibcTZ& operator=(const ScopedLibcTZ& other) = delete;
102
is_success() const103 bool is_success() const { return success_; }
104
105 private:
106 static constexpr char kTZ[] = "TZ";
107
108 bool success_ = true;
109 absl::optional<std::string> old_timezone_;
110 };
111
112 constexpr char ScopedLibcTZ::kTZ[];
113
114 #endif // BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMEOS)
115
TEST(TimeTestOutOfBounds,FromExplodedOutOfBoundsTime)116 TEST(TimeTestOutOfBounds, FromExplodedOutOfBoundsTime) {
117 // FromUTCExploded must set time to Time(0) and failure, if the day is set to
118 // 31 on a 28-30 day month. Test |exploded| returns Time(0) on 31st of
119 // February and 31st of April. New implementation handles this.
120
121 const struct DateTestData {
122 Time::Exploded explode;
123 bool is_valid;
124 } kDateTestData[] = {
125 // 31st of February
126 {{2016, 2, 0, 31, 12, 30, 0, 0}, true},
127 // 31st of April
128 {{2016, 4, 0, 31, 8, 43, 0, 0}, true},
129 // Negative month
130 {{2016, -5, 0, 2, 4, 10, 0, 0}, false},
131 // Negative date of month
132 {{2016, 6, 0, -15, 2, 50, 0, 0}, false},
133 // Negative hours
134 {{2016, 7, 0, 10, -11, 29, 0, 0}, false},
135 // Negative minutes
136 {{2016, 3, 0, 14, 10, -29, 0, 0}, false},
137 // Negative seconds
138 {{2016, 10, 0, 25, 7, 47, -30, 0}, false},
139 // Negative milliseconds
140 {{2016, 10, 0, 25, 7, 47, 20, -500}, false},
141 // Hours are too large
142 {{2016, 7, 0, 10, 26, 29, 0, 0}, false},
143 // Minutes are too large
144 {{2016, 3, 0, 14, 10, 78, 0, 0}, false},
145 // Seconds are too large
146 {{2016, 10, 0, 25, 7, 47, 234, 0}, false},
147 // Milliseconds are too large
148 {{2016, 10, 0, 25, 6, 31, 23, 1643}, false},
149 // Test overflow. Time is valid, but overflow case
150 // results in Time(0).
151 {{9840633, 1, 0, 1, 1, 1, 0, 0}, true},
152 // Underflow will fail as well.
153 {{-9840633, 1, 0, 1, 1, 1, 0, 0}, true},
154 // Test integer overflow and underflow cases for the values themselves.
155 {{std::numeric_limits<int>::min(), 1, 0, 1, 1, 1, 0, 0}, true},
156 {{std::numeric_limits<int>::max(), 1, 0, 1, 1, 1, 0, 0}, true},
157 {{2016, std::numeric_limits<int>::min(), 0, 1, 1, 1, 0, 0}, false},
158 {{2016, std::numeric_limits<int>::max(), 0, 1, 1, 1, 0, 0}, false},
159 };
160
161 for (const auto& test : kDateTestData) {
162 EXPECT_EQ(test.explode.HasValidValues(), test.is_valid);
163
164 base::Time result;
165 EXPECT_FALSE(base::Time::FromUTCExploded(test.explode, &result));
166 EXPECT_TRUE(result.is_null());
167 EXPECT_FALSE(base::Time::FromLocalExploded(test.explode, &result));
168 EXPECT_TRUE(result.is_null());
169 }
170 }
171
172 // Specialized test fixture allowing time strings without timezones to be
173 // tested by comparing them to a known time in the local zone.
174 // See also pr_time_unittests.cc
175 class TimeTest : public testing::Test {
176 protected:
177 #if BUILDFLAG(IS_FUCHSIA)
178 // POSIX local time functions always use UTC on Fuchsia. As this is not very
179 // interesting for any "local" tests, set a different default ICU timezone for
180 // the test. This only affects code that uses ICU, such as Exploded time.
181 // Chicago is a non-Pacific time zone known to observe daylight saving time.
TimeTest()182 TimeTest() : chicago_time_("America/Chicago") {}
183 test::ScopedRestoreDefaultTimezone chicago_time_;
184 #endif
185
SetUp()186 void SetUp() override {
187 // Use mktime to get a time_t, and turn it into a PRTime by converting
188 // seconds to microseconds. Use 15th Oct 2007 12:45:00 local. This
189 // must be a time guaranteed to be outside of a DST fallback hour in
190 // any timezone.
191 struct tm local_comparison_tm = {
192 0, // second
193 45, // minute
194 12, // hour
195 15, // day of month
196 10 - 1, // month
197 2007 - 1900, // year
198 0, // day of week (ignored, output only)
199 0, // day of year (ignored, output only)
200 -1 // DST in effect, -1 tells mktime to figure it out
201 };
202
203 time_t converted_time = mktime(&local_comparison_tm);
204 ASSERT_GT(converted_time, 0);
205 comparison_time_local_ = Time::FromTimeT(converted_time);
206
207 // time_t representation of 15th Oct 2007 12:45:00 PDT
208 comparison_time_pdt_ = Time::FromTimeT(1192477500);
209 }
210
211 Time comparison_time_local_;
212 Time comparison_time_pdt_;
213 };
214
215 // Test conversion to/from TimeDeltas elapsed since the Windows epoch.
216 // Conversions should be idempotent and non-lossy.
TEST_F(TimeTest,DeltaSinceWindowsEpoch)217 TEST_F(TimeTest, DeltaSinceWindowsEpoch) {
218 constexpr TimeDelta delta = Microseconds(123);
219 EXPECT_EQ(delta,
220 Time::FromDeltaSinceWindowsEpoch(delta).ToDeltaSinceWindowsEpoch());
221
222 const Time now = Time::Now();
223 const Time actual =
224 Time::FromDeltaSinceWindowsEpoch(now.ToDeltaSinceWindowsEpoch());
225 EXPECT_EQ(now, actual);
226
227 // Null times should remain null after a round-trip conversion. This is an
228 // important invariant for the common use case of serialization +
229 // deserialization.
230 const Time should_be_null =
231 Time::FromDeltaSinceWindowsEpoch(Time().ToDeltaSinceWindowsEpoch());
232 EXPECT_TRUE(should_be_null.is_null());
233
234 {
235 constexpr Time constexpr_time =
236 Time::FromDeltaSinceWindowsEpoch(Microseconds(123));
237 constexpr TimeDelta constexpr_delta =
238 constexpr_time.ToDeltaSinceWindowsEpoch();
239 static_assert(constexpr_delta == delta);
240 }
241 }
242
243 // Test conversion to/from time_t.
TEST_F(TimeTest,TimeT)244 TEST_F(TimeTest, TimeT) {
245 EXPECT_EQ(10, Time().FromTimeT(10).ToTimeT());
246 EXPECT_EQ(10.0, Time().FromTimeT(10).ToDoubleT());
247
248 // Conversions of 0 should stay 0.
249 EXPECT_EQ(0, Time().ToTimeT());
250 EXPECT_EQ(0, Time::FromTimeT(0).ToInternalValue());
251 }
252
253 // Test conversions to/from time_t and exploding/unexploding (utc time).
TEST_F(TimeTest,UTCTimeT)254 TEST_F(TimeTest, UTCTimeT) {
255 // C library time and exploded time.
256 time_t now_t_1 = time(nullptr);
257 struct tm tms;
258 #if BUILDFLAG(IS_WIN)
259 gmtime_s(&tms, &now_t_1);
260 #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
261 gmtime_r(&now_t_1, &tms);
262 #endif
263
264 // Convert to ours.
265 Time our_time_1 = Time::FromTimeT(now_t_1);
266 Time::Exploded exploded;
267 our_time_1.UTCExplode(&exploded);
268
269 // This will test both our exploding and our time_t -> Time conversion.
270 EXPECT_EQ(tms.tm_year + 1900, exploded.year);
271 EXPECT_EQ(tms.tm_mon + 1, exploded.month);
272 EXPECT_EQ(tms.tm_mday, exploded.day_of_month);
273 EXPECT_EQ(tms.tm_hour, exploded.hour);
274 EXPECT_EQ(tms.tm_min, exploded.minute);
275 EXPECT_EQ(tms.tm_sec, exploded.second);
276
277 // Convert exploded back to the time struct.
278 Time our_time_2;
279 EXPECT_TRUE(Time::FromUTCExploded(exploded, &our_time_2));
280 EXPECT_TRUE(our_time_1 == our_time_2);
281
282 time_t now_t_2 = our_time_2.ToTimeT();
283 EXPECT_EQ(now_t_1, now_t_2);
284 }
285
286 // Test conversions to/from time_t and exploding/unexploding (local time).
TEST_F(TimeTest,LocalTimeT)287 TEST_F(TimeTest, LocalTimeT) {
288 // C library time and exploded time.
289 time_t now_t_1 = time(nullptr);
290 struct tm tms;
291
292 #if BUILDFLAG(IS_WIN)
293 localtime_s(&tms, &now_t_1);
294 #elif BUILDFLAG(IS_POSIX)
295 localtime_r(&now_t_1, &tms);
296 #elif BUILDFLAG(IS_FUCHSIA)
297 // POSIX local time functions always use UTC on Fuchsia, so set a known time
298 // zone and manually obtain the local |tms| values by using an adjusted input.
299 test::ScopedRestoreDefaultTimezone honolulu_time(kHonoluluTimeZoneId);
300 time_t adjusted_now_t_1 = now_t_1 + kHonoluluOffsetSeconds;
301 localtime_r(&adjusted_now_t_1, &tms);
302 #endif
303
304 // Convert to ours.
305 Time our_time_1 = Time::FromTimeT(now_t_1);
306 Time::Exploded exploded;
307 our_time_1.LocalExplode(&exploded);
308
309 // This will test both our exploding and our time_t -> Time conversion.
310 EXPECT_EQ(tms.tm_year + 1900, exploded.year);
311 EXPECT_EQ(tms.tm_mon + 1, exploded.month);
312 EXPECT_EQ(tms.tm_mday, exploded.day_of_month);
313 EXPECT_EQ(tms.tm_hour, exploded.hour);
314 EXPECT_EQ(tms.tm_min, exploded.minute);
315 EXPECT_EQ(tms.tm_sec, exploded.second);
316
317 // Convert exploded back to the time struct.
318 Time our_time_2;
319 EXPECT_TRUE(Time::FromLocalExploded(exploded, &our_time_2));
320 EXPECT_TRUE(our_time_1 == our_time_2);
321
322 time_t now_t_2 = our_time_2.ToTimeT();
323 EXPECT_EQ(now_t_1, now_t_2);
324 }
325
326 // Test conversions to/from javascript time.
TEST_F(TimeTest,JsTime)327 TEST_F(TimeTest, JsTime) {
328 Time epoch = Time::FromJsTime(0.0);
329 EXPECT_EQ(epoch, Time::UnixEpoch());
330 Time t = Time::FromJsTime(700000.3);
331 EXPECT_EQ(700.0003, t.ToDoubleT());
332 t = Time::FromDoubleT(800.73);
333 EXPECT_EQ(800730.0, t.ToJsTime());
334
335 // 1601-01-01 isn't round-trip with ToJsTime().
336 const double kWindowsEpoch = -11644473600000.0;
337 Time time = Time::FromJsTime(kWindowsEpoch);
338 EXPECT_TRUE(time.is_null());
339 EXPECT_NE(kWindowsEpoch, time.ToJsTime());
340 EXPECT_EQ(kWindowsEpoch, time.ToJsTimeIgnoringNull());
341 }
342
343 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
TEST_F(TimeTest,FromTimeVal)344 TEST_F(TimeTest, FromTimeVal) {
345 Time now = Time::Now();
346 Time also_now = Time::FromTimeVal(now.ToTimeVal());
347 EXPECT_EQ(now, also_now);
348 }
349 #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
350
TEST_F(TimeTest,FromExplodedWithMilliseconds)351 TEST_F(TimeTest, FromExplodedWithMilliseconds) {
352 // Some platform implementations of FromExploded are liable to drop
353 // milliseconds if we aren't careful.
354 Time now = Time::NowFromSystemTime();
355 Time::Exploded exploded1 = {0};
356 now.UTCExplode(&exploded1);
357 exploded1.millisecond = 500;
358 Time time;
359 EXPECT_TRUE(Time::FromUTCExploded(exploded1, &time));
360 Time::Exploded exploded2 = {0};
361 time.UTCExplode(&exploded2);
362 EXPECT_EQ(exploded1.millisecond, exploded2.millisecond);
363 }
364
TEST_F(TimeTest,ZeroIsSymmetric)365 TEST_F(TimeTest, ZeroIsSymmetric) {
366 Time zero_time(Time::FromTimeT(0));
367 EXPECT_EQ(0, zero_time.ToTimeT());
368
369 EXPECT_EQ(0.0, zero_time.ToDoubleT());
370 }
371
372 // Note that this test does not check whether the implementation correctly
373 // accounts for the local time zone.
TEST_F(TimeTest,LocalExplode)374 TEST_F(TimeTest, LocalExplode) {
375 Time a = Time::Now();
376 Time::Exploded exploded;
377 a.LocalExplode(&exploded);
378
379 Time b;
380 EXPECT_TRUE(Time::FromLocalExploded(exploded, &b));
381
382 // The exploded structure doesn't have microseconds, and on Mac & Linux, the
383 // internal OS conversion uses seconds, which will cause truncation. So we
384 // can only make sure that the delta is within one second.
385 EXPECT_LT(a - b, Seconds(1));
386 }
387
TEST_F(TimeTest,UTCExplode)388 TEST_F(TimeTest, UTCExplode) {
389 Time a = Time::Now();
390 Time::Exploded exploded;
391 a.UTCExplode(&exploded);
392
393 Time b;
394 EXPECT_TRUE(Time::FromUTCExploded(exploded, &b));
395
396 // The exploded structure doesn't have microseconds, and on Mac & Linux, the
397 // internal OS conversion uses seconds, which will cause truncation. So we
398 // can only make sure that the delta is within one second.
399 EXPECT_LT(a - b, Seconds(1));
400 }
401
TEST_F(TimeTest,UTCMidnight)402 TEST_F(TimeTest, UTCMidnight) {
403 Time::Exploded exploded;
404 Time::Now().UTCMidnight().UTCExplode(&exploded);
405 EXPECT_EQ(0, exploded.hour);
406 EXPECT_EQ(0, exploded.minute);
407 EXPECT_EQ(0, exploded.second);
408 EXPECT_EQ(0, exploded.millisecond);
409 }
410
411 // Note that this test does not check whether the implementation correctly
412 // accounts for the local time zone.
TEST_F(TimeTest,LocalMidnight)413 TEST_F(TimeTest, LocalMidnight) {
414 Time::Exploded exploded;
415 Time::Now().LocalMidnight().LocalExplode(&exploded);
416 EXPECT_EQ(0, exploded.hour);
417 EXPECT_EQ(0, exploded.minute);
418 EXPECT_EQ(0, exploded.second);
419 EXPECT_EQ(0, exploded.millisecond);
420 }
421
422 // These tests require the ability to fake the local time zone.
423 #if BUILDFLAG(IS_FUCHSIA)
TEST_F(TimeTest,LocalExplodeIsLocal)424 TEST_F(TimeTest, LocalExplodeIsLocal) {
425 // Set the default time zone to a zone with an offset different from UTC.
426 test::ScopedRestoreDefaultTimezone honolulu_time(kHonoluluTimeZoneId);
427
428 // The member contains useful values for this test, which uses it as UTC.
429 Time comparison_time_utc(comparison_time_local_);
430
431 Time::Exploded utc_exploded;
432 comparison_time_utc.UTCExplode(&utc_exploded);
433
434 Time::Exploded local_exploded;
435 comparison_time_utc.LocalExplode(&local_exploded);
436
437 // The year, month, and day are the same because the (negative) offset is
438 // smaller than the hour in the test time. Similarly, there is no underflow
439 // for hour.
440 EXPECT_EQ(utc_exploded.year, local_exploded.year);
441 EXPECT_EQ(utc_exploded.month, local_exploded.month);
442 EXPECT_EQ(utc_exploded.day_of_week, local_exploded.day_of_week);
443 EXPECT_EQ(utc_exploded.day_of_month, local_exploded.day_of_month);
444 EXPECT_EQ(utc_exploded.hour + kHonoluluOffsetHours, local_exploded.hour);
445 EXPECT_EQ(utc_exploded.minute, local_exploded.minute);
446 EXPECT_EQ(utc_exploded.second, local_exploded.second);
447 EXPECT_EQ(utc_exploded.millisecond, local_exploded.millisecond);
448
449 Time time_from_local_exploded;
450 EXPECT_TRUE(
451 Time::FromLocalExploded(local_exploded, &time_from_local_exploded));
452
453 EXPECT_EQ(comparison_time_utc, time_from_local_exploded);
454
455 // Unexplode the local time using the non-local method.
456 // The resulting time should be offset hours earlier.
457 Time time_from_utc_exploded;
458 EXPECT_TRUE(Time::FromUTCExploded(local_exploded, &time_from_utc_exploded));
459 EXPECT_EQ(comparison_time_utc + Hours(kHonoluluOffsetHours),
460 time_from_utc_exploded);
461 }
462
TEST_F(TimeTest,LocalMidnightIsLocal)463 TEST_F(TimeTest, LocalMidnightIsLocal) {
464 // Set the default time zone to a zone with an offset different from UTC.
465 test::ScopedRestoreDefaultTimezone honolulu_time(kHonoluluTimeZoneId);
466
467 // The member contains useful values for this test, which uses it as UTC.
468 Time comparison_time_utc(comparison_time_local_);
469
470 Time::Exploded utc_midnight_exploded;
471 comparison_time_utc.UTCMidnight().UTCExplode(&utc_midnight_exploded);
472
473 // Local midnight exploded in UTC will have an offset hour instead of 0.
474 Time::Exploded local_midnight_utc_exploded;
475 comparison_time_utc.LocalMidnight().UTCExplode(&local_midnight_utc_exploded);
476
477 // The year, month, and day are the same because the (negative) offset is
478 // smaller than the hour in the test time and thus both midnights round down
479 // on the same day.
480 EXPECT_EQ(utc_midnight_exploded.year, local_midnight_utc_exploded.year);
481 EXPECT_EQ(utc_midnight_exploded.month, local_midnight_utc_exploded.month);
482 EXPECT_EQ(utc_midnight_exploded.day_of_week,
483 local_midnight_utc_exploded.day_of_week);
484 EXPECT_EQ(utc_midnight_exploded.day_of_month,
485 local_midnight_utc_exploded.day_of_month);
486 EXPECT_EQ(0, utc_midnight_exploded.hour);
487 EXPECT_EQ(0 - kHonoluluOffsetHours, local_midnight_utc_exploded.hour);
488 EXPECT_EQ(0, local_midnight_utc_exploded.minute);
489 EXPECT_EQ(0, local_midnight_utc_exploded.second);
490 EXPECT_EQ(0, local_midnight_utc_exploded.millisecond);
491
492 // Local midnight exploded in local time will have no offset.
493 Time::Exploded local_midnight_exploded;
494 comparison_time_utc.LocalMidnight().LocalExplode(&local_midnight_exploded);
495
496 EXPECT_EQ(utc_midnight_exploded.year, local_midnight_exploded.year);
497 EXPECT_EQ(utc_midnight_exploded.month, local_midnight_exploded.month);
498 EXPECT_EQ(utc_midnight_exploded.day_of_week,
499 local_midnight_exploded.day_of_week);
500 EXPECT_EQ(utc_midnight_exploded.day_of_month,
501 local_midnight_exploded.day_of_month);
502 EXPECT_EQ(0, local_midnight_exploded.hour);
503 EXPECT_EQ(0, local_midnight_exploded.minute);
504 EXPECT_EQ(0, local_midnight_exploded.second);
505 EXPECT_EQ(0, local_midnight_exploded.millisecond);
506 }
507 #endif // BUILDFLAG(IS_FUCHSIA)
508
TEST_F(TimeTest,ParseTimeTest1)509 TEST_F(TimeTest, ParseTimeTest1) {
510 time_t current_time = 0;
511 time(¤t_time);
512
513 struct tm local_time = {};
514 char time_buf[64] = {};
515 #if BUILDFLAG(IS_WIN)
516 localtime_s(&local_time, ¤t_time);
517 asctime_s(time_buf, std::size(time_buf), &local_time);
518 #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
519 localtime_r(¤t_time, &local_time);
520 asctime_r(&local_time, time_buf);
521 #endif
522
523 Time parsed_time;
524 EXPECT_TRUE(Time::FromString(time_buf, &parsed_time));
525 EXPECT_EQ(current_time, parsed_time.ToTimeT());
526 }
527
TEST_F(TimeTest,DayOfWeekSunday)528 TEST_F(TimeTest, DayOfWeekSunday) {
529 Time time;
530 EXPECT_TRUE(Time::FromString("Sun, 06 May 2012 12:00:00 GMT", &time));
531 Time::Exploded exploded;
532 time.UTCExplode(&exploded);
533 EXPECT_EQ(0, exploded.day_of_week);
534 }
535
TEST_F(TimeTest,DayOfWeekWednesday)536 TEST_F(TimeTest, DayOfWeekWednesday) {
537 Time time;
538 EXPECT_TRUE(Time::FromString("Wed, 09 May 2012 12:00:00 GMT", &time));
539 Time::Exploded exploded;
540 time.UTCExplode(&exploded);
541 EXPECT_EQ(3, exploded.day_of_week);
542 }
543
TEST_F(TimeTest,DayOfWeekSaturday)544 TEST_F(TimeTest, DayOfWeekSaturday) {
545 Time time;
546 EXPECT_TRUE(Time::FromString("Sat, 12 May 2012 12:00:00 GMT", &time));
547 Time::Exploded exploded;
548 time.UTCExplode(&exploded);
549 EXPECT_EQ(6, exploded.day_of_week);
550 }
551
TEST_F(TimeTest,ParseTimeTest2)552 TEST_F(TimeTest, ParseTimeTest2) {
553 Time parsed_time;
554 EXPECT_TRUE(Time::FromString("Mon, 15 Oct 2007 19:45:00 GMT", &parsed_time));
555 EXPECT_EQ(comparison_time_pdt_, parsed_time);
556 }
557
TEST_F(TimeTest,ParseTimeTest3)558 TEST_F(TimeTest, ParseTimeTest3) {
559 Time parsed_time;
560 EXPECT_TRUE(Time::FromString("15 Oct 07 12:45:00", &parsed_time));
561 EXPECT_EQ(comparison_time_local_, parsed_time);
562 }
563
TEST_F(TimeTest,ParseTimeTest4)564 TEST_F(TimeTest, ParseTimeTest4) {
565 Time parsed_time;
566 EXPECT_TRUE(Time::FromString("15 Oct 07 19:45 GMT", &parsed_time));
567 EXPECT_EQ(comparison_time_pdt_, parsed_time);
568 }
569
TEST_F(TimeTest,ParseTimeTest5)570 TEST_F(TimeTest, ParseTimeTest5) {
571 Time parsed_time;
572 EXPECT_TRUE(Time::FromString("Mon Oct 15 12:45 PDT 2007", &parsed_time));
573 EXPECT_EQ(comparison_time_pdt_, parsed_time);
574 }
575
TEST_F(TimeTest,ParseTimeTest6)576 TEST_F(TimeTest, ParseTimeTest6) {
577 Time parsed_time;
578 EXPECT_TRUE(Time::FromString("Monday, Oct 15, 2007 12:45 PM", &parsed_time));
579 EXPECT_EQ(comparison_time_local_, parsed_time);
580 }
581
TEST_F(TimeTest,ParseTimeTest7)582 TEST_F(TimeTest, ParseTimeTest7) {
583 Time parsed_time;
584 EXPECT_TRUE(Time::FromString("10/15/07 12:45:00 PM", &parsed_time));
585 EXPECT_EQ(comparison_time_local_, parsed_time);
586 }
587
TEST_F(TimeTest,ParseTimeTest8)588 TEST_F(TimeTest, ParseTimeTest8) {
589 Time parsed_time;
590 EXPECT_TRUE(Time::FromString("15-OCT-2007 12:45pm", &parsed_time));
591 EXPECT_EQ(comparison_time_local_, parsed_time);
592 }
593
TEST_F(TimeTest,ParseTimeTest9)594 TEST_F(TimeTest, ParseTimeTest9) {
595 Time parsed_time;
596 EXPECT_TRUE(Time::FromString("16 Oct 2007 4:45-JST (Tuesday)", &parsed_time));
597 EXPECT_EQ(comparison_time_pdt_, parsed_time);
598 }
599
TEST_F(TimeTest,ParseTimeTest10)600 TEST_F(TimeTest, ParseTimeTest10) {
601 Time parsed_time;
602 EXPECT_TRUE(Time::FromString("15/10/07 12:45", &parsed_time));
603 EXPECT_EQ(parsed_time, comparison_time_local_);
604 }
605
606 // Test some of edge cases around epoch, etc.
TEST_F(TimeTest,ParseTimeTestEpoch0)607 TEST_F(TimeTest, ParseTimeTestEpoch0) {
608 Time parsed_time;
609
610 // time_t == epoch == 0
611 EXPECT_TRUE(Time::FromString("Thu Jan 01 01:00:00 +0100 1970",
612 &parsed_time));
613 EXPECT_EQ(0, parsed_time.ToTimeT());
614 EXPECT_TRUE(Time::FromString("Thu Jan 01 00:00:00 GMT 1970",
615 &parsed_time));
616 EXPECT_EQ(0, parsed_time.ToTimeT());
617 }
618
TEST_F(TimeTest,ParseTimeTestEpoch1)619 TEST_F(TimeTest, ParseTimeTestEpoch1) {
620 Time parsed_time;
621
622 // time_t == 1 second after epoch == 1
623 EXPECT_TRUE(Time::FromString("Thu Jan 01 01:00:01 +0100 1970",
624 &parsed_time));
625 EXPECT_EQ(1, parsed_time.ToTimeT());
626 EXPECT_TRUE(Time::FromString("Thu Jan 01 00:00:01 GMT 1970",
627 &parsed_time));
628 EXPECT_EQ(1, parsed_time.ToTimeT());
629 }
630
TEST_F(TimeTest,ParseTimeTestEpoch2)631 TEST_F(TimeTest, ParseTimeTestEpoch2) {
632 Time parsed_time;
633
634 // time_t == 2 seconds after epoch == 2
635 EXPECT_TRUE(Time::FromString("Thu Jan 01 01:00:02 +0100 1970",
636 &parsed_time));
637 EXPECT_EQ(2, parsed_time.ToTimeT());
638 EXPECT_TRUE(Time::FromString("Thu Jan 01 00:00:02 GMT 1970",
639 &parsed_time));
640 EXPECT_EQ(2, parsed_time.ToTimeT());
641 }
642
TEST_F(TimeTest,ParseTimeTestEpochNeg1)643 TEST_F(TimeTest, ParseTimeTestEpochNeg1) {
644 Time parsed_time;
645
646 // time_t == 1 second before epoch == -1
647 EXPECT_TRUE(Time::FromString("Thu Jan 01 00:59:59 +0100 1970",
648 &parsed_time));
649 EXPECT_EQ(-1, parsed_time.ToTimeT());
650 EXPECT_TRUE(Time::FromString("Wed Dec 31 23:59:59 GMT 1969",
651 &parsed_time));
652 EXPECT_EQ(-1, parsed_time.ToTimeT());
653 }
654
655 // If time_t is 32 bits, a date after year 2038 will overflow time_t and
656 // cause timegm() to return -1. The parsed time should not be 1 second
657 // before epoch.
TEST_F(TimeTest,ParseTimeTestEpochNotNeg1)658 TEST_F(TimeTest, ParseTimeTestEpochNotNeg1) {
659 Time parsed_time;
660
661 EXPECT_TRUE(Time::FromString("Wed Dec 31 23:59:59 GMT 2100",
662 &parsed_time));
663 EXPECT_NE(-1, parsed_time.ToTimeT());
664 }
665
TEST_F(TimeTest,ParseTimeTestEpochNeg2)666 TEST_F(TimeTest, ParseTimeTestEpochNeg2) {
667 Time parsed_time;
668
669 // time_t == 2 seconds before epoch == -2
670 EXPECT_TRUE(Time::FromString("Thu Jan 01 00:59:58 +0100 1970",
671 &parsed_time));
672 EXPECT_EQ(-2, parsed_time.ToTimeT());
673 EXPECT_TRUE(Time::FromString("Wed Dec 31 23:59:58 GMT 1969",
674 &parsed_time));
675 EXPECT_EQ(-2, parsed_time.ToTimeT());
676 }
677
TEST_F(TimeTest,ParseTimeTestEpoch1960)678 TEST_F(TimeTest, ParseTimeTestEpoch1960) {
679 Time parsed_time;
680
681 // time_t before Epoch, in 1960
682 EXPECT_TRUE(Time::FromString("Wed Jun 29 19:40:01 +0100 1960",
683 &parsed_time));
684 EXPECT_EQ(-299999999, parsed_time.ToTimeT());
685 EXPECT_TRUE(Time::FromString("Wed Jun 29 18:40:01 GMT 1960",
686 &parsed_time));
687 EXPECT_EQ(-299999999, parsed_time.ToTimeT());
688 EXPECT_TRUE(Time::FromString("Wed Jun 29 17:40:01 GMT 1960",
689 &parsed_time));
690 EXPECT_EQ(-300003599, parsed_time.ToTimeT());
691 }
692
TEST_F(TimeTest,ParseTimeTestEmpty)693 TEST_F(TimeTest, ParseTimeTestEmpty) {
694 Time parsed_time;
695 EXPECT_FALSE(Time::FromString("", &parsed_time));
696 }
697
TEST_F(TimeTest,ParseTimeTestInvalidString)698 TEST_F(TimeTest, ParseTimeTestInvalidString) {
699 Time parsed_time;
700 EXPECT_FALSE(Time::FromString("Monday morning 2000", &parsed_time));
701 }
702
TEST_F(TimeTest,ExplodeBeforeUnixEpoch)703 TEST_F(TimeTest, ExplodeBeforeUnixEpoch) {
704 static const int kUnixEpochYear = 1970; // In case this changes (ha!).
705 Time t;
706 Time::Exploded exploded;
707
708 t = Time::UnixEpoch() - Microseconds(1);
709 t.UTCExplode(&exploded);
710 EXPECT_TRUE(exploded.HasValidValues());
711 // Should be 1969-12-31 23:59:59 999 milliseconds (and 999 microseconds).
712 EXPECT_EQ(kUnixEpochYear - 1, exploded.year);
713 EXPECT_EQ(12, exploded.month);
714 EXPECT_EQ(31, exploded.day_of_month);
715 EXPECT_EQ(23, exploded.hour);
716 EXPECT_EQ(59, exploded.minute);
717 EXPECT_EQ(59, exploded.second);
718 EXPECT_EQ(999, exploded.millisecond);
719
720 t = Time::UnixEpoch() - Microseconds(999);
721 t.UTCExplode(&exploded);
722 EXPECT_TRUE(exploded.HasValidValues());
723 // Should be 1969-12-31 23:59:59 999 milliseconds (and 1 microsecond).
724 EXPECT_EQ(kUnixEpochYear - 1, exploded.year);
725 EXPECT_EQ(12, exploded.month);
726 EXPECT_EQ(31, exploded.day_of_month);
727 EXPECT_EQ(23, exploded.hour);
728 EXPECT_EQ(59, exploded.minute);
729 EXPECT_EQ(59, exploded.second);
730 EXPECT_EQ(999, exploded.millisecond);
731
732 t = Time::UnixEpoch() - Microseconds(1000);
733 t.UTCExplode(&exploded);
734 EXPECT_TRUE(exploded.HasValidValues());
735 // Should be 1969-12-31 23:59:59 999 milliseconds.
736 EXPECT_EQ(kUnixEpochYear - 1, exploded.year);
737 EXPECT_EQ(12, exploded.month);
738 EXPECT_EQ(31, exploded.day_of_month);
739 EXPECT_EQ(23, exploded.hour);
740 EXPECT_EQ(59, exploded.minute);
741 EXPECT_EQ(59, exploded.second);
742 EXPECT_EQ(999, exploded.millisecond);
743
744 t = Time::UnixEpoch() - Microseconds(1001);
745 t.UTCExplode(&exploded);
746 EXPECT_TRUE(exploded.HasValidValues());
747 // Should be 1969-12-31 23:59:59 998 milliseconds (and 999 microseconds).
748 EXPECT_EQ(kUnixEpochYear - 1, exploded.year);
749 EXPECT_EQ(12, exploded.month);
750 EXPECT_EQ(31, exploded.day_of_month);
751 EXPECT_EQ(23, exploded.hour);
752 EXPECT_EQ(59, exploded.minute);
753 EXPECT_EQ(59, exploded.second);
754 EXPECT_EQ(998, exploded.millisecond);
755
756 t = Time::UnixEpoch() - Milliseconds(1000);
757 t.UTCExplode(&exploded);
758 EXPECT_TRUE(exploded.HasValidValues());
759 // Should be 1969-12-31 23:59:59.
760 EXPECT_EQ(kUnixEpochYear - 1, exploded.year);
761 EXPECT_EQ(12, exploded.month);
762 EXPECT_EQ(31, exploded.day_of_month);
763 EXPECT_EQ(23, exploded.hour);
764 EXPECT_EQ(59, exploded.minute);
765 EXPECT_EQ(59, exploded.second);
766 EXPECT_EQ(0, exploded.millisecond);
767
768 t = Time::UnixEpoch() - Milliseconds(1001);
769 t.UTCExplode(&exploded);
770 EXPECT_TRUE(exploded.HasValidValues());
771 // Should be 1969-12-31 23:59:58 999 milliseconds.
772 EXPECT_EQ(kUnixEpochYear - 1, exploded.year);
773 EXPECT_EQ(12, exploded.month);
774 EXPECT_EQ(31, exploded.day_of_month);
775 EXPECT_EQ(23, exploded.hour);
776 EXPECT_EQ(59, exploded.minute);
777 EXPECT_EQ(58, exploded.second);
778 EXPECT_EQ(999, exploded.millisecond);
779
780 // Make sure we still handle at/after Unix epoch correctly.
781 t = Time::UnixEpoch();
782 t.UTCExplode(&exploded);
783 EXPECT_TRUE(exploded.HasValidValues());
784 // Should be 1970-12-31 00:00:00 0 milliseconds.
785 EXPECT_EQ(kUnixEpochYear, exploded.year);
786 EXPECT_EQ(1, exploded.month);
787 EXPECT_EQ(1, exploded.day_of_month);
788 EXPECT_EQ(0, exploded.hour);
789 EXPECT_EQ(0, exploded.minute);
790 EXPECT_EQ(0, exploded.second);
791 EXPECT_EQ(0, exploded.millisecond);
792
793 t = Time::UnixEpoch() + Microseconds(1);
794 t.UTCExplode(&exploded);
795 EXPECT_TRUE(exploded.HasValidValues());
796 // Should be 1970-01-01 00:00:00 0 milliseconds (and 1 microsecond).
797 EXPECT_EQ(kUnixEpochYear, exploded.year);
798 EXPECT_EQ(1, exploded.month);
799 EXPECT_EQ(1, exploded.day_of_month);
800 EXPECT_EQ(0, exploded.hour);
801 EXPECT_EQ(0, exploded.minute);
802 EXPECT_EQ(0, exploded.second);
803 EXPECT_EQ(0, exploded.millisecond);
804
805 t = Time::UnixEpoch() + Microseconds(999);
806 t.UTCExplode(&exploded);
807 EXPECT_TRUE(exploded.HasValidValues());
808 // Should be 1970-01-01 00:00:00 0 milliseconds (and 999 microseconds).
809 EXPECT_EQ(kUnixEpochYear, exploded.year);
810 EXPECT_EQ(1, exploded.month);
811 EXPECT_EQ(1, exploded.day_of_month);
812 EXPECT_EQ(0, exploded.hour);
813 EXPECT_EQ(0, exploded.minute);
814 EXPECT_EQ(0, exploded.second);
815 EXPECT_EQ(0, exploded.millisecond);
816
817 t = Time::UnixEpoch() + Microseconds(1000);
818 t.UTCExplode(&exploded);
819 EXPECT_TRUE(exploded.HasValidValues());
820 // Should be 1970-01-01 00:00:00 1 millisecond.
821 EXPECT_EQ(kUnixEpochYear, exploded.year);
822 EXPECT_EQ(1, exploded.month);
823 EXPECT_EQ(1, exploded.day_of_month);
824 EXPECT_EQ(0, exploded.hour);
825 EXPECT_EQ(0, exploded.minute);
826 EXPECT_EQ(0, exploded.second);
827 EXPECT_EQ(1, exploded.millisecond);
828
829 t = Time::UnixEpoch() + Milliseconds(1000);
830 t.UTCExplode(&exploded);
831 EXPECT_TRUE(exploded.HasValidValues());
832 // Should be 1970-01-01 00:00:01.
833 EXPECT_EQ(kUnixEpochYear, exploded.year);
834 EXPECT_EQ(1, exploded.month);
835 EXPECT_EQ(1, exploded.day_of_month);
836 EXPECT_EQ(0, exploded.hour);
837 EXPECT_EQ(0, exploded.minute);
838 EXPECT_EQ(1, exploded.second);
839 EXPECT_EQ(0, exploded.millisecond);
840
841 t = Time::UnixEpoch() + Milliseconds(1001);
842 t.UTCExplode(&exploded);
843 EXPECT_TRUE(exploded.HasValidValues());
844 // Should be 1970-01-01 00:00:01 1 millisecond.
845 EXPECT_EQ(kUnixEpochYear, exploded.year);
846 EXPECT_EQ(1, exploded.month);
847 EXPECT_EQ(1, exploded.day_of_month);
848 EXPECT_EQ(0, exploded.hour);
849 EXPECT_EQ(0, exploded.minute);
850 EXPECT_EQ(1, exploded.second);
851 EXPECT_EQ(1, exploded.millisecond);
852 }
853
TEST_F(TimeTest,Max)854 TEST_F(TimeTest, Max) {
855 constexpr Time kMax = Time::Max();
856 static_assert(kMax.is_max());
857 static_assert(kMax == Time::Max());
858 EXPECT_GT(kMax, Time::Now());
859 static_assert(kMax > Time());
860 EXPECT_TRUE((Time::Now() - kMax).is_negative());
861 EXPECT_TRUE((kMax - Time::Now()).is_positive());
862 }
863
TEST_F(TimeTest,MaxConversions)864 TEST_F(TimeTest, MaxConversions) {
865 constexpr Time kMax = Time::Max();
866 static_assert(std::numeric_limits<int64_t>::max() == kMax.ToInternalValue(),
867 "");
868
869 Time t = Time::FromDoubleT(std::numeric_limits<double>::infinity());
870 EXPECT_TRUE(t.is_max());
871 EXPECT_EQ(std::numeric_limits<double>::infinity(), t.ToDoubleT());
872
873 t = Time::FromJsTime(std::numeric_limits<double>::infinity());
874 EXPECT_TRUE(t.is_max());
875 EXPECT_EQ(std::numeric_limits<double>::infinity(), t.ToJsTime());
876
877 t = Time::FromTimeT(std::numeric_limits<time_t>::max());
878 EXPECT_TRUE(t.is_max());
879 EXPECT_EQ(std::numeric_limits<time_t>::max(), t.ToTimeT());
880
881 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
882 struct timeval tval;
883 tval.tv_sec = std::numeric_limits<time_t>::max();
884 tval.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1;
885 t = Time::FromTimeVal(tval);
886 EXPECT_TRUE(t.is_max());
887 tval = t.ToTimeVal();
888 EXPECT_EQ(std::numeric_limits<time_t>::max(), tval.tv_sec);
889 EXPECT_EQ(static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1,
890 tval.tv_usec);
891 #endif
892
893 #if BUILDFLAG(IS_APPLE)
894 t = Time::FromCFAbsoluteTime(std::numeric_limits<CFAbsoluteTime>::infinity());
895 EXPECT_TRUE(t.is_max());
896 EXPECT_EQ(std::numeric_limits<CFAbsoluteTime>::infinity(),
897 t.ToCFAbsoluteTime());
898 #endif
899
900 #if BUILDFLAG(IS_WIN)
901 FILETIME ftime;
902 ftime.dwHighDateTime = std::numeric_limits<DWORD>::max();
903 ftime.dwLowDateTime = std::numeric_limits<DWORD>::max();
904 t = Time::FromFileTime(ftime);
905 EXPECT_TRUE(t.is_max());
906 ftime = t.ToFileTime();
907 EXPECT_EQ(std::numeric_limits<DWORD>::max(), ftime.dwHighDateTime);
908 EXPECT_EQ(std::numeric_limits<DWORD>::max(), ftime.dwLowDateTime);
909 #endif
910 }
911
TEST_F(TimeTest,Min)912 TEST_F(TimeTest, Min) {
913 constexpr Time kMin = Time::Min();
914 static_assert(kMin.is_min());
915 static_assert(kMin == Time::Min());
916 EXPECT_LT(kMin, Time::Now());
917 static_assert(kMin < Time());
918 EXPECT_TRUE((Time::Now() - kMin).is_positive());
919 EXPECT_TRUE((kMin - Time::Now()).is_negative());
920 }
921
922 #if BUILDFLAG(IS_APPLE)
TEST_F(TimeTest,TimeTOverflow)923 TEST_F(TimeTest, TimeTOverflow) {
924 constexpr Time kMaxMinusOne =
925 Time::FromInternalValue(std::numeric_limits<int64_t>::max() - 1);
926 static_assert(!kMaxMinusOne.is_max());
927 EXPECT_EQ(std::numeric_limits<time_t>::max(), kMaxMinusOne.ToTimeT());
928 }
929 #endif
930
931 #if BUILDFLAG(IS_ANDROID)
TEST_F(TimeTest,FromLocalExplodedCrashOnAndroid)932 TEST_F(TimeTest, FromLocalExplodedCrashOnAndroid) {
933 // This crashed inside Time:: FromLocalExploded() on Android 4.1.2.
934 // See http://crbug.com/287821
935 Time::Exploded midnight = {2013, // year
936 10, // month
937 0, // day_of_week
938 13, // day_of_month
939 0, // hour
940 0, // minute
941 0, // second
942 };
943 // The string passed to putenv() must be a char* and the documentation states
944 // that it 'becomes part of the environment', so use a static buffer.
945 static char buffer[] = "TZ=America/Santiago";
946 putenv(buffer);
947 tzset();
948 Time t;
949 EXPECT_TRUE(Time::FromLocalExploded(midnight, &t));
950 EXPECT_EQ(1381633200, t.ToTimeT());
951 }
952 #endif // BUILDFLAG(IS_ANDROID)
953
954 // Regression test for https://crbug.com/1104442
TEST_F(TimeTest,Explode_Y10KCompliance)955 TEST_F(TimeTest, Explode_Y10KCompliance) {
956 constexpr int kDaysPerYear = 365;
957 constexpr int64_t kHalfYearInMicros = Days(kDaysPerYear / 2).InMicroseconds();
958
959 // The Y2038 issue occurs when a 32-bit signed integer overflows.
960 constexpr int64_t kYear2038MicrosOffset =
961 Time::kTimeTToMicrosecondsOffset +
962 (std::numeric_limits<int32_t>::max() * Time::kMicrosecondsPerSecond);
963
964 // 1 March 10000 at noon.
965 constexpr int64_t kYear10000YearsOffset = 10000 - 1970;
966 constexpr int kExtraLeapDaysOverThoseYears = 1947;
967 constexpr int kDaysFromJanToMar10000 = 31 + 29;
968 constexpr int64_t kMarch10000MicrosOffset =
969 Time::kTimeTToMicrosecondsOffset +
970 Days(kYear10000YearsOffset * kDaysPerYear + kExtraLeapDaysOverThoseYears +
971 kDaysFromJanToMar10000)
972 .InMicroseconds() +
973 Hours(12).InMicroseconds();
974
975 // Windows uses a 64-bit signed integer type that reperesents the number of
976 // 1/10 microsecond ticks.
977 constexpr int64_t kWindowsMaxMicrosOffset =
978 std::numeric_limits<int64_t>::max() / 10;
979
980 // ICU's Calendar API uses double values. Thus, the maximum supported value is
981 // the maximum integer that can be represented by a double.
982 static_assert(std::numeric_limits<double>::radix == 2);
983 constexpr int64_t kMaxIntegerAsDoubleMillis =
984 int64_t{1} << std::numeric_limits<double>::digits;
985 constexpr int64_t kIcuMaxMicrosOffset =
986 Time::kTimeTToMicrosecondsOffset +
987 (kMaxIntegerAsDoubleMillis * Time::kMicrosecondsPerMillisecond + 999);
988
989 const auto make_time = [](int64_t micros) {
990 return Time::FromDeltaSinceWindowsEpoch(Microseconds(micros));
991 };
992
993 const struct TestCase {
994 Time time;
995 Time::Exploded expected;
996 } kTestCases[] = {
997 // A very long time ago.
998 {Time::Min(), Time::Exploded{-290677, 12, 4, 23, 19, 59, 5, 224}},
999
1000 // Before/On/After 1 Jan 1601.
1001 {make_time(-kHalfYearInMicros),
1002 Time::Exploded{1600, 7, 1, 3, 0, 0, 0, 0}},
1003 {make_time(0), Time::Exploded{1601, 1, 1, 1, 0, 0, 0, 0}},
1004 {make_time(kHalfYearInMicros), Time::Exploded{1601, 7, 1, 2, 0, 0, 0, 0}},
1005
1006 // Before/On/After 1 Jan 1970.
1007 {make_time(Time::kTimeTToMicrosecondsOffset - kHalfYearInMicros),
1008 Time::Exploded{1969, 7, 4, 3, 0, 0, 0, 0}},
1009 {make_time(Time::kTimeTToMicrosecondsOffset),
1010 Time::Exploded{1970, 1, 4, 1, 0, 0, 0, 0}},
1011 {make_time(Time::kTimeTToMicrosecondsOffset + kHalfYearInMicros),
1012 Time::Exploded{1970, 7, 4, 2, 0, 0, 0, 0}},
1013
1014 // Before/On/After 19 January 2038.
1015 {make_time(kYear2038MicrosOffset - kHalfYearInMicros),
1016 Time::Exploded{2037, 7, 2, 21, 3, 14, 7, 0}},
1017 {make_time(kYear2038MicrosOffset),
1018 Time::Exploded{2038, 1, 2, 19, 3, 14, 7, 0}},
1019 {make_time(kYear2038MicrosOffset + kHalfYearInMicros),
1020 Time::Exploded{2038, 7, 2, 20, 3, 14, 7, 0}},
1021
1022 // Before/On/After 1 March 10000 at noon.
1023 {make_time(kMarch10000MicrosOffset - kHalfYearInMicros),
1024 Time::Exploded{9999, 9, 3, 1, 12, 0, 0, 0}},
1025 {make_time(kMarch10000MicrosOffset),
1026 Time::Exploded{10000, 3, 3, 1, 12, 0, 0, 0}},
1027 {make_time(kMarch10000MicrosOffset + kHalfYearInMicros),
1028 Time::Exploded{10000, 8, 3, 30, 12, 0, 0, 0}},
1029
1030 // Before/On/After Windows Max (14 September 30828).
1031 {make_time(kWindowsMaxMicrosOffset - kHalfYearInMicros),
1032 Time::Exploded{30828, 3, 4, 16, 2, 48, 5, 477}},
1033 {make_time(kWindowsMaxMicrosOffset),
1034 Time::Exploded{30828, 9, 4, 14, 2, 48, 5, 477}},
1035 {make_time(kWindowsMaxMicrosOffset + kHalfYearInMicros),
1036 Time::Exploded{30829, 3, 4, 15, 2, 48, 5, 477}},
1037
1038 // Before/On/After ICU Max.
1039 {make_time(kIcuMaxMicrosOffset - kHalfYearInMicros),
1040 Time::Exploded{287396, 4, 3, 13, 8, 59, 0, 992}},
1041 {make_time(kIcuMaxMicrosOffset),
1042 Time::Exploded{287396, 10, 3, 12, 8, 59, 0, 992}},
1043 {make_time(kIcuMaxMicrosOffset + kHalfYearInMicros),
1044 Time::Exploded{287397, 4, 3, 12, 8, 59, 0, 992}},
1045
1046 // A very long time from now.
1047 {Time::Max(), Time::Exploded{293878, 1, 4, 10, 4, 0, 54, 775}},
1048 };
1049
1050 for (const TestCase& test_case : kTestCases) {
1051 SCOPED_TRACE(testing::Message() << "Time: " << test_case.time);
1052
1053 Time::Exploded exploded = {};
1054 test_case.time.UTCExplode(&exploded);
1055
1056 // Confirm the implementation provides a correct conversion for all inputs
1057 // within the guaranteed range (as discussed in the header comments). If an
1058 // implementation provides a result for inputs outside the guaranteed range,
1059 // the result must still be correct.
1060 if (exploded.HasValidValues()) {
1061 EXPECT_EQ(test_case.expected.year, exploded.year);
1062 EXPECT_EQ(test_case.expected.month, exploded.month);
1063 EXPECT_EQ(test_case.expected.day_of_week, exploded.day_of_week);
1064 EXPECT_EQ(test_case.expected.day_of_month, exploded.day_of_month);
1065 EXPECT_EQ(test_case.expected.hour, exploded.hour);
1066 EXPECT_EQ(test_case.expected.minute, exploded.minute);
1067 EXPECT_EQ(test_case.expected.second, exploded.second);
1068 EXPECT_EQ(test_case.expected.millisecond, exploded.millisecond);
1069 } else {
1070 // The implementation could not provide a conversion. That is only allowed
1071 // for inputs outside the guaranteed range.
1072 const bool is_in_range =
1073 test_case.time >= make_time(0) &&
1074 test_case.time <= make_time(kWindowsMaxMicrosOffset);
1075 EXPECT_FALSE(is_in_range);
1076 }
1077 }
1078 }
1079
1080 #if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMEOS)
1081 // Regression tests for https://crbug.com/1198313: base::Time::UTCExplode and
1082 // base::Time::LocalExplode should not be locale-dependent.
TEST_F(TimeTest,UTCExplodedIsLocaleIndependent)1083 TEST_F(TimeTest, UTCExplodedIsLocaleIndependent) {
1084 // Time-to-Exploded could be using libc or ICU functions.
1085 // Set the ICU locale and timezone and the libc timezone.
1086 // We're not setting the libc locale because the libc time functions are
1087 // locale-independent and the th_TH.utf8 locale was not available on all
1088 // trybots at the time this test was added.
1089 // th-TH maps to a non-gregorian calendar.
1090 test::ScopedRestoreICUDefaultLocale scoped_icu_locale(kThaiLocale);
1091 test::ScopedRestoreDefaultTimezone scoped_timezone(kBangkokTimeZoneId);
1092 ScopedLibcTZ scoped_libc_tz(kBangkokTimeZoneId);
1093 ASSERT_TRUE(scoped_libc_tz.is_success());
1094
1095 Time::Exploded utc_exploded_orig;
1096 utc_exploded_orig.year = 2020;
1097 utc_exploded_orig.month = 7;
1098 utc_exploded_orig.day_of_week = 5; // Friday
1099 utc_exploded_orig.day_of_month = 3;
1100 utc_exploded_orig.hour = 12;
1101 utc_exploded_orig.minute = 0;
1102 utc_exploded_orig.second = 0;
1103 utc_exploded_orig.millisecond = 0;
1104
1105 Time time;
1106 ASSERT_TRUE(base::Time::FromUTCExploded(utc_exploded_orig, &time));
1107
1108 // Round trip to UTC Exploded should produce the exact same result.
1109 Time::Exploded utc_exploded;
1110 time.UTCExplode(&utc_exploded);
1111 EXPECT_EQ(utc_exploded_orig.year, utc_exploded.year);
1112 EXPECT_EQ(utc_exploded_orig.month, utc_exploded.month);
1113 EXPECT_EQ(utc_exploded_orig.day_of_week, utc_exploded.day_of_week);
1114 EXPECT_EQ(utc_exploded_orig.day_of_month, utc_exploded.day_of_month);
1115 EXPECT_EQ(utc_exploded_orig.hour, utc_exploded.hour);
1116 EXPECT_EQ(utc_exploded_orig.minute, utc_exploded.minute);
1117 EXPECT_EQ(utc_exploded_orig.second, utc_exploded.second);
1118 EXPECT_EQ(utc_exploded_orig.millisecond, utc_exploded.millisecond);
1119 }
1120
TEST_F(TimeTest,LocalExplodedIsLocaleIndependent)1121 TEST_F(TimeTest, LocalExplodedIsLocaleIndependent) {
1122 // Time-to-Exploded could be using libc or ICU functions.
1123 // Set the ICU locale and timezone and the libc timezone.
1124 // We're not setting the libc locale because the libc time functions are
1125 // locale-independent and the th_TH.utf8 locale was not available on all
1126 // trybots at the time this test was added.
1127 // th-TH maps to a non-gregorian calendar.
1128 test::ScopedRestoreICUDefaultLocale scoped_icu_locale(kThaiLocale);
1129 test::ScopedRestoreDefaultTimezone scoped_timezone(kBangkokTimeZoneId);
1130 ScopedLibcTZ scoped_libc_tz(kBangkokTimeZoneId);
1131 ASSERT_TRUE(scoped_libc_tz.is_success());
1132
1133 Time::Exploded utc_exploded_orig;
1134 utc_exploded_orig.year = 2020;
1135 utc_exploded_orig.month = 7;
1136 utc_exploded_orig.day_of_week = 5; // Friday
1137 utc_exploded_orig.day_of_month = 3;
1138 utc_exploded_orig.hour = 12;
1139 utc_exploded_orig.minute = 0;
1140 utc_exploded_orig.second = 0;
1141 utc_exploded_orig.millisecond = 0;
1142
1143 Time time;
1144 ASSERT_TRUE(base::Time::FromUTCExploded(utc_exploded_orig, &time));
1145
1146 absl::optional<TimeDelta> expected_delta =
1147 GetTimeZoneOffsetAtTime(kBangkokTimeZoneId, time);
1148
1149 ASSERT_TRUE(expected_delta.has_value());
1150
1151 // This is to be sure that the day has not changed
1152 ASSERT_LT(*expected_delta, base::Hours(12));
1153
1154 Time::Exploded local_exploded;
1155 time.LocalExplode(&local_exploded);
1156
1157 TimeDelta actual_delta = TimePassedAfterMidnight(local_exploded) -
1158 TimePassedAfterMidnight(utc_exploded_orig);
1159
1160 EXPECT_EQ(utc_exploded_orig.year, local_exploded.year);
1161 EXPECT_EQ(utc_exploded_orig.month, local_exploded.month);
1162 EXPECT_EQ(utc_exploded_orig.day_of_week, local_exploded.day_of_week);
1163 EXPECT_EQ(utc_exploded_orig.day_of_month, local_exploded.day_of_month);
1164 EXPECT_EQ(actual_delta, *expected_delta);
1165 }
1166 #endif // BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMEOS)
1167
TEST_F(TimeTest,FromExploded_MinMax)1168 TEST_F(TimeTest, FromExploded_MinMax) {
1169 Time::Exploded exploded = {0};
1170 exploded.month = 1;
1171 exploded.day_of_month = 1;
1172
1173 Time parsed_time;
1174
1175 if (Time::kExplodedMinYear != std::numeric_limits<int>::min()) {
1176 exploded.year = Time::kExplodedMinYear;
1177 EXPECT_TRUE(Time::FromUTCExploded(exploded, &parsed_time));
1178 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
1179 // On Windows, January 1, 1601 00:00:00 is actually the null time.
1180 EXPECT_FALSE(parsed_time.is_null());
1181 #endif
1182
1183 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_APPLE)
1184 // The dates earlier than |kExplodedMinYear| that don't work are OS version
1185 // dependent on Android and Mac (for example, macOS 10.13 seems to support
1186 // dates before 1902).
1187 exploded.year--;
1188 EXPECT_FALSE(Time::FromUTCExploded(exploded, &parsed_time));
1189 EXPECT_TRUE(parsed_time.is_null());
1190 #endif
1191 }
1192
1193 if (Time::kExplodedMaxYear != std::numeric_limits<int>::max()) {
1194 exploded.year = Time::kExplodedMaxYear;
1195 exploded.month = 12;
1196 exploded.day_of_month = 31;
1197 exploded.hour = 23;
1198 exploded.minute = 59;
1199 exploded.second = 59;
1200 exploded.millisecond = 999;
1201 EXPECT_TRUE(Time::FromUTCExploded(exploded, &parsed_time));
1202 EXPECT_FALSE(parsed_time.is_null());
1203
1204 exploded.year++;
1205 EXPECT_FALSE(Time::FromUTCExploded(exploded, &parsed_time));
1206 EXPECT_TRUE(parsed_time.is_null());
1207 }
1208 }
1209
1210 class TimeOverride {
1211 public:
Now()1212 static Time Now() {
1213 now_time_ += Seconds(1);
1214 return now_time_;
1215 }
1216
1217 static Time now_time_;
1218 };
1219
1220 // static
1221 Time TimeOverride::now_time_;
1222
TEST_F(TimeTest,NowOverride)1223 TEST_F(TimeTest, NowOverride) {
1224 TimeOverride::now_time_ = Time::UnixEpoch();
1225
1226 // Choose a reference time that we know to be in the past but close to now.
1227 Time build_time = GetBuildTime();
1228
1229 // Override is not active. All Now() methods should return a time greater than
1230 // the build time.
1231 EXPECT_LT(build_time, Time::Now());
1232 EXPECT_GT(Time::Max(), Time::Now());
1233 EXPECT_LT(build_time, subtle::TimeNowIgnoringOverride());
1234 EXPECT_GT(Time::Max(), subtle::TimeNowIgnoringOverride());
1235 EXPECT_LT(build_time, Time::NowFromSystemTime());
1236 EXPECT_GT(Time::Max(), Time::NowFromSystemTime());
1237 EXPECT_LT(build_time, subtle::TimeNowFromSystemTimeIgnoringOverride());
1238 EXPECT_GT(Time::Max(), subtle::TimeNowFromSystemTimeIgnoringOverride());
1239
1240 {
1241 // Set override.
1242 subtle::ScopedTimeClockOverrides overrides(&TimeOverride::Now, nullptr,
1243 nullptr);
1244
1245 // Overridden value is returned and incremented when Now() or
1246 // NowFromSystemTime() is called.
1247 EXPECT_EQ(Time::UnixEpoch() + Seconds(1), Time::Now());
1248 EXPECT_EQ(Time::UnixEpoch() + Seconds(2), Time::Now());
1249 EXPECT_EQ(Time::UnixEpoch() + Seconds(3), Time::NowFromSystemTime());
1250 EXPECT_EQ(Time::UnixEpoch() + Seconds(4), Time::NowFromSystemTime());
1251
1252 // IgnoringOverride methods still return real time.
1253 EXPECT_LT(build_time, subtle::TimeNowIgnoringOverride());
1254 EXPECT_GT(Time::Max(), subtle::TimeNowIgnoringOverride());
1255 EXPECT_LT(build_time, subtle::TimeNowFromSystemTimeIgnoringOverride());
1256 EXPECT_GT(Time::Max(), subtle::TimeNowFromSystemTimeIgnoringOverride());
1257
1258 // IgnoringOverride methods didn't call NowOverrideClock::Now().
1259 EXPECT_EQ(Time::UnixEpoch() + Seconds(5), Time::Now());
1260 EXPECT_EQ(Time::UnixEpoch() + Seconds(6), Time::NowFromSystemTime());
1261 }
1262
1263 // All methods return real time again.
1264 EXPECT_LT(build_time, Time::Now());
1265 EXPECT_GT(Time::Max(), Time::Now());
1266 EXPECT_LT(build_time, subtle::TimeNowIgnoringOverride());
1267 EXPECT_GT(Time::Max(), subtle::TimeNowIgnoringOverride());
1268 EXPECT_LT(build_time, Time::NowFromSystemTime());
1269 EXPECT_GT(Time::Max(), Time::NowFromSystemTime());
1270 EXPECT_LT(build_time, subtle::TimeNowFromSystemTimeIgnoringOverride());
1271 EXPECT_GT(Time::Max(), subtle::TimeNowFromSystemTimeIgnoringOverride());
1272 }
1273
1274 #undef MAYBE_NowOverride
1275
TEST_F(TimeTest,TimeFormatHTTP)1276 TEST_F(TimeTest, TimeFormatHTTP) {
1277 base::Time time;
1278 ASSERT_TRUE(base::Time::FromString("1994-11-06T08:49:37Z", &time));
1279 EXPECT_EQ("Sun, 06 Nov 1994 08:49:37 GMT", TimeFormatHTTP(time));
1280 }
1281
1282 #if BUILDFLAG(IS_FUCHSIA)
TEST(ZxTimeTest,ToFromConversions)1283 TEST(ZxTimeTest, ToFromConversions) {
1284 Time unix_epoch = Time::UnixEpoch();
1285 EXPECT_EQ(unix_epoch.ToZxTime(), 0);
1286 EXPECT_EQ(Time::FromZxTime(6000000000), unix_epoch + Seconds(6));
1287
1288 TimeTicks ticks_now = TimeTicks::Now();
1289 EXPECT_GE(ticks_now.ToZxTime(), 0);
1290 TimeTicks ticks_later = ticks_now + Seconds(2);
1291 EXPECT_EQ((ticks_later.ToZxTime() - ticks_now.ToZxTime()), 2000000000);
1292 EXPECT_EQ(TimeTicks::FromZxTime(3000000000), TimeTicks() + Seconds(3));
1293
1294 EXPECT_EQ(TimeDelta().ToZxDuration(), 0);
1295 EXPECT_EQ(TimeDelta::FromZxDuration(0), TimeDelta());
1296
1297 EXPECT_EQ(Seconds(2).ToZxDuration(), 2000000000);
1298 EXPECT_EQ(TimeDelta::FromZxDuration(4000000000), Seconds(4));
1299 }
1300 #endif // BUILDFLAG(IS_FUCHSIA)
1301
TEST(TimeTicks,Deltas)1302 TEST(TimeTicks, Deltas) {
1303 for (int index = 0; index < 50; index++) {
1304 TimeTicks ticks_start = TimeTicks::Now();
1305 base::PlatformThread::Sleep(base::Milliseconds(10));
1306 TimeTicks ticks_stop = TimeTicks::Now();
1307 TimeDelta delta = ticks_stop - ticks_start;
1308 // Note: Although we asked for a 10ms sleep, if the
1309 // time clock has a finer granularity than the Sleep()
1310 // clock, it is quite possible to wakeup early. Here
1311 // is how that works:
1312 // Time(ms timer) Time(us timer)
1313 // 5 5010
1314 // 6 6010
1315 // 7 7010
1316 // 8 8010
1317 // 9 9000
1318 // Elapsed 4ms 3990us
1319 //
1320 // Unfortunately, our InMilliseconds() function truncates
1321 // rather than rounds. We should consider fixing this
1322 // so that our averages come out better.
1323 EXPECT_GE(delta.InMilliseconds(), 9);
1324 EXPECT_GE(delta.InMicroseconds(), 9000);
1325 EXPECT_EQ(delta.InSeconds(), 0);
1326 }
1327 }
1328
HighResClockTest(TimeTicks (* GetTicks)())1329 static void HighResClockTest(TimeTicks (*GetTicks)()) {
1330 // IsHighResolution() is false on some systems. Since the product still works
1331 // even if it's false, it makes this entire test questionable.
1332 if (!TimeTicks::IsHighResolution())
1333 return;
1334
1335 // Why do we loop here?
1336 // We're trying to measure that intervals increment in a VERY small amount
1337 // of time -- less than 15ms. Unfortunately, if we happen to have a
1338 // context switch in the middle of our test, the context switch could easily
1339 // exceed our limit. So, we iterate on this several times. As long as we're
1340 // able to detect the fine-granularity timers at least once, then the test
1341 // has succeeded.
1342
1343 const int kTargetGranularityUs = 15000; // 15ms
1344
1345 bool success = false;
1346 int retries = 100; // Arbitrary.
1347 TimeDelta delta;
1348 while (!success && retries--) {
1349 TimeTicks ticks_start = GetTicks();
1350 // Loop until we can detect that the clock has changed. Non-HighRes timers
1351 // will increment in chunks, e.g. 15ms. By spinning until we see a clock
1352 // change, we detect the minimum time between measurements.
1353 do {
1354 delta = GetTicks() - ticks_start;
1355 } while (delta.InMilliseconds() == 0);
1356
1357 if (delta.InMicroseconds() <= kTargetGranularityUs)
1358 success = true;
1359 }
1360
1361 // In high resolution mode, we expect to see the clock increment
1362 // in intervals less than 15ms.
1363 EXPECT_TRUE(success);
1364 }
1365
TEST(TimeTicks,HighRes)1366 TEST(TimeTicks, HighRes) {
1367 HighResClockTest(&TimeTicks::Now);
1368 }
1369
1370 class TimeTicksOverride {
1371 public:
Now()1372 static TimeTicks Now() {
1373 now_ticks_ += Seconds(1);
1374 return now_ticks_;
1375 }
1376
1377 static TimeTicks now_ticks_;
1378 };
1379
1380 // static
1381 TimeTicks TimeTicksOverride::now_ticks_;
1382
TEST(TimeTicks,NowOverride)1383 TEST(TimeTicks, NowOverride) {
1384 TimeTicksOverride::now_ticks_ = TimeTicks::Min();
1385
1386 // Override is not active. All Now() methods should return a sensible value.
1387 EXPECT_LT(TimeTicks::Min(), TimeTicks::UnixEpoch());
1388 EXPECT_LT(TimeTicks::UnixEpoch(), TimeTicks::Now());
1389 EXPECT_GT(TimeTicks::Max(), TimeTicks::Now());
1390 EXPECT_LT(TimeTicks::UnixEpoch(), subtle::TimeTicksNowIgnoringOverride());
1391 EXPECT_GT(TimeTicks::Max(), subtle::TimeTicksNowIgnoringOverride());
1392
1393 {
1394 // Set override.
1395 subtle::ScopedTimeClockOverrides overrides(nullptr, &TimeTicksOverride::Now,
1396 nullptr);
1397
1398 // Overridden value is returned and incremented when Now() is called.
1399 EXPECT_EQ(TimeTicks::Min() + Seconds(1), TimeTicks::Now());
1400 EXPECT_EQ(TimeTicks::Min() + Seconds(2), TimeTicks::Now());
1401
1402 // NowIgnoringOverride() still returns real ticks.
1403 EXPECT_LT(TimeTicks::UnixEpoch(), subtle::TimeTicksNowIgnoringOverride());
1404 EXPECT_GT(TimeTicks::Max(), subtle::TimeTicksNowIgnoringOverride());
1405
1406 // IgnoringOverride methods didn't call NowOverrideTickClock::NowTicks().
1407 EXPECT_EQ(TimeTicks::Min() + Seconds(3), TimeTicks::Now());
1408 }
1409
1410 // All methods return real ticks again.
1411 EXPECT_LT(TimeTicks::UnixEpoch(), TimeTicks::Now());
1412 EXPECT_GT(TimeTicks::Max(), TimeTicks::Now());
1413 EXPECT_LT(TimeTicks::UnixEpoch(), subtle::TimeTicksNowIgnoringOverride());
1414 EXPECT_GT(TimeTicks::Max(), subtle::TimeTicksNowIgnoringOverride());
1415 }
1416
1417 class ThreadTicksOverride {
1418 public:
Now()1419 static ThreadTicks Now() {
1420 now_ticks_ += Seconds(1);
1421 return now_ticks_;
1422 }
1423
1424 static ThreadTicks now_ticks_;
1425 };
1426
1427 // static
1428 ThreadTicks ThreadTicksOverride::now_ticks_;
1429
1430 // IOS doesn't support ThreadTicks::Now().
1431 #if BUILDFLAG(IS_IOS)
1432 #define MAYBE_NowOverride DISABLED_NowOverride
1433 #else
1434 #define MAYBE_NowOverride NowOverride
1435 #endif
TEST(ThreadTicks,MAYBE_NowOverride)1436 TEST(ThreadTicks, MAYBE_NowOverride) {
1437 ThreadTicksOverride::now_ticks_ = ThreadTicks::Min();
1438
1439 // Override is not active. All Now() methods should return a sensible value.
1440 ThreadTicks initial_thread_ticks = ThreadTicks::Now();
1441 EXPECT_LE(initial_thread_ticks, ThreadTicks::Now());
1442 EXPECT_GT(ThreadTicks::Max(), ThreadTicks::Now());
1443 EXPECT_LE(initial_thread_ticks, subtle::ThreadTicksNowIgnoringOverride());
1444 EXPECT_GT(ThreadTicks::Max(), subtle::ThreadTicksNowIgnoringOverride());
1445
1446 {
1447 // Set override.
1448 subtle::ScopedTimeClockOverrides overrides(nullptr, nullptr,
1449 &ThreadTicksOverride::Now);
1450
1451 // Overridden value is returned and incremented when Now() is called.
1452 EXPECT_EQ(ThreadTicks::Min() + Seconds(1), ThreadTicks::Now());
1453 EXPECT_EQ(ThreadTicks::Min() + Seconds(2), ThreadTicks::Now());
1454
1455 // NowIgnoringOverride() still returns real ticks.
1456 EXPECT_LE(initial_thread_ticks, subtle::ThreadTicksNowIgnoringOverride());
1457 EXPECT_GT(ThreadTicks::Max(), subtle::ThreadTicksNowIgnoringOverride());
1458
1459 // IgnoringOverride methods didn't call NowOverrideTickClock::NowTicks().
1460 EXPECT_EQ(ThreadTicks::Min() + Seconds(3), ThreadTicks::Now());
1461 }
1462
1463 // All methods return real ticks again.
1464 EXPECT_LE(initial_thread_ticks, ThreadTicks::Now());
1465 EXPECT_GT(ThreadTicks::Max(), ThreadTicks::Now());
1466 EXPECT_LE(initial_thread_ticks, subtle::ThreadTicksNowIgnoringOverride());
1467 EXPECT_GT(ThreadTicks::Max(), subtle::ThreadTicksNowIgnoringOverride());
1468 }
1469
TEST(ThreadTicks,ThreadNow)1470 TEST(ThreadTicks, ThreadNow) {
1471 if (ThreadTicks::IsSupported()) {
1472 ThreadTicks::WaitUntilInitialized();
1473 TimeTicks begin = TimeTicks::Now();
1474 ThreadTicks begin_thread = ThreadTicks::Now();
1475 // Make sure that ThreadNow value is non-zero.
1476 EXPECT_GT(begin_thread, ThreadTicks());
1477 // Sleep for 10 milliseconds to get the thread de-scheduled.
1478 base::PlatformThread::Sleep(base::Milliseconds(10));
1479 ThreadTicks end_thread = ThreadTicks::Now();
1480 TimeTicks end = TimeTicks::Now();
1481 TimeDelta delta = end - begin;
1482 TimeDelta delta_thread = end_thread - begin_thread;
1483 // Make sure that some thread time have elapsed.
1484 EXPECT_GE(delta_thread.InMicroseconds(), 0);
1485 // But the thread time is at least 9ms less than clock time.
1486 TimeDelta difference = delta - delta_thread;
1487 EXPECT_GE(difference.InMicroseconds(), 9000);
1488 }
1489 }
1490
TEST(TimeTicks,SnappedToNextTickBasic)1491 TEST(TimeTicks, SnappedToNextTickBasic) {
1492 base::TimeTicks phase = base::TimeTicks::FromInternalValue(4000);
1493 base::TimeDelta interval = base::Microseconds(1000);
1494 base::TimeTicks timestamp;
1495
1496 // Timestamp in previous interval.
1497 timestamp = base::TimeTicks::FromInternalValue(3500);
1498 EXPECT_EQ(4000,
1499 timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1500
1501 // Timestamp in next interval.
1502 timestamp = base::TimeTicks::FromInternalValue(4500);
1503 EXPECT_EQ(5000,
1504 timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1505
1506 // Timestamp multiple intervals before.
1507 timestamp = base::TimeTicks::FromInternalValue(2500);
1508 EXPECT_EQ(3000,
1509 timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1510
1511 // Timestamp multiple intervals after.
1512 timestamp = base::TimeTicks::FromInternalValue(6500);
1513 EXPECT_EQ(7000,
1514 timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1515
1516 // Timestamp on previous interval.
1517 timestamp = base::TimeTicks::FromInternalValue(3000);
1518 EXPECT_EQ(3000,
1519 timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1520
1521 // Timestamp on next interval.
1522 timestamp = base::TimeTicks::FromInternalValue(5000);
1523 EXPECT_EQ(5000,
1524 timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1525
1526 // Timestamp equal to phase.
1527 timestamp = base::TimeTicks::FromInternalValue(4000);
1528 EXPECT_EQ(4000,
1529 timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1530 }
1531
TEST(TimeTicks,SnappedToNextTickOverflow)1532 TEST(TimeTicks, SnappedToNextTickOverflow) {
1533 // int(big_timestamp / interval) < 0, so this causes a crash if the number of
1534 // intervals elapsed is attempted to be stored in an int.
1535 base::TimeTicks phase = base::TimeTicks::FromInternalValue(0);
1536 base::TimeDelta interval = base::Microseconds(4000);
1537 base::TimeTicks big_timestamp =
1538 base::TimeTicks::FromInternalValue(8635916564000);
1539
1540 EXPECT_EQ(8635916564000,
1541 big_timestamp.SnappedToNextTick(phase, interval).ToInternalValue());
1542 EXPECT_EQ(8635916564000,
1543 big_timestamp.SnappedToNextTick(big_timestamp, interval)
1544 .ToInternalValue());
1545 }
1546
1547 #if BUILDFLAG(IS_ANDROID)
TEST(TimeTicks,Android_FromUptimeMillis_ClocksMatch)1548 TEST(TimeTicks, Android_FromUptimeMillis_ClocksMatch) {
1549 JNIEnv* const env = android::AttachCurrentThread();
1550 android::ScopedJavaLocalRef<jclass> clazz(
1551 android::GetClass(env, "android/os/SystemClock"));
1552 ASSERT_TRUE(clazz.obj());
1553 const jmethodID method_id =
1554 android::MethodID::Get<android::MethodID::TYPE_STATIC>(
1555 env, clazz.obj(), "uptimeMillis", "()J");
1556 ASSERT_FALSE(!method_id);
1557 // Subtract 1ms from the expected lower bound to allow millisecond-level
1558 // truncation performed in uptimeMillis().
1559 const TimeTicks lower_bound_ticks = TimeTicks::Now() - Milliseconds(1);
1560 const TimeTicks converted_ticks = TimeTicks::FromUptimeMillis(
1561 env->CallStaticLongMethod(clazz.obj(), method_id));
1562 const TimeTicks upper_bound_ticks = TimeTicks::Now();
1563 EXPECT_LE(lower_bound_ticks, converted_ticks);
1564 EXPECT_GE(upper_bound_ticks, converted_ticks);
1565 }
1566
TEST(TimeTicks,Android_FromJavaNanoTime_ClocksMatch)1567 TEST(TimeTicks, Android_FromJavaNanoTime_ClocksMatch) {
1568 JNIEnv* const env = android::AttachCurrentThread();
1569 android::ScopedJavaLocalRef<jclass> clazz(
1570 android::GetClass(env, "java/lang/System"));
1571 ASSERT_TRUE(clazz.obj());
1572 const jmethodID method_id =
1573 android::MethodID::Get<android::MethodID::TYPE_STATIC>(env, clazz.obj(),
1574 "nanoTime", "()J");
1575 ASSERT_FALSE(!method_id);
1576 const TimeTicks lower_bound_ticks = TimeTicks::Now();
1577 const TimeTicks converted_ticks = TimeTicks::FromJavaNanoTime(
1578 env->CallStaticLongMethod(clazz.obj(), method_id));
1579 // Add 1us to the expected upper bound to allow microsecond-level
1580 // truncation performed in TimeTicks::Now().
1581 const TimeTicks upper_bound_ticks = TimeTicks::Now() + Microseconds(1);
1582 EXPECT_LE(lower_bound_ticks, converted_ticks);
1583 EXPECT_GE(upper_bound_ticks, converted_ticks);
1584 }
1585 #endif // BUILDFLAG(IS_ANDROID)
1586
TEST(TimeDelta,FromAndIn)1587 TEST(TimeDelta, FromAndIn) {
1588 // static_assert also checks that the contained expression is a constant
1589 // expression, meaning all its components are suitable for initializing global
1590 // variables.
1591 static_assert(Days(2) == Hours(48));
1592 static_assert(Hours(3) == Minutes(180));
1593 static_assert(Minutes(2) == Seconds(120));
1594 static_assert(Seconds(2) == Milliseconds(2000));
1595 static_assert(Milliseconds(2) == Microseconds(2000));
1596 static_assert(Seconds(2.3) == Milliseconds(2300));
1597 static_assert(Milliseconds(2.5) == Microseconds(2500));
1598 EXPECT_EQ(Days(13).InDays(), 13);
1599 static_assert(Hours(13).InHours() == 13);
1600 static_assert(Minutes(13).InMinutes() == 13);
1601 static_assert(Seconds(13).InSeconds() == 13);
1602 static_assert(Seconds(13).InSecondsF() == 13.0);
1603 EXPECT_EQ(Milliseconds(13).InMilliseconds(), 13);
1604 EXPECT_EQ(Milliseconds(13).InMillisecondsF(), 13.0);
1605 static_assert(Seconds(13.1).InSeconds() == 13);
1606 static_assert(Seconds(13.1).InSecondsF() == 13.1);
1607 EXPECT_EQ(Milliseconds(13.3).InMilliseconds(), 13);
1608 EXPECT_EQ(Milliseconds(13.3).InMillisecondsF(), 13.3);
1609 static_assert(Microseconds(13).InMicroseconds() == 13);
1610 static_assert(Microseconds(13.3).InMicroseconds() == 13);
1611 EXPECT_EQ(Milliseconds(3.45678).InMillisecondsF(), 3.456);
1612 static_assert(Nanoseconds(12345).InNanoseconds() == 12000);
1613 static_assert(Nanoseconds(12345.678).InNanoseconds() == 12000);
1614 }
1615
TEST(TimeDelta,InRoundsTowardsZero)1616 TEST(TimeDelta, InRoundsTowardsZero) {
1617 EXPECT_EQ(Hours(23).InDays(), 0);
1618 EXPECT_EQ(Hours(-23).InDays(), 0);
1619 static_assert(Minutes(59).InHours() == 0);
1620 static_assert(Minutes(-59).InHours() == 0);
1621 static_assert(Seconds(59).InMinutes() == 0);
1622 static_assert(Seconds(-59).InMinutes() == 0);
1623 static_assert(Milliseconds(999).InSeconds() == 0);
1624 static_assert(Milliseconds(-999).InSeconds() == 0);
1625 EXPECT_EQ(Microseconds(999).InMilliseconds(), 0);
1626 EXPECT_EQ(Microseconds(-999).InMilliseconds(), 0);
1627 }
1628
TEST(TimeDelta,InDaysFloored)1629 TEST(TimeDelta, InDaysFloored) {
1630 EXPECT_EQ(Hours(-25).InDaysFloored(), -2);
1631 EXPECT_EQ(Hours(-24).InDaysFloored(), -1);
1632 EXPECT_EQ(Hours(-23).InDaysFloored(), -1);
1633
1634 EXPECT_EQ(Hours(-1).InDaysFloored(), -1);
1635 EXPECT_EQ(Hours(0).InDaysFloored(), 0);
1636 EXPECT_EQ(Hours(1).InDaysFloored(), 0);
1637
1638 EXPECT_EQ(Hours(23).InDaysFloored(), 0);
1639 EXPECT_EQ(Hours(24).InDaysFloored(), 1);
1640 EXPECT_EQ(Hours(25).InDaysFloored(), 1);
1641 }
1642
TEST(TimeDelta,InMillisecondsRoundedUp)1643 TEST(TimeDelta, InMillisecondsRoundedUp) {
1644 EXPECT_EQ(Microseconds(-1001).InMillisecondsRoundedUp(), -1);
1645 EXPECT_EQ(Microseconds(-1000).InMillisecondsRoundedUp(), -1);
1646 EXPECT_EQ(Microseconds(-999).InMillisecondsRoundedUp(), 0);
1647
1648 EXPECT_EQ(Microseconds(-1).InMillisecondsRoundedUp(), 0);
1649 EXPECT_EQ(Microseconds(0).InMillisecondsRoundedUp(), 0);
1650 EXPECT_EQ(Microseconds(1).InMillisecondsRoundedUp(), 1);
1651
1652 EXPECT_EQ(Microseconds(999).InMillisecondsRoundedUp(), 1);
1653 EXPECT_EQ(Microseconds(1000).InMillisecondsRoundedUp(), 1);
1654 EXPECT_EQ(Microseconds(1001).InMillisecondsRoundedUp(), 2);
1655 }
1656
1657 // Check that near-min/max values saturate rather than overflow when converted
1658 // lossily with InXXX() functions. Only integral hour, minute, and nanosecond
1659 // conversions are checked, since those are the only cases where the return type
1660 // is small enough for saturation or overflow to occur.
TEST(TimeDelta,InXXXOverflow)1661 TEST(TimeDelta, InXXXOverflow) {
1662 constexpr TimeDelta kLargeDelta =
1663 Microseconds(std::numeric_limits<int64_t>::max() - 1);
1664 static_assert(!kLargeDelta.is_max());
1665 static_assert(std::numeric_limits<int>::max() == kLargeDelta.InHours());
1666 static_assert(std::numeric_limits<int>::max() == kLargeDelta.InMinutes());
1667 static_assert(
1668 std::numeric_limits<int64_t>::max() == kLargeDelta.InNanoseconds(), "");
1669
1670 constexpr TimeDelta kLargeNegative =
1671 Microseconds(std::numeric_limits<int64_t>::min() + 1);
1672 static_assert(!kLargeNegative.is_min());
1673 static_assert(std::numeric_limits<int>::min() == kLargeNegative.InHours(),
1674 "");
1675 static_assert(std::numeric_limits<int>::min() == kLargeNegative.InMinutes(),
1676 "");
1677 static_assert(
1678 std::numeric_limits<int64_t>::min() == kLargeNegative.InNanoseconds(),
1679 "");
1680 }
1681
1682 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
TEST(TimeDelta,TimeSpecConversion)1683 TEST(TimeDelta, TimeSpecConversion) {
1684 TimeDelta delta = Seconds(0);
1685 struct timespec result = delta.ToTimeSpec();
1686 EXPECT_EQ(result.tv_sec, 0);
1687 EXPECT_EQ(result.tv_nsec, 0);
1688 EXPECT_EQ(delta, TimeDelta::FromTimeSpec(result));
1689
1690 delta = Seconds(1);
1691 result = delta.ToTimeSpec();
1692 EXPECT_EQ(result.tv_sec, 1);
1693 EXPECT_EQ(result.tv_nsec, 0);
1694 EXPECT_EQ(delta, TimeDelta::FromTimeSpec(result));
1695
1696 delta = Microseconds(1);
1697 result = delta.ToTimeSpec();
1698 EXPECT_EQ(result.tv_sec, 0);
1699 EXPECT_EQ(result.tv_nsec, 1000);
1700 EXPECT_EQ(delta, TimeDelta::FromTimeSpec(result));
1701
1702 delta = Microseconds(Time::kMicrosecondsPerSecond + 1);
1703 result = delta.ToTimeSpec();
1704 EXPECT_EQ(result.tv_sec, 1);
1705 EXPECT_EQ(result.tv_nsec, 1000);
1706 EXPECT_EQ(delta, TimeDelta::FromTimeSpec(result));
1707 }
1708 #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
1709
1710 // Our internal time format is serialized in things like databases, so it's
1711 // important that it's consistent across all our platforms. We use the 1601
1712 // Windows epoch as the internal format across all platforms.
TEST(TimeDelta,WindowsEpoch)1713 TEST(TimeDelta, WindowsEpoch) {
1714 Time::Exploded exploded;
1715 exploded.year = 1970;
1716 exploded.month = 1;
1717 exploded.day_of_week = 0; // Should be unusued.
1718 exploded.day_of_month = 1;
1719 exploded.hour = 0;
1720 exploded.minute = 0;
1721 exploded.second = 0;
1722 exploded.millisecond = 0;
1723 Time t;
1724 EXPECT_TRUE(Time::FromUTCExploded(exploded, &t));
1725 // Unix 1970 epoch.
1726 EXPECT_EQ(INT64_C(11644473600000000), t.ToInternalValue());
1727
1728 // We can't test 1601 epoch, since the system time functions on Linux
1729 // only compute years starting from 1900.
1730 }
1731
TEST(TimeDelta,Hz)1732 TEST(TimeDelta, Hz) {
1733 static_assert(Hertz(1) == Seconds(1));
1734 EXPECT_EQ(Hertz(0), TimeDelta::Max());
1735 static_assert(Hertz(-1) == Seconds(-1));
1736 static_assert(Hertz(1000) == Milliseconds(1));
1737 static_assert(Hertz(0.5) == Seconds(2));
1738 static_assert(Hertz(std::numeric_limits<double>::infinity()) == TimeDelta(),
1739 "");
1740
1741 static_assert(Seconds(1).ToHz() == 1);
1742 static_assert(TimeDelta::Max().ToHz() == 0);
1743 static_assert(Seconds(-1).ToHz() == -1);
1744 static_assert(Milliseconds(1).ToHz() == 1000);
1745 static_assert(Seconds(2).ToHz() == 0.5);
1746 EXPECT_EQ(TimeDelta().ToHz(), std::numeric_limits<double>::infinity());
1747
1748 // 60 Hz can't be represented exactly.
1749 static_assert(Hertz(60) * 60 != Seconds(1));
1750 static_assert(Hertz(60).ToHz() != 60);
1751 EXPECT_EQ(base::ClampRound(Hertz(60).ToHz()), 60);
1752 }
1753
1754 // We could define this separately for Time, TimeTicks and TimeDelta but the
1755 // definitions would be identical anyway.
1756 template <class Any>
AnyToString(Any any)1757 std::string AnyToString(Any any) {
1758 std::ostringstream oss;
1759 oss << any;
1760 return oss.str();
1761 }
1762
TEST(TimeDelta,Magnitude)1763 TEST(TimeDelta, Magnitude) {
1764 constexpr int64_t zero = 0;
1765 static_assert(Microseconds(zero) == Microseconds(zero).magnitude());
1766
1767 constexpr int64_t one = 1;
1768 constexpr int64_t negative_one = -1;
1769 static_assert(Microseconds(one) == Microseconds(one).magnitude());
1770 static_assert(Microseconds(one) == Microseconds(negative_one).magnitude(),
1771 "");
1772
1773 constexpr int64_t max_int64_minus_one =
1774 std::numeric_limits<int64_t>::max() - 1;
1775 constexpr int64_t min_int64_plus_two =
1776 std::numeric_limits<int64_t>::min() + 2;
1777 static_assert(Microseconds(max_int64_minus_one) ==
1778 Microseconds(max_int64_minus_one).magnitude(),
1779 "");
1780 static_assert(Microseconds(max_int64_minus_one) ==
1781 Microseconds(min_int64_plus_two).magnitude(),
1782 "");
1783
1784 static_assert(TimeDelta::Max() == TimeDelta::Min().magnitude());
1785 }
1786
TEST(TimeDelta,ZeroMinMax)1787 TEST(TimeDelta, ZeroMinMax) {
1788 constexpr TimeDelta kZero;
1789 static_assert(kZero.is_zero());
1790
1791 constexpr TimeDelta kMax = TimeDelta::Max();
1792 static_assert(kMax.is_max());
1793 static_assert(kMax == TimeDelta::Max());
1794 static_assert(kMax > Days(100 * 365));
1795 static_assert(kMax > kZero);
1796
1797 constexpr TimeDelta kMin = TimeDelta::Min();
1798 static_assert(kMin.is_min());
1799 static_assert(kMin == TimeDelta::Min());
1800 static_assert(kMin < Days(-100 * 365));
1801 static_assert(kMin < kZero);
1802 }
1803
TEST(TimeDelta,MaxConversions)1804 TEST(TimeDelta, MaxConversions) {
1805 // static_assert also confirms constexpr works as intended.
1806 constexpr TimeDelta kMax = TimeDelta::Max();
1807 static_assert(kMax.ToInternalValue() == std::numeric_limits<int64_t>::max(),
1808 "");
1809 EXPECT_EQ(kMax.InDays(), std::numeric_limits<int>::max());
1810 static_assert(kMax.InHours() == std::numeric_limits<int>::max());
1811 static_assert(kMax.InMinutes() == std::numeric_limits<int>::max());
1812 static_assert(kMax.InSecondsF() == std::numeric_limits<double>::infinity(),
1813 "");
1814 static_assert(kMax.InSeconds() == std::numeric_limits<int64_t>::max());
1815 EXPECT_EQ(kMax.InMillisecondsF(), std::numeric_limits<double>::infinity());
1816 EXPECT_EQ(kMax.InMilliseconds(), std::numeric_limits<int64_t>::max());
1817 EXPECT_EQ(kMax.InMillisecondsRoundedUp(), std::numeric_limits<int64_t>::max());
1818
1819 static_assert(Days(std::numeric_limits<int64_t>::max()).is_max());
1820
1821 static_assert(Hours(std::numeric_limits<int64_t>::max()).is_max());
1822
1823 static_assert(Minutes(std::numeric_limits<int64_t>::max()).is_max());
1824
1825 constexpr int64_t max_int = std::numeric_limits<int64_t>::max();
1826 constexpr int64_t min_int = std::numeric_limits<int64_t>::min();
1827
1828 static_assert(Seconds(max_int / Time::kMicrosecondsPerSecond + 1).is_max(),
1829 "");
1830
1831 static_assert(
1832 Milliseconds(max_int / Time::kMillisecondsPerSecond + 1).is_max(), "");
1833
1834 static_assert(Microseconds(max_int).is_max());
1835
1836 static_assert(Seconds(min_int / Time::kMicrosecondsPerSecond - 1).is_min(),
1837 "");
1838
1839 static_assert(
1840 Milliseconds(min_int / Time::kMillisecondsPerSecond - 1).is_min(), "");
1841
1842 static_assert(Microseconds(min_int).is_min());
1843
1844 static_assert(Microseconds(std::numeric_limits<int64_t>::min()).is_min());
1845
1846 static_assert(Seconds(std::numeric_limits<double>::infinity()).is_max());
1847
1848 // Note that max_int/min_int will be rounded when converted to doubles - they
1849 // can't be exactly represented.
1850 constexpr double max_d = static_cast<double>(max_int);
1851 constexpr double min_d = static_cast<double>(min_int);
1852
1853 static_assert(Seconds(max_d / Time::kMicrosecondsPerSecond + 1).is_max());
1854
1855 static_assert(
1856 Microseconds(max_d).is_max(),
1857 "Make sure that 2^63 correctly gets clamped to `max` (crbug.com/612601)");
1858
1859 static_assert(Milliseconds(std::numeric_limits<double>::infinity()).is_max(),
1860 "");
1861
1862 static_assert(Milliseconds(max_d / Time::kMillisecondsPerSecond * 2).is_max(),
1863 "");
1864
1865 static_assert(Seconds(min_d / Time::kMicrosecondsPerSecond - 1).is_min());
1866
1867 static_assert(Milliseconds(min_d / Time::kMillisecondsPerSecond * 2).is_min(),
1868 "");
1869 }
1870
TEST(TimeDelta,MinConversions)1871 TEST(TimeDelta, MinConversions) {
1872 constexpr TimeDelta kMin = TimeDelta::Min();
1873
1874 EXPECT_EQ(kMin.InDays(), std::numeric_limits<int>::min());
1875 static_assert(kMin.InHours() == std::numeric_limits<int>::min());
1876 static_assert(kMin.InMinutes() == std::numeric_limits<int>::min());
1877 static_assert(kMin.InSecondsF() == -std::numeric_limits<double>::infinity(),
1878 "");
1879 static_assert(kMin.InSeconds() == std::numeric_limits<int64_t>::min());
1880 EXPECT_EQ(kMin.InMillisecondsF(), -std::numeric_limits<double>::infinity());
1881 EXPECT_EQ(kMin.InMilliseconds(), std::numeric_limits<int64_t>::min());
1882 EXPECT_EQ(kMin.InMillisecondsRoundedUp(),
1883 std::numeric_limits<int64_t>::min());
1884 }
1885
TEST(TimeDelta,FiniteMaxMin)1886 TEST(TimeDelta, FiniteMaxMin) {
1887 constexpr TimeDelta kFiniteMax = TimeDelta::FiniteMax();
1888 constexpr TimeDelta kUnit = Microseconds(1);
1889 static_assert(kFiniteMax + kUnit == TimeDelta::Max());
1890 static_assert(kFiniteMax - kUnit < kFiniteMax);
1891
1892 constexpr TimeDelta kFiniteMin = TimeDelta::FiniteMin();
1893 static_assert(kFiniteMin - kUnit == TimeDelta::Min());
1894 static_assert(kFiniteMin + kUnit > kFiniteMin);
1895 }
1896
TEST(TimeDelta,NumericOperators)1897 TEST(TimeDelta, NumericOperators) {
1898 constexpr double d = 0.5;
1899 static_assert(Milliseconds(500) == Milliseconds(1000) * d);
1900 static_assert(Milliseconds(2000) == (Milliseconds(1000) / d));
1901 static_assert(Milliseconds(500) == (Milliseconds(1000) *= d));
1902 static_assert(Milliseconds(2000) == (Milliseconds(1000) /= d));
1903 static_assert(Milliseconds(500) == d * Milliseconds(1000));
1904
1905 constexpr float f = 0.5;
1906 static_assert(Milliseconds(500) == Milliseconds(1000) * f);
1907 static_assert(Milliseconds(2000) == (Milliseconds(1000) / f));
1908 static_assert(Milliseconds(500) == (Milliseconds(1000) *= f));
1909 static_assert(Milliseconds(2000) == (Milliseconds(1000) /= f));
1910 static_assert(Milliseconds(500) == f * Milliseconds(1000));
1911
1912 constexpr int i = 2;
1913 static_assert(Milliseconds(2000) == Milliseconds(1000) * i);
1914 static_assert(Milliseconds(500) == (Milliseconds(1000) / i));
1915 static_assert(Milliseconds(2000) == (Milliseconds(1000) *= i));
1916 static_assert(Milliseconds(500) == (Milliseconds(1000) /= i));
1917 static_assert(Milliseconds(2000) == i * Milliseconds(1000));
1918
1919 constexpr int64_t i64 = 2;
1920 static_assert(Milliseconds(2000) == Milliseconds(1000) * i64);
1921 static_assert(Milliseconds(500) == (Milliseconds(1000) / i64));
1922 static_assert(Milliseconds(2000) == (Milliseconds(1000) *= i64));
1923 static_assert(Milliseconds(500) == (Milliseconds(1000) /= i64));
1924 static_assert(Milliseconds(2000) == i64 * Milliseconds(1000));
1925
1926 static_assert(Milliseconds(500) == Milliseconds(1000) * 0.5);
1927 static_assert(Milliseconds(2000) == (Milliseconds(1000) / 0.5));
1928 static_assert(Milliseconds(500) == (Milliseconds(1000) *= 0.5));
1929 static_assert(Milliseconds(2000) == (Milliseconds(1000) /= 0.5));
1930 static_assert(Milliseconds(500) == 0.5 * Milliseconds(1000));
1931
1932 static_assert(Milliseconds(2000) == Milliseconds(1000) * 2);
1933 static_assert(Milliseconds(500) == (Milliseconds(1000) / 2));
1934 static_assert(Milliseconds(2000) == (Milliseconds(1000) *= 2));
1935 static_assert(Milliseconds(500) == (Milliseconds(1000) /= 2));
1936 static_assert(Milliseconds(2000) == 2 * Milliseconds(1000));
1937 }
1938
1939 // Basic test of operators between TimeDeltas (without overflow -- next test
1940 // handles overflow).
TEST(TimeDelta,TimeDeltaOperators)1941 TEST(TimeDelta, TimeDeltaOperators) {
1942 constexpr TimeDelta kElevenSeconds = Seconds(11);
1943 constexpr TimeDelta kThreeSeconds = Seconds(3);
1944
1945 static_assert(Seconds(14) == kElevenSeconds + kThreeSeconds);
1946 static_assert(Seconds(14) == kThreeSeconds + kElevenSeconds);
1947 static_assert(Seconds(8) == kElevenSeconds - kThreeSeconds);
1948 static_assert(Seconds(-8) == kThreeSeconds - kElevenSeconds);
1949 static_assert(11.0 / 3.0 == kElevenSeconds / kThreeSeconds);
1950 static_assert(3.0 / 11.0 == kThreeSeconds / kElevenSeconds);
1951 static_assert(3 == kElevenSeconds.IntDiv(kThreeSeconds));
1952 static_assert(0 == kThreeSeconds.IntDiv(kElevenSeconds));
1953 static_assert(Seconds(2) == kElevenSeconds % kThreeSeconds);
1954 }
1955
TEST(TimeDelta,Overflows)1956 TEST(TimeDelta, Overflows) {
1957 // Some sanity checks. static_asserts used where possible to verify constexpr
1958 // evaluation at the same time.
1959 static_assert(TimeDelta::Max().is_max());
1960 static_assert(TimeDelta::Max().is_positive());
1961 static_assert((-TimeDelta::Max()).is_negative());
1962 static_assert(-TimeDelta::Max() == TimeDelta::Min());
1963 static_assert(TimeDelta() > -TimeDelta::Max());
1964
1965 static_assert(TimeDelta::Min().is_min());
1966 static_assert(TimeDelta::Min().is_negative());
1967 static_assert((-TimeDelta::Min()).is_positive());
1968 static_assert(-TimeDelta::Min() == TimeDelta::Max());
1969 static_assert(TimeDelta() < -TimeDelta::Min());
1970
1971 constexpr TimeDelta kLargeDelta = TimeDelta::Max() - Milliseconds(1);
1972 constexpr TimeDelta kLargeNegative = -kLargeDelta;
1973 static_assert(TimeDelta() > kLargeNegative);
1974 static_assert(!kLargeDelta.is_max());
1975 static_assert(!(-kLargeNegative).is_min());
1976
1977 // Test +, -, * and / operators.
1978 constexpr TimeDelta kOneSecond = Seconds(1);
1979 static_assert((kLargeDelta + kOneSecond).is_max());
1980 static_assert((kLargeNegative + (-kOneSecond)).is_min());
1981 static_assert((kLargeNegative - kOneSecond).is_min());
1982 static_assert((kLargeDelta - (-kOneSecond)).is_max());
1983 static_assert((kLargeDelta * 2).is_max());
1984 static_assert((kLargeDelta * -2).is_min());
1985 static_assert((kLargeDelta / 0.5).is_max());
1986 static_assert((kLargeDelta / -0.5).is_min());
1987
1988 // Test math operators on Max() and Min() values
1989 // Calculations that would overflow are saturated.
1990 static_assert(TimeDelta::Max() + kOneSecond == TimeDelta::Max());
1991 static_assert(TimeDelta::Max() * 7 == TimeDelta::Max());
1992 static_assert(TimeDelta::FiniteMax() + kOneSecond == TimeDelta::Max());
1993 static_assert(TimeDelta::Min() - kOneSecond == TimeDelta::Min());
1994 static_assert(TimeDelta::Min() * 7 == TimeDelta::Min());
1995 static_assert(TimeDelta::FiniteMin() - kOneSecond == TimeDelta::Min());
1996
1997 // Division is done by converting to double with Max()/Min() converted to
1998 // +/- infinities.
1999 static_assert(
2000 TimeDelta::Max() / kOneSecond == std::numeric_limits<double>::infinity(),
2001 "");
2002 static_assert(TimeDelta::Max() / -kOneSecond ==
2003 -std::numeric_limits<double>::infinity(),
2004 "");
2005 static_assert(
2006 TimeDelta::Min() / kOneSecond == -std::numeric_limits<double>::infinity(),
2007 "");
2008 static_assert(
2009 TimeDelta::Min() / -kOneSecond == std::numeric_limits<double>::infinity(),
2010 "");
2011 static_assert(TimeDelta::Max().IntDiv(kOneSecond) ==
2012 std::numeric_limits<int64_t>::max(),
2013 "");
2014 static_assert(TimeDelta::Max().IntDiv(-kOneSecond) ==
2015 std::numeric_limits<int64_t>::min(),
2016 "");
2017 static_assert(TimeDelta::Min().IntDiv(kOneSecond) ==
2018 std::numeric_limits<int64_t>::min(),
2019 "");
2020 static_assert(TimeDelta::Min().IntDiv(-kOneSecond) ==
2021 std::numeric_limits<int64_t>::max(),
2022 "");
2023 static_assert(TimeDelta::Max() % kOneSecond == TimeDelta::Max());
2024 static_assert(TimeDelta::Max() % -kOneSecond == TimeDelta::Max());
2025 static_assert(TimeDelta::Min() % kOneSecond == TimeDelta::Min());
2026 static_assert(TimeDelta::Min() % -kOneSecond == TimeDelta::Min());
2027
2028 // Division by zero.
2029 static_assert((kOneSecond / 0).is_max());
2030 static_assert((-kOneSecond / 0).is_min());
2031 static_assert((TimeDelta::Max() / 0).is_max());
2032 static_assert((TimeDelta::Min() / 0).is_min());
2033 EXPECT_EQ(std::numeric_limits<double>::infinity(), kOneSecond / TimeDelta());
2034 EXPECT_EQ(-std::numeric_limits<double>::infinity(),
2035 -kOneSecond / TimeDelta());
2036 EXPECT_EQ(std::numeric_limits<double>::infinity(),
2037 TimeDelta::Max() / TimeDelta());
2038 EXPECT_EQ(-std::numeric_limits<double>::infinity(),
2039 TimeDelta::Min() / TimeDelta());
2040 static_assert(
2041 kOneSecond.IntDiv(TimeDelta()) == std::numeric_limits<int64_t>::max(),
2042 "");
2043 static_assert(
2044 (-kOneSecond).IntDiv(TimeDelta()) == std::numeric_limits<int64_t>::min(),
2045 "");
2046 static_assert(TimeDelta::Max().IntDiv(TimeDelta()) ==
2047 std::numeric_limits<int64_t>::max(),
2048 "");
2049 static_assert(TimeDelta::Min().IntDiv(TimeDelta()) ==
2050 std::numeric_limits<int64_t>::min(),
2051 "");
2052 static_assert(kOneSecond % TimeDelta() == kOneSecond);
2053 static_assert(-kOneSecond % TimeDelta() == -kOneSecond);
2054 static_assert(TimeDelta::Max() % TimeDelta() == TimeDelta::Max());
2055 static_assert(TimeDelta::Min() % TimeDelta() == TimeDelta::Min());
2056
2057 // Division by infinity.
2058 static_assert(kLargeDelta / TimeDelta::Min() == 0);
2059 static_assert(kLargeDelta / TimeDelta::Max() == 0);
2060 static_assert(kLargeNegative / TimeDelta::Min() == 0);
2061 static_assert(kLargeNegative / TimeDelta::Max() == 0);
2062 static_assert(kLargeDelta.IntDiv(TimeDelta::Min()) == 0);
2063 static_assert(kLargeDelta.IntDiv(TimeDelta::Max()) == 0);
2064 static_assert(kLargeNegative.IntDiv(TimeDelta::Min()) == 0);
2065 static_assert(kLargeNegative.IntDiv(TimeDelta::Max()) == 0);
2066 static_assert(kOneSecond % TimeDelta::Min() == kOneSecond);
2067 static_assert(kOneSecond % TimeDelta::Max() == kOneSecond);
2068
2069 // Test that double conversions overflow to infinity.
2070 static_assert((kLargeDelta + kOneSecond).InSecondsF() ==
2071 std::numeric_limits<double>::infinity(),
2072 "");
2073 EXPECT_EQ((kLargeDelta + kOneSecond).InMillisecondsF(),
2074 std::numeric_limits<double>::infinity());
2075 EXPECT_EQ((kLargeDelta + kOneSecond).InMicrosecondsF(),
2076 std::numeric_limits<double>::infinity());
2077
2078 // Test op=.
2079 static_assert((TimeDelta::FiniteMax() += kOneSecond).is_max());
2080 static_assert((TimeDelta::FiniteMin() += -kOneSecond).is_min());
2081
2082 static_assert((TimeDelta::FiniteMin() -= kOneSecond).is_min());
2083 static_assert((TimeDelta::FiniteMax() -= -kOneSecond).is_max());
2084
2085 static_assert((TimeDelta::FiniteMax() *= 2).is_max());
2086 static_assert((TimeDelta::FiniteMin() *= 1.5).is_min());
2087
2088 static_assert((TimeDelta::FiniteMax() /= 0.5).is_max());
2089 static_assert((TimeDelta::FiniteMin() /= 0.5).is_min());
2090
2091 static_assert((Seconds(1) %= TimeDelta::Max()) == Seconds(1));
2092 static_assert((Seconds(1) %= TimeDelta()) == Seconds(1));
2093
2094 // Test operations with Time and TimeTicks.
2095 EXPECT_TRUE((kLargeDelta + Time::Now()).is_max());
2096 EXPECT_TRUE((kLargeDelta + TimeTicks::Now()).is_max());
2097 EXPECT_TRUE((Time::Now() + kLargeDelta).is_max());
2098 EXPECT_TRUE((TimeTicks::Now() + kLargeDelta).is_max());
2099
2100 Time time_now = Time::Now();
2101 EXPECT_EQ(kOneSecond, (time_now + kOneSecond) - time_now);
2102 EXPECT_EQ(-kOneSecond, (time_now - kOneSecond) - time_now);
2103
2104 TimeTicks ticks_now = TimeTicks::Now();
2105 EXPECT_EQ(-kOneSecond, (ticks_now - kOneSecond) - ticks_now);
2106 EXPECT_EQ(kOneSecond, (ticks_now + kOneSecond) - ticks_now);
2107 }
2108
TEST(TimeDelta,CeilToMultiple)2109 TEST(TimeDelta, CeilToMultiple) {
2110 for (const auto interval : {Seconds(10), Seconds(-10)}) {
2111 SCOPED_TRACE(interval);
2112 EXPECT_EQ(TimeDelta().CeilToMultiple(interval), TimeDelta());
2113 EXPECT_EQ(Seconds(1).CeilToMultiple(interval), Seconds(10));
2114 EXPECT_EQ(Seconds(9).CeilToMultiple(interval), Seconds(10));
2115 EXPECT_EQ(Seconds(10).CeilToMultiple(interval), Seconds(10));
2116 EXPECT_EQ(Seconds(15).CeilToMultiple(interval), Seconds(20));
2117 EXPECT_EQ(Seconds(20).CeilToMultiple(interval), Seconds(20));
2118 EXPECT_EQ(TimeDelta::Max().CeilToMultiple(interval), TimeDelta::Max());
2119 EXPECT_EQ(Seconds(-1).CeilToMultiple(interval), TimeDelta());
2120 EXPECT_EQ(Seconds(-9).CeilToMultiple(interval), TimeDelta());
2121 EXPECT_EQ(Seconds(-10).CeilToMultiple(interval), Seconds(-10));
2122 EXPECT_EQ(Seconds(-15).CeilToMultiple(interval), Seconds(-10));
2123 EXPECT_EQ(Seconds(-20).CeilToMultiple(interval), Seconds(-20));
2124 EXPECT_EQ(TimeDelta::Min().CeilToMultiple(interval), TimeDelta::Min());
2125 }
2126
2127 for (const auto interval : {TimeDelta::Max(), TimeDelta::Min()}) {
2128 SCOPED_TRACE(interval);
2129 EXPECT_EQ(TimeDelta().CeilToMultiple(interval), TimeDelta());
2130 EXPECT_EQ(Seconds(1).CeilToMultiple(interval), TimeDelta::Max());
2131 EXPECT_EQ(Seconds(9).CeilToMultiple(interval), TimeDelta::Max());
2132 EXPECT_EQ(Seconds(10).CeilToMultiple(interval), TimeDelta::Max());
2133 EXPECT_EQ(Seconds(15).CeilToMultiple(interval), TimeDelta::Max());
2134 EXPECT_EQ(Seconds(20).CeilToMultiple(interval), TimeDelta::Max());
2135 EXPECT_EQ(TimeDelta::Max().CeilToMultiple(interval), TimeDelta::Max());
2136 EXPECT_EQ(Seconds(-1).CeilToMultiple(interval), TimeDelta());
2137 EXPECT_EQ(Seconds(-9).CeilToMultiple(interval), TimeDelta());
2138 EXPECT_EQ(Seconds(-10).CeilToMultiple(interval), TimeDelta());
2139 EXPECT_EQ(Seconds(-15).CeilToMultiple(interval), TimeDelta());
2140 EXPECT_EQ(Seconds(-20).CeilToMultiple(interval), TimeDelta());
2141 EXPECT_EQ(TimeDelta::Min().CeilToMultiple(interval), TimeDelta::Min());
2142 }
2143 }
2144
TEST(TimeDelta,FloorToMultiple)2145 TEST(TimeDelta, FloorToMultiple) {
2146 for (const auto interval : {Seconds(10), Seconds(-10)}) {
2147 SCOPED_TRACE(interval);
2148 EXPECT_EQ(TimeDelta().FloorToMultiple(interval), TimeDelta());
2149 EXPECT_EQ(Seconds(1).FloorToMultiple(interval), TimeDelta());
2150 EXPECT_EQ(Seconds(9).FloorToMultiple(interval), TimeDelta());
2151 EXPECT_EQ(Seconds(10).FloorToMultiple(interval), Seconds(10));
2152 EXPECT_EQ(Seconds(15).FloorToMultiple(interval), Seconds(10));
2153 EXPECT_EQ(Seconds(20).FloorToMultiple(interval), Seconds(20));
2154 EXPECT_EQ(TimeDelta::Max().FloorToMultiple(interval), TimeDelta::Max());
2155 EXPECT_EQ(Seconds(-1).FloorToMultiple(interval), Seconds(-10));
2156 EXPECT_EQ(Seconds(-9).FloorToMultiple(interval), Seconds(-10));
2157 EXPECT_EQ(Seconds(-10).FloorToMultiple(interval), Seconds(-10));
2158 EXPECT_EQ(Seconds(-15).FloorToMultiple(interval), Seconds(-20));
2159 EXPECT_EQ(Seconds(-20).FloorToMultiple(interval), Seconds(-20));
2160 EXPECT_EQ(TimeDelta::Min().FloorToMultiple(interval), TimeDelta::Min());
2161 }
2162
2163 for (const auto interval : {TimeDelta::Max(), TimeDelta::Min()}) {
2164 SCOPED_TRACE(interval);
2165 EXPECT_EQ(TimeDelta().FloorToMultiple(interval), TimeDelta());
2166 EXPECT_EQ(Seconds(1).FloorToMultiple(interval), TimeDelta());
2167 EXPECT_EQ(Seconds(9).FloorToMultiple(interval), TimeDelta());
2168 EXPECT_EQ(Seconds(10).FloorToMultiple(interval), TimeDelta());
2169 EXPECT_EQ(Seconds(15).FloorToMultiple(interval), TimeDelta());
2170 EXPECT_EQ(Seconds(20).FloorToMultiple(interval), TimeDelta());
2171 EXPECT_EQ(TimeDelta::Max().FloorToMultiple(interval), TimeDelta::Max());
2172 EXPECT_EQ(Seconds(-1).FloorToMultiple(interval), TimeDelta::Min());
2173 EXPECT_EQ(Seconds(-9).FloorToMultiple(interval), TimeDelta::Min());
2174 EXPECT_EQ(Seconds(-10).FloorToMultiple(interval), TimeDelta::Min());
2175 EXPECT_EQ(Seconds(-15).FloorToMultiple(interval), TimeDelta::Min());
2176 EXPECT_EQ(Seconds(-20).FloorToMultiple(interval), TimeDelta::Min());
2177 EXPECT_EQ(TimeDelta::Min().FloorToMultiple(interval), TimeDelta::Min());
2178 }
2179 }
2180
TEST(TimeDelta,RoundToMultiple)2181 TEST(TimeDelta, RoundToMultiple) {
2182 for (const auto interval : {Seconds(10), Seconds(-10)}) {
2183 SCOPED_TRACE(interval);
2184 EXPECT_EQ(TimeDelta().RoundToMultiple(interval), TimeDelta());
2185 EXPECT_EQ(Seconds(1).RoundToMultiple(interval), TimeDelta());
2186 EXPECT_EQ(Seconds(9).RoundToMultiple(interval), Seconds(10));
2187 EXPECT_EQ(Seconds(10).RoundToMultiple(interval), Seconds(10));
2188 EXPECT_EQ(Seconds(15).RoundToMultiple(interval), Seconds(20));
2189 EXPECT_EQ(Seconds(20).RoundToMultiple(interval), Seconds(20));
2190 EXPECT_EQ(TimeDelta::Max().RoundToMultiple(interval), TimeDelta::Max());
2191 EXPECT_EQ(Seconds(-1).RoundToMultiple(interval), TimeDelta());
2192 EXPECT_EQ(Seconds(-9).RoundToMultiple(interval), Seconds(-10));
2193 EXPECT_EQ(Seconds(-10).RoundToMultiple(interval), Seconds(-10));
2194 EXPECT_EQ(Seconds(-15).RoundToMultiple(interval), Seconds(-20));
2195 EXPECT_EQ(Seconds(-20).RoundToMultiple(interval), Seconds(-20));
2196 EXPECT_EQ(TimeDelta::Min().RoundToMultiple(interval), TimeDelta::Min());
2197 }
2198
2199 for (const auto interval : {TimeDelta::Max(), TimeDelta::Min()}) {
2200 SCOPED_TRACE(interval);
2201 EXPECT_EQ(TimeDelta().RoundToMultiple(interval), TimeDelta());
2202 EXPECT_EQ(Seconds(1).RoundToMultiple(interval), TimeDelta());
2203 EXPECT_EQ(Seconds(9).RoundToMultiple(interval), TimeDelta());
2204 EXPECT_EQ(Seconds(10).RoundToMultiple(interval), TimeDelta());
2205 EXPECT_EQ(Seconds(15).RoundToMultiple(interval), TimeDelta());
2206 EXPECT_EQ(Seconds(20).RoundToMultiple(interval), TimeDelta());
2207 EXPECT_EQ(TimeDelta::Max().RoundToMultiple(interval), TimeDelta::Max());
2208 EXPECT_EQ(Seconds(-1).RoundToMultiple(interval), TimeDelta());
2209 EXPECT_EQ(Seconds(-9).RoundToMultiple(interval), TimeDelta());
2210 EXPECT_EQ(Seconds(-10).RoundToMultiple(interval), TimeDelta());
2211 EXPECT_EQ(Seconds(-15).RoundToMultiple(interval), TimeDelta());
2212 EXPECT_EQ(Seconds(-20).RoundToMultiple(interval), TimeDelta());
2213 EXPECT_EQ(TimeDelta::Min().RoundToMultiple(interval), TimeDelta::Min());
2214 }
2215 }
2216
TEST(TimeBase,AddSubDeltaSaturates)2217 TEST(TimeBase, AddSubDeltaSaturates) {
2218 constexpr TimeTicks kLargeTimeTicks =
2219 TimeTicks::FromInternalValue(std::numeric_limits<int64_t>::max() - 1);
2220
2221 constexpr TimeTicks kLargeNegativeTimeTicks =
2222 TimeTicks::FromInternalValue(std::numeric_limits<int64_t>::min() + 1);
2223
2224 static_assert((kLargeTimeTicks + TimeDelta::Max()).is_max());
2225 static_assert((kLargeNegativeTimeTicks + TimeDelta::Max()).is_max());
2226 static_assert((kLargeTimeTicks - TimeDelta::Max()).is_min());
2227 static_assert((kLargeNegativeTimeTicks - TimeDelta::Max()).is_min());
2228 static_assert((TimeTicks() + TimeDelta::Max()).is_max());
2229 static_assert((TimeTicks() - TimeDelta::Max()).is_min());
2230 EXPECT_TRUE((TimeTicks::Now() + TimeDelta::Max()).is_max())
2231 << (TimeTicks::Now() + TimeDelta::Max());
2232 EXPECT_TRUE((TimeTicks::Now() - TimeDelta::Max()).is_min())
2233 << (TimeTicks::Now() - TimeDelta::Max());
2234
2235 static_assert((kLargeTimeTicks + TimeDelta::Min()).is_min());
2236 static_assert((kLargeNegativeTimeTicks + TimeDelta::Min()).is_min());
2237 static_assert((kLargeTimeTicks - TimeDelta::Min()).is_max());
2238 static_assert((kLargeNegativeTimeTicks - TimeDelta::Min()).is_max());
2239 static_assert((TimeTicks() + TimeDelta::Min()).is_min());
2240 static_assert((TimeTicks() - TimeDelta::Min()).is_max());
2241 EXPECT_TRUE((TimeTicks::Now() + TimeDelta::Min()).is_min())
2242 << (TimeTicks::Now() + TimeDelta::Min());
2243 EXPECT_TRUE((TimeTicks::Now() - TimeDelta::Min()).is_max())
2244 << (TimeTicks::Now() - TimeDelta::Min());
2245 }
2246
TEST(TimeBase,AddSubInfinities)2247 TEST(TimeBase, AddSubInfinities) {
2248 // CHECK when adding opposite signs or subtracting same sign.
2249 EXPECT_CHECK_DEATH({ TimeTicks::Min() + TimeDelta::Max(); });
2250 EXPECT_CHECK_DEATH({ TimeTicks::Max() + TimeDelta::Min(); });
2251 EXPECT_CHECK_DEATH({ TimeTicks::Min() - TimeDelta::Min(); });
2252 EXPECT_CHECK_DEATH({ TimeTicks::Max() - TimeDelta::Max(); });
2253
2254 // Saturates when adding same sign or subtracting opposite signs.
2255 static_assert((TimeTicks::Max() + TimeDelta::Max()).is_max());
2256 static_assert((TimeTicks::Min() + TimeDelta::Min()).is_min());
2257 static_assert((TimeTicks::Max() - TimeDelta::Min()).is_max());
2258 static_assert((TimeTicks::Min() - TimeDelta::Max()).is_min());
2259 }
2260
TestTimeTicksConstexprCopyAssignment()2261 constexpr TimeTicks TestTimeTicksConstexprCopyAssignment() {
2262 TimeTicks a = TimeTicks::FromInternalValue(12345);
2263 TimeTicks b;
2264 b = a;
2265 return b;
2266 }
2267
TEST(TimeTicks,ConstexprAndTriviallyCopiable)2268 TEST(TimeTicks, ConstexprAndTriviallyCopiable) {
2269 // "Trivially copyable" is necessary for use in std::atomic<TimeTicks>.
2270 static_assert(std::is_trivially_copyable<TimeTicks>());
2271
2272 // Copy ctor.
2273 constexpr TimeTicks a = TimeTicks::FromInternalValue(12345);
2274 constexpr TimeTicks b{a};
2275 static_assert(a.ToInternalValue() == b.ToInternalValue());
2276
2277 // Copy assignment.
2278 static_assert(a.ToInternalValue() ==
2279 TestTimeTicksConstexprCopyAssignment().ToInternalValue(),
2280 "");
2281 }
2282
TestThreadTicksConstexprCopyAssignment()2283 constexpr ThreadTicks TestThreadTicksConstexprCopyAssignment() {
2284 ThreadTicks a = ThreadTicks::FromInternalValue(12345);
2285 ThreadTicks b;
2286 b = a;
2287 return b;
2288 }
2289
TEST(ThreadTicks,ConstexprAndTriviallyCopiable)2290 TEST(ThreadTicks, ConstexprAndTriviallyCopiable) {
2291 // "Trivially copyable" is necessary for use in std::atomic<ThreadTicks>.
2292 static_assert(std::is_trivially_copyable<ThreadTicks>());
2293
2294 // Copy ctor.
2295 constexpr ThreadTicks a = ThreadTicks::FromInternalValue(12345);
2296 constexpr ThreadTicks b{a};
2297 static_assert(a.ToInternalValue() == b.ToInternalValue());
2298
2299 // Copy assignment.
2300 static_assert(a.ToInternalValue() ==
2301 TestThreadTicksConstexprCopyAssignment().ToInternalValue(),
2302 "");
2303 }
2304
TestTimeDeltaConstexprCopyAssignment()2305 constexpr TimeDelta TestTimeDeltaConstexprCopyAssignment() {
2306 TimeDelta a = Seconds(1);
2307 TimeDelta b;
2308 b = a;
2309 return b;
2310 }
2311
TEST(TimeDelta,ConstexprAndTriviallyCopiable)2312 TEST(TimeDelta, ConstexprAndTriviallyCopiable) {
2313 // "Trivially copyable" is necessary for use in std::atomic<TimeDelta>.
2314 static_assert(std::is_trivially_copyable<TimeDelta>());
2315
2316 // Copy ctor.
2317 constexpr TimeDelta a = Seconds(1);
2318 constexpr TimeDelta b{a};
2319 static_assert(a == b);
2320
2321 // Copy assignment.
2322 static_assert(a == TestTimeDeltaConstexprCopyAssignment());
2323 }
2324
TEST(TimeDeltaLogging,DCheckEqCompiles)2325 TEST(TimeDeltaLogging, DCheckEqCompiles) {
2326 DCHECK_EQ(TimeDelta(), TimeDelta());
2327 }
2328
TEST(TimeDeltaLogging,EmptyIsZero)2329 TEST(TimeDeltaLogging, EmptyIsZero) {
2330 constexpr TimeDelta kZero;
2331 EXPECT_EQ("0 s", AnyToString(kZero));
2332 }
2333
TEST(TimeDeltaLogging,FiveHundredMs)2334 TEST(TimeDeltaLogging, FiveHundredMs) {
2335 constexpr TimeDelta kFiveHundredMs = Milliseconds(500);
2336 EXPECT_EQ("0.5 s", AnyToString(kFiveHundredMs));
2337 }
2338
TEST(TimeDeltaLogging,MinusTenSeconds)2339 TEST(TimeDeltaLogging, MinusTenSeconds) {
2340 constexpr TimeDelta kMinusTenSeconds = Seconds(-10);
2341 EXPECT_EQ("-10 s", AnyToString(kMinusTenSeconds));
2342 }
2343
TEST(TimeDeltaLogging,DoesNotMessUpFormattingFlags)2344 TEST(TimeDeltaLogging, DoesNotMessUpFormattingFlags) {
2345 std::ostringstream oss;
2346 std::ios_base::fmtflags flags_before = oss.flags();
2347 oss << TimeDelta();
2348 EXPECT_EQ(flags_before, oss.flags());
2349 }
2350
TEST(TimeDeltaLogging,DoesNotMakeStreamBad)2351 TEST(TimeDeltaLogging, DoesNotMakeStreamBad) {
2352 std::ostringstream oss;
2353 oss << TimeDelta();
2354 EXPECT_TRUE(oss.good());
2355 }
2356
TEST(TimeLogging,DCheckEqCompiles)2357 TEST(TimeLogging, DCheckEqCompiles) {
2358 DCHECK_EQ(Time(), Time());
2359 }
2360
TEST(TimeLogging,ChromeBirthdate)2361 TEST(TimeLogging, ChromeBirthdate) {
2362 Time birthdate;
2363 ASSERT_TRUE(Time::FromString("Tue, 02 Sep 2008 09:42:18 GMT", &birthdate));
2364 EXPECT_EQ("2008-09-02 09:42:18.000 UTC", AnyToString(birthdate));
2365 }
2366
TEST(TimeLogging,DoesNotMessUpFormattingFlags)2367 TEST(TimeLogging, DoesNotMessUpFormattingFlags) {
2368 std::ostringstream oss;
2369 std::ios_base::fmtflags flags_before = oss.flags();
2370 oss << Time();
2371 EXPECT_EQ(flags_before, oss.flags());
2372 }
2373
TEST(TimeLogging,DoesNotMakeStreamBad)2374 TEST(TimeLogging, DoesNotMakeStreamBad) {
2375 std::ostringstream oss;
2376 oss << Time();
2377 EXPECT_TRUE(oss.good());
2378 }
2379
TEST(TimeTicksLogging,DCheckEqCompiles)2380 TEST(TimeTicksLogging, DCheckEqCompiles) {
2381 DCHECK_EQ(TimeTicks(), TimeTicks());
2382 }
2383
TEST(TimeTicksLogging,ZeroTime)2384 TEST(TimeTicksLogging, ZeroTime) {
2385 TimeTicks zero;
2386 EXPECT_EQ("0 bogo-microseconds", AnyToString(zero));
2387 }
2388
TEST(TimeTicksLogging,FortyYearsLater)2389 TEST(TimeTicksLogging, FortyYearsLater) {
2390 TimeTicks forty_years_later = TimeTicks() + Days(365.25 * 40);
2391 EXPECT_EQ("1262304000000000 bogo-microseconds",
2392 AnyToString(forty_years_later));
2393 }
2394
TEST(TimeTicksLogging,DoesNotMessUpFormattingFlags)2395 TEST(TimeTicksLogging, DoesNotMessUpFormattingFlags) {
2396 std::ostringstream oss;
2397 std::ios_base::fmtflags flags_before = oss.flags();
2398 oss << TimeTicks();
2399 EXPECT_EQ(flags_before, oss.flags());
2400 }
2401
TEST(TimeTicksLogging,DoesNotMakeStreamBad)2402 TEST(TimeTicksLogging, DoesNotMakeStreamBad) {
2403 std::ostringstream oss;
2404 oss << TimeTicks();
2405 EXPECT_TRUE(oss.good());
2406 }
2407
2408 } // namespace
2409
2410 } // namespace base
2411