Home | History | Annotate | Download | only in base
      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.
      4 
      5 #include <time.h>
      6 
      7 #include "base/platform_thread.h"
      8 #include "base/time.h"
      9 #include "build/build_config.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 using base::Time;
     13 using base::TimeDelta;
     14 using base::TimeTicks;
     15 
     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;
     21 #if defined(OS_WIN)
     22   localtime_s(&tms, &now_t_1);
     23 #elif defined(OS_POSIX)
     24   localtime_r(&now_t_1, &tms);
     25 #endif
     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 
     47   EXPECT_EQ(10, Time().FromTimeT(10).ToTimeT());
     48   EXPECT_EQ(10.0, Time().FromTimeT(10).ToDoubleT());
     49 
     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) {
     56   Time zero_time(Time::FromTimeT(0));
     57   EXPECT_EQ(0, zero_time.ToTimeT());
     58 
     59   EXPECT_EQ(0.0, zero_time.ToDoubleT());
     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 
     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));
     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);
     81   EXPECT_TRUE((a - b) < TimeDelta::FromSeconds(1));
     82 }
     83 
     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 
     93 TEST(TimeTicks, Deltas) {
     94   for (int index = 0; index < 50; 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   }
    118 }
    119 
    120 TEST(TimeTicks, HighResNow) {
    121   TimeTicks ticks_start = TimeTicks::HighResNow();
    122   PlatformThread::Sleep(10);
    123   TimeTicks ticks_stop = TimeTicks::HighResNow();
    124   TimeDelta delta = ticks_stop - ticks_start;
    125   EXPECT_GE(delta.InMicroseconds(), 9000);
    126 }
    127 
    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 }
    144 
    145 #if defined(OS_POSIX)
    146 TEST(TimeDelta, TimeSpecConversion) {
    147   struct timespec result = TimeDelta::FromSeconds(0).ToTimeSpec();
    148   EXPECT_EQ(result.tv_sec, 0);
    149   EXPECT_EQ(result.tv_nsec, 0);
    150 
    151   result = TimeDelta::FromSeconds(1).ToTimeSpec();
    152   EXPECT_EQ(result.tv_sec, 1);
    153   EXPECT_EQ(result.tv_nsec, 0);
    154 
    155   result = TimeDelta::FromMicroseconds(1).ToTimeSpec();
    156   EXPECT_EQ(result.tv_sec, 0);
    157   EXPECT_EQ(result.tv_nsec, 1000);
    158 
    159   result = TimeDelta::FromMicroseconds(
    160       Time::kMicrosecondsPerSecond + 1).ToTimeSpec();
    161   EXPECT_EQ(result.tv_sec, 1);
    162   EXPECT_EQ(result.tv_nsec, 1000);
    163 }
    164 #endif  // OS_POSIX
    165 
    166 // Our internal time format is serialized in things like databases, so it's
    167 // important that it's consistent across all our platforms.  We use the 1601
    168 // Windows epoch as the internal format across all platforms.
    169 TEST(TimeDelta, WindowsEpoch) {
    170   Time::Exploded exploded;
    171   exploded.year = 1970;
    172   exploded.month = 1;
    173   exploded.day_of_week = 0;  // Should be unusued.
    174   exploded.day_of_month = 1;
    175   exploded.hour = 0;
    176   exploded.minute = 0;
    177   exploded.second = 0;
    178   exploded.millisecond = 0;
    179   Time t = Time::FromUTCExploded(exploded);
    180   // Unix 1970 epoch.
    181   EXPECT_EQ(GG_INT64_C(11644473600000000), t.ToInternalValue());
    182 
    183   // We can't test 1601 epoch, since the system time functions on Linux
    184   // only compute years starting from 1900.
    185 }
    186