| license.bot | f003cfe | 2008-08-24 09:55:55 +0900 | [diff] [blame] | 1 | // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 
|  | 2 | // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 | // found in the LICENSE file. | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 4 |  | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 5 | #include <time.h> | 
|  | 6 |  | 
| pinkerton@google.com | 75d7402 | 2008-08-14 07:55:45 +0900 | [diff] [blame] | 7 | #include "base/platform_thread.h" | 
| deanm@google.com | 69dced8 | 2008-09-02 17:28:37 +0900 | [diff] [blame] | 8 | #include "base/time.h" | 
|  | 9 | #include "build/build_config.h" | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 10 | #include "testing/gtest/include/gtest/gtest.h" | 
|  | 11 |  | 
| dsh@google.com | 0f8dd26 | 2008-10-28 05:43:33 +0900 | [diff] [blame] | 12 | using base::Time; | 
|  | 13 | using base::TimeDelta; | 
|  | 14 | using base::TimeTicks; | 
|  | 15 |  | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 16 | // Test conversions to/from time_t and exploding/unexploding. | 
|  | 17 | TEST(Time, TimeT) { | 
|  | 18 | // C library time and exploded time. | 
|  | 19 | time_t now_t_1 = time(NULL); | 
|  | 20 | struct tm tms; | 
| pinkerton@google.com | 75d7402 | 2008-08-14 07:55:45 +0900 | [diff] [blame] | 21 | #if defined(OS_WIN) | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 22 | localtime_s(&tms, &now_t_1); | 
| pinkerton@google.com | 75d7402 | 2008-08-14 07:55:45 +0900 | [diff] [blame] | 23 | #elif defined(OS_POSIX) | 
|  | 24 | localtime_r(&now_t_1, &tms); | 
|  | 25 | #endif | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 26 |  | 
|  | 27 | // Convert to ours. | 
|  | 28 | Time our_time_1 = Time::FromTimeT(now_t_1); | 
|  | 29 | Time::Exploded exploded; | 
|  | 30 | our_time_1.LocalExplode(&exploded); | 
|  | 31 |  | 
|  | 32 | // This will test both our exploding and our time_t -> Time conversion. | 
|  | 33 | EXPECT_EQ(tms.tm_year + 1900, exploded.year); | 
|  | 34 | EXPECT_EQ(tms.tm_mon + 1, exploded.month); | 
|  | 35 | EXPECT_EQ(tms.tm_mday, exploded.day_of_month); | 
|  | 36 | EXPECT_EQ(tms.tm_hour, exploded.hour); | 
|  | 37 | EXPECT_EQ(tms.tm_min, exploded.minute); | 
|  | 38 | EXPECT_EQ(tms.tm_sec, exploded.second); | 
|  | 39 |  | 
|  | 40 | // Convert exploded back to the time struct. | 
|  | 41 | Time our_time_2 = Time::FromLocalExploded(exploded); | 
|  | 42 | EXPECT_TRUE(our_time_1 == our_time_2); | 
|  | 43 |  | 
|  | 44 | time_t now_t_2 = our_time_2.ToTimeT(); | 
|  | 45 | EXPECT_EQ(now_t_1, now_t_2); | 
|  | 46 |  | 
| deanm@google.com | 0278122 | 2008-08-19 18:16:49 +0900 | [diff] [blame] | 47 | EXPECT_EQ(10, Time().FromTimeT(10).ToTimeT()); | 
|  | 48 | EXPECT_EQ(10.0, Time().FromTimeT(10).ToDoubleT()); | 
|  | 49 |  | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 50 | // Conversions of 0 should stay 0. | 
|  | 51 | EXPECT_EQ(0, Time().ToTimeT()); | 
|  | 52 | EXPECT_EQ(0, Time::FromTimeT(0).ToInternalValue()); | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | TEST(Time, ZeroIsSymmetric) { | 
| deanm@google.com | 0278122 | 2008-08-19 18:16:49 +0900 | [diff] [blame] | 56 | Time zero_time(Time::FromTimeT(0)); | 
|  | 57 | EXPECT_EQ(0, zero_time.ToTimeT()); | 
|  | 58 |  | 
|  | 59 | EXPECT_EQ(0.0, zero_time.ToDoubleT()); | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 60 | } | 
|  | 61 |  | 
|  | 62 | TEST(Time, LocalExplode) { | 
|  | 63 | Time a = Time::Now(); | 
|  | 64 | Time::Exploded exploded; | 
|  | 65 | a.LocalExplode(&exploded); | 
|  | 66 |  | 
|  | 67 | Time b = Time::FromLocalExploded(exploded); | 
|  | 68 |  | 
| brettw@chromium.org | d2f9782 | 2009-08-26 11:53:36 +0900 | [diff] [blame] | 69 | // The exploded structure doesn't have microseconds, and on Mac & Linux, the | 
|  | 70 | // internal OS conversion uses seconds, which will cause truncation. So we | 
|  | 71 | // can only make sure that the delta is within one second. | 
|  | 72 | EXPECT_TRUE((a - b) < TimeDelta::FromSeconds(1)); | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 73 | } | 
|  | 74 |  | 
|  | 75 | TEST(Time, UTCExplode) { | 
|  | 76 | Time a = Time::Now(); | 
|  | 77 | Time::Exploded exploded; | 
|  | 78 | a.UTCExplode(&exploded); | 
|  | 79 |  | 
|  | 80 | Time b = Time::FromUTCExploded(exploded); | 
| brettw@chromium.org | d2f9782 | 2009-08-26 11:53:36 +0900 | [diff] [blame] | 81 | EXPECT_TRUE((a - b) < TimeDelta::FromSeconds(1)); | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 82 | } | 
|  | 83 |  | 
| deanm@google.com | 0278122 | 2008-08-19 18:16:49 +0900 | [diff] [blame] | 84 | TEST(Time, LocalMidnight) { | 
|  | 85 | Time::Exploded exploded; | 
|  | 86 | Time::Now().LocalMidnight().LocalExplode(&exploded); | 
|  | 87 | EXPECT_EQ(0, exploded.hour); | 
|  | 88 | EXPECT_EQ(0, exploded.minute); | 
|  | 89 | EXPECT_EQ(0, exploded.second); | 
|  | 90 | EXPECT_EQ(0, exploded.millisecond); | 
|  | 91 | } | 
|  | 92 |  | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 93 | TEST(TimeTicks, Deltas) { | 
| mbelshe@google.com | 556bc84 | 2008-09-26 12:00:00 +0900 | [diff] [blame] | 94 | for (int index = 0; index < 500; index++) { | 
|  | 95 | TimeTicks ticks_start = TimeTicks::Now(); | 
|  | 96 | PlatformThread::Sleep(10); | 
|  | 97 | TimeTicks ticks_stop = TimeTicks::Now(); | 
|  | 98 | TimeDelta delta = ticks_stop - ticks_start; | 
|  | 99 | // Note:  Although we asked for a 10ms sleep, if the | 
|  | 100 | // time clock has a finer granularity than the Sleep() | 
|  | 101 | // clock, it is quite possible to wakeup early.  Here | 
|  | 102 | // is how that works: | 
|  | 103 | //      Time(ms timer)      Time(us timer) | 
|  | 104 | //          5                   5010 | 
|  | 105 | //          6                   6010 | 
|  | 106 | //          7                   7010 | 
|  | 107 | //          8                   8010 | 
|  | 108 | //          9                   9000 | 
|  | 109 | // Elapsed  4ms                 3990us | 
|  | 110 | // | 
|  | 111 | // Unfortunately, our InMilliseconds() function truncates | 
|  | 112 | // rather than rounds.  We should consider fixing this | 
|  | 113 | // so that our averages come out better. | 
|  | 114 | EXPECT_GE(delta.InMilliseconds(), 9); | 
|  | 115 | EXPECT_GE(delta.InMicroseconds(), 9000); | 
|  | 116 | EXPECT_EQ(delta.InSeconds(), 0); | 
|  | 117 | } | 
| initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 118 | } | 
|  | 119 |  | 
| mbelshe@google.com | 556bc84 | 2008-09-26 12:00:00 +0900 | [diff] [blame] | 120 | TEST(TimeTicks, HighResNow) { | 
|  | 121 | TimeTicks ticks_start = TimeTicks::HighResNow(); | 
| deanm@google.com | d6c2dee | 2008-09-04 03:18:32 +0900 | [diff] [blame] | 122 | PlatformThread::Sleep(10); | 
| mbelshe@google.com | 556bc84 | 2008-09-26 12:00:00 +0900 | [diff] [blame] | 123 | TimeTicks ticks_stop = TimeTicks::HighResNow(); | 
| deanm@google.com | d6c2dee | 2008-09-04 03:18:32 +0900 | [diff] [blame] | 124 | TimeDelta delta = ticks_stop - ticks_start; | 
| mbelshe@google.com | 556bc84 | 2008-09-26 12:00:00 +0900 | [diff] [blame] | 125 | EXPECT_GE(delta.InMicroseconds(), 9000); | 
| deanm@google.com | d6c2dee | 2008-09-04 03:18:32 +0900 | [diff] [blame] | 126 | } | 
|  | 127 |  | 
| deanm@google.com | 0278122 | 2008-08-19 18:16:49 +0900 | [diff] [blame] | 128 | TEST(TimeDelta, FromAndIn) { | 
|  | 129 | EXPECT_TRUE(TimeDelta::FromDays(2) == TimeDelta::FromHours(48)); | 
|  | 130 | EXPECT_TRUE(TimeDelta::FromHours(3) == TimeDelta::FromMinutes(180)); | 
|  | 131 | EXPECT_TRUE(TimeDelta::FromMinutes(2) == TimeDelta::FromSeconds(120)); | 
|  | 132 | EXPECT_TRUE(TimeDelta::FromSeconds(2) == TimeDelta::FromMilliseconds(2000)); | 
|  | 133 | EXPECT_TRUE(TimeDelta::FromMilliseconds(2) == | 
|  | 134 | TimeDelta::FromMicroseconds(2000)); | 
|  | 135 | EXPECT_EQ(13, TimeDelta::FromDays(13).InDays()); | 
|  | 136 | EXPECT_EQ(13, TimeDelta::FromHours(13).InHours()); | 
|  | 137 | EXPECT_EQ(13, TimeDelta::FromMinutes(13).InMinutes()); | 
|  | 138 | EXPECT_EQ(13, TimeDelta::FromSeconds(13).InSeconds()); | 
|  | 139 | EXPECT_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF()); | 
|  | 140 | EXPECT_EQ(13, TimeDelta::FromMilliseconds(13).InMilliseconds()); | 
|  | 141 | EXPECT_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF()); | 
|  | 142 | EXPECT_EQ(13, TimeDelta::FromMicroseconds(13).InMicroseconds()); | 
|  | 143 | } | 
| brettw@chromium.org | d2f9782 | 2009-08-26 11:53:36 +0900 | [diff] [blame] | 144 |  | 
|  | 145 | // Our internal time format is serialized in things like databases, so it's | 
|  | 146 | // important that it's consistent across all our platforms.  We use the 1601 | 
|  | 147 | // Windows epoch as the internal format across all platforms. | 
|  | 148 | TEST(TimeDelta, WindowsEpoch) { | 
|  | 149 | Time::Exploded exploded; | 
|  | 150 | exploded.year = 1970; | 
|  | 151 | exploded.month = 1; | 
|  | 152 | exploded.day_of_week = 0;  // Should be unusued. | 
|  | 153 | exploded.day_of_month = 1; | 
|  | 154 | exploded.hour = 0; | 
|  | 155 | exploded.minute = 0; | 
|  | 156 | exploded.second = 0; | 
|  | 157 | exploded.millisecond = 0; | 
|  | 158 | Time t = Time::FromUTCExploded(exploded); | 
|  | 159 | // Unix 1970 epoch. | 
|  | 160 | EXPECT_EQ(GG_INT64_C(11644473600000000), t.ToInternalValue()); | 
|  | 161 |  | 
|  | 162 | // We can't test 1601 epoch, since the system time functions on Linux | 
|  | 163 | // only compute years starting from 1900. | 
|  | 164 | } |