Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2009 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 // Time represents an absolute point in time, internally represented as
      6 // microseconds (s/1,000,000) since a platform-dependent epoch.  Each
      7 // platform's epoch, along with other system-dependent clock interface
      8 // routines, is defined in time_PLATFORM.cc.
      9 //
     10 // TimeDelta represents a duration of time, internally represented in
     11 // microseconds.
     12 //
     13 // TimeTicks represents an abstract time that is always incrementing for use
     14 // in measuring time durations. It is internally represented in microseconds.
     15 // It can not be converted to a human-readable time, but is guaranteed not to
     16 // decrease (if the user changes the computer clock, Time::Now() may actually
     17 // decrease or jump).
     18 //
     19 // These classes are represented as only a 64-bit value, so they can be
     20 // efficiently passed by value.
     21 
     22 #ifndef BASE_TIME_H_
     23 #define BASE_TIME_H_
     24 
     25 #include <time.h>
     26 
     27 #include "base/basictypes.h"
     28 
     29 #if defined(OS_WIN)
     30 // For FILETIME in FromFileTime, until it moves to a new converter class.
     31 // See TODO(iyengar) below.
     32 #include <windows.h>
     33 #endif
     34 
     35 namespace base {
     36 
     37 class Time;
     38 class TimeTicks;
     39 
     40 // This unit test does a lot of manual time manipulation.
     41 class PageLoadTrackerUnitTest;
     42 
     43 // TimeDelta ------------------------------------------------------------------
     44 
     45 class TimeDelta {
     46  public:
     47   TimeDelta() : delta_(0) {
     48   }
     49 
     50   // Converts units of time to TimeDeltas.
     51   static TimeDelta FromDays(int64 days);
     52   static TimeDelta FromHours(int64 hours);
     53   static TimeDelta FromMinutes(int64 minutes);
     54   static TimeDelta FromSeconds(int64 secs);
     55   static TimeDelta FromMilliseconds(int64 ms);
     56   static TimeDelta FromMicroseconds(int64 us);
     57 
     58   // Returns the internal numeric value of the TimeDelta object. Please don't
     59   // use this and do arithmetic on it, as it is more error prone than using the
     60   // provided operators.
     61   int64 ToInternalValue() const {
     62     return delta_;
     63   }
     64 
     65 #if defined(OS_POSIX)
     66   struct timespec ToTimeSpec() const;
     67 #endif
     68 
     69   // Returns the time delta in some unit. The F versions return a floating
     70   // point value, the "regular" versions return a rounded-down value.
     71   //
     72   // InMillisecondsRoundedUp() instead returns an integer that is rounded up
     73   // to the next full millisecond.
     74   int InDays() const;
     75   int InHours() const;
     76   int InMinutes() const;
     77   double InSecondsF() const;
     78   int64 InSeconds() const;
     79   double InMillisecondsF() const;
     80   int64 InMilliseconds() const;
     81   int64 InMillisecondsRoundedUp() const;
     82   int64 InMicroseconds() const;
     83 
     84   TimeDelta& operator=(TimeDelta other) {
     85     delta_ = other.delta_;
     86     return *this;
     87   }
     88 
     89   // Computations with other deltas.
     90   TimeDelta operator+(TimeDelta other) const {
     91     return TimeDelta(delta_ + other.delta_);
     92   }
     93   TimeDelta operator-(TimeDelta other) const {
     94     return TimeDelta(delta_ - other.delta_);
     95   }
     96 
     97   TimeDelta& operator+=(TimeDelta other) {
     98     delta_ += other.delta_;
     99     return *this;
    100   }
    101   TimeDelta& operator-=(TimeDelta other) {
    102     delta_ -= other.delta_;
    103     return *this;
    104   }
    105   TimeDelta operator-() const {
    106     return TimeDelta(-delta_);
    107   }
    108 
    109   // Computations with ints, note that we only allow multiplicative operations
    110   // with ints, and additive operations with other deltas.
    111   TimeDelta operator*(int64 a) const {
    112     return TimeDelta(delta_ * a);
    113   }
    114   TimeDelta operator/(int64 a) const {
    115     return TimeDelta(delta_ / a);
    116   }
    117   TimeDelta& operator*=(int64 a) {
    118     delta_ *= a;
    119     return *this;
    120   }
    121   TimeDelta& operator/=(int64 a) {
    122     delta_ /= a;
    123     return *this;
    124   }
    125   int64 operator/(TimeDelta a) const {
    126     return delta_ / a.delta_;
    127   }
    128 
    129   // Defined below because it depends on the definition of the other classes.
    130   Time operator+(Time t) const;
    131   TimeTicks operator+(TimeTicks t) const;
    132 
    133   // Comparison operators.
    134   bool operator==(TimeDelta other) const {
    135     return delta_ == other.delta_;
    136   }
    137   bool operator!=(TimeDelta other) const {
    138     return delta_ != other.delta_;
    139   }
    140   bool operator<(TimeDelta other) const {
    141     return delta_ < other.delta_;
    142   }
    143   bool operator<=(TimeDelta other) const {
    144     return delta_ <= other.delta_;
    145   }
    146   bool operator>(TimeDelta other) const {
    147     return delta_ > other.delta_;
    148   }
    149   bool operator>=(TimeDelta other) const {
    150     return delta_ >= other.delta_;
    151   }
    152 
    153  private:
    154   friend class Time;
    155   friend class TimeTicks;
    156   friend TimeDelta operator*(int64 a, TimeDelta td);
    157 
    158   // Constructs a delta given the duration in microseconds. This is private
    159   // to avoid confusion by callers with an integer constructor. Use
    160   // FromSeconds, FromMilliseconds, etc. instead.
    161   explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
    162   }
    163 
    164   // Delta in microseconds.
    165   int64 delta_;
    166 };
    167 
    168 inline TimeDelta operator*(int64 a, TimeDelta td) {
    169   return TimeDelta(a * td.delta_);
    170 }
    171 
    172 // Time -----------------------------------------------------------------------
    173 
    174 // Represents a wall clock time.
    175 class Time {
    176  public:
    177   static const int64 kMillisecondsPerSecond = 1000;
    178   static const int64 kMicrosecondsPerMillisecond = 1000;
    179   static const int64 kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
    180                                               kMillisecondsPerSecond;
    181   static const int64 kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
    182   static const int64 kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
    183   static const int64 kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
    184   static const int64 kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
    185   static const int64 kNanosecondsPerMicrosecond = 1000;
    186   static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
    187                                              kMicrosecondsPerSecond;
    188 
    189 #if !defined(OS_WIN)
    190   // On Mac & Linux, this value is the delta from the Windows epoch of 1601 to
    191   // the Posix delta of 1970. This is used for migrating between the old
    192   // 1970-based epochs to the new 1601-based ones. It should be removed from
    193   // this global header and put in the platform-specific ones when we remove the
    194   // migration code.
    195   static const int64 kWindowsEpochDeltaMicroseconds;
    196 #endif
    197 
    198   // Represents an exploded time that can be formatted nicely. This is kind of
    199   // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
    200   // additions and changes to prevent errors.
    201   struct Exploded {
    202     int year;          // Four digit year "2007"
    203     int month;         // 1-based month (values 1 = January, etc.)
    204     int day_of_week;   // 0-based day of week (0 = Sunday, etc.)
    205     int day_of_month;  // 1-based day of month (1-31)
    206     int hour;          // Hour within the current day (0-23)
    207     int minute;        // Minute within the current hour (0-59)
    208     int second;        // Second within the current minute (0-59 plus leap
    209                        //   seconds which may take it up to 60).
    210     int millisecond;   // Milliseconds within the current second (0-999)
    211   };
    212 
    213   // Contains the NULL time. Use Time::Now() to get the current time.
    214   explicit Time() : us_(0) {
    215   }
    216 
    217   // Returns true if the time object has not been initialized.
    218   bool is_null() const {
    219     return us_ == 0;
    220   }
    221 
    222   // Returns the current time. Watch out, the system might adjust its clock
    223   // in which case time will actually go backwards. We don't guarantee that
    224   // times are increasing, or that two calls to Now() won't be the same.
    225   static Time Now();
    226 
    227   // Returns the current time. Same as Now() except that this function always
    228   // uses system time so that there are no discrepancies between the returned
    229   // time and system time even on virtual environments including our test bot.
    230   // For timing sensitive unittests, this function should be used.
    231   static Time NowFromSystemTime();
    232 
    233   // Converts to/from time_t in UTC and a Time class.
    234   // TODO(brettw) this should be removed once everybody starts using the |Time|
    235   // class.
    236   static Time FromTimeT(time_t tt);
    237   time_t ToTimeT() const;
    238 
    239   // Converts time to/from a double which is the number of seconds since epoch
    240   // (Jan 1, 1970).  Webkit uses this format to represent time.
    241   static Time FromDoubleT(double dt);
    242   double ToDoubleT() const;
    243 
    244 
    245 #if defined(OS_WIN)
    246   static Time FromFileTime(FILETIME ft);
    247   FILETIME ToFileTime() const;
    248 
    249   // Enable or disable Windows high resolution timer. For more details
    250   // see comments in time_win.cc. Returns true on success.
    251   static bool UseHighResolutionTimer(bool use);
    252 #endif
    253 
    254   // Converts an exploded structure representing either the local time or UTC
    255   // into a Time class.
    256   static Time FromUTCExploded(const Exploded& exploded) {
    257     return FromExploded(false, exploded);
    258   }
    259   static Time FromLocalExploded(const Exploded& exploded) {
    260     return FromExploded(true, exploded);
    261   }
    262 
    263   // Converts an integer value representing Time to a class. This is used
    264   // when deserializing a |Time| structure, using a value known to be
    265   // compatible. It is not provided as a constructor because the integer type
    266   // may be unclear from the perspective of a caller.
    267   static Time FromInternalValue(int64 us) {
    268     return Time(us);
    269   }
    270 
    271   // Converts a string representation of time to a Time object.
    272   // An example of a time string which is converted is as below:-
    273   // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
    274   // in the input string, we assume local time.
    275   // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to
    276   // a new time converter class.
    277   static bool FromString(const wchar_t* time_string, Time* parsed_time);
    278 
    279   // For serializing, use FromInternalValue to reconstitute. Please don't use
    280   // this and do arithmetic on it, as it is more error prone than using the
    281   // provided operators.
    282   int64 ToInternalValue() const {
    283     return us_;
    284   }
    285 
    286   // Fills the given exploded structure with either the local time or UTC from
    287   // this time structure (containing UTC).
    288   void UTCExplode(Exploded* exploded) const {
    289     return Explode(false, exploded);
    290   }
    291   void LocalExplode(Exploded* exploded) const {
    292     return Explode(true, exploded);
    293   }
    294 
    295   // Rounds this time down to the nearest day in local time. It will represent
    296   // midnight on that day.
    297   Time LocalMidnight() const;
    298 
    299   Time& operator=(Time other) {
    300     us_ = other.us_;
    301     return *this;
    302   }
    303 
    304   // Compute the difference between two times.
    305   TimeDelta operator-(Time other) const {
    306     return TimeDelta(us_ - other.us_);
    307   }
    308 
    309   // Modify by some time delta.
    310   Time& operator+=(TimeDelta delta) {
    311     us_ += delta.delta_;
    312     return *this;
    313   }
    314   Time& operator-=(TimeDelta delta) {
    315     us_ -= delta.delta_;
    316     return *this;
    317   }
    318 
    319   // Return a new time modified by some delta.
    320   Time operator+(TimeDelta delta) const {
    321     return Time(us_ + delta.delta_);
    322   }
    323   Time operator-(TimeDelta delta) const {
    324     return Time(us_ - delta.delta_);
    325   }
    326 
    327   // Comparison operators
    328   bool operator==(Time other) const {
    329     return us_ == other.us_;
    330   }
    331   bool operator!=(Time other) const {
    332     return us_ != other.us_;
    333   }
    334   bool operator<(Time other) const {
    335     return us_ < other.us_;
    336   }
    337   bool operator<=(Time other) const {
    338     return us_ <= other.us_;
    339   }
    340   bool operator>(Time other) const {
    341     return us_ > other.us_;
    342   }
    343   bool operator>=(Time other) const {
    344     return us_ >= other.us_;
    345   }
    346 
    347  private:
    348   friend class TimeDelta;
    349 
    350   // Explodes the given time to either local time |is_local = true| or UTC
    351   // |is_local = false|.
    352   void Explode(bool is_local, Exploded* exploded) const;
    353 
    354   // Unexplodes a given time assuming the source is either local time
    355   // |is_local = true| or UTC |is_local = false|.
    356   static Time FromExploded(bool is_local, const Exploded& exploded);
    357 
    358   explicit Time(int64 us) : us_(us) {
    359   }
    360 
    361   // The representation of Jan 1, 1970 UTC in microseconds since the
    362   // platform-dependent epoch.
    363   static const int64 kTimeTToMicrosecondsOffset;
    364 
    365   // Time in microseconds in UTC.
    366   int64 us_;
    367 };
    368 
    369 inline Time TimeDelta::operator+(Time t) const {
    370   return Time(t.us_ + delta_);
    371 }
    372 
    373 // Inline the TimeDelta factory methods, for fast TimeDelta construction.
    374 
    375 // static
    376 inline TimeDelta TimeDelta::FromDays(int64 days) {
    377   return TimeDelta(days * Time::kMicrosecondsPerDay);
    378 }
    379 
    380 // static
    381 inline TimeDelta TimeDelta::FromHours(int64 hours) {
    382   return TimeDelta(hours * Time::kMicrosecondsPerHour);
    383 }
    384 
    385 // static
    386 inline TimeDelta TimeDelta::FromMinutes(int64 minutes) {
    387   return TimeDelta(minutes * Time::kMicrosecondsPerMinute);
    388 }
    389 
    390 // static
    391 inline TimeDelta TimeDelta::FromSeconds(int64 secs) {
    392   return TimeDelta(secs * Time::kMicrosecondsPerSecond);
    393 }
    394 
    395 // static
    396 inline TimeDelta TimeDelta::FromMilliseconds(int64 ms) {
    397   return TimeDelta(ms * Time::kMicrosecondsPerMillisecond);
    398 }
    399 
    400 // static
    401 inline TimeDelta TimeDelta::FromMicroseconds(int64 us) {
    402   return TimeDelta(us);
    403 }
    404 
    405 // TimeTicks ------------------------------------------------------------------
    406 
    407 class TimeTicks {
    408  public:
    409   TimeTicks() : ticks_(0) {
    410   }
    411 
    412   // Platform-dependent tick count representing "right now."
    413   // The resolution of this clock is ~1-15ms.  Resolution varies depending
    414   // on hardware/operating system configuration.
    415   static TimeTicks Now();
    416 
    417   // Returns a platform-dependent high-resolution tick count. Implementation
    418   // is hardware dependent and may or may not return sub-millisecond
    419   // resolution.  THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
    420   // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
    421   static TimeTicks HighResNow();
    422 
    423   // Returns true if this object has not been initialized.
    424   bool is_null() const {
    425     return ticks_ == 0;
    426   }
    427 
    428   // Returns the internal numeric value of the TimeTicks object.
    429   int64 ToInternalValue() const {
    430     return ticks_;
    431   }
    432 
    433   TimeTicks& operator=(TimeTicks other) {
    434     ticks_ = other.ticks_;
    435     return *this;
    436   }
    437 
    438   // Compute the difference between two times.
    439   TimeDelta operator-(TimeTicks other) const {
    440     return TimeDelta(ticks_ - other.ticks_);
    441   }
    442 
    443   // Modify by some time delta.
    444   TimeTicks& operator+=(TimeDelta delta) {
    445     ticks_ += delta.delta_;
    446     return *this;
    447   }
    448   TimeTicks& operator-=(TimeDelta delta) {
    449     ticks_ -= delta.delta_;
    450     return *this;
    451   }
    452 
    453   // Return a new TimeTicks modified by some delta.
    454   TimeTicks operator+(TimeDelta delta) const {
    455     return TimeTicks(ticks_ + delta.delta_);
    456   }
    457   TimeTicks operator-(TimeDelta delta) const {
    458     return TimeTicks(ticks_ - delta.delta_);
    459   }
    460 
    461   // Comparison operators
    462   bool operator==(TimeTicks other) const {
    463     return ticks_ == other.ticks_;
    464   }
    465   bool operator!=(TimeTicks other) const {
    466     return ticks_ != other.ticks_;
    467   }
    468   bool operator<(TimeTicks other) const {
    469     return ticks_ < other.ticks_;
    470   }
    471   bool operator<=(TimeTicks other) const {
    472     return ticks_ <= other.ticks_;
    473   }
    474   bool operator>(TimeTicks other) const {
    475     return ticks_ > other.ticks_;
    476   }
    477   bool operator>=(TimeTicks other) const {
    478     return ticks_ >= other.ticks_;
    479   }
    480 
    481  protected:
    482   friend class TimeDelta;
    483   friend class PageLoadTrackerUnitTest;
    484 
    485   // Please use Now() to create a new object. This is for internal use
    486   // and testing. Ticks is in microseconds.
    487   explicit TimeTicks(int64 ticks) : ticks_(ticks) {
    488   }
    489 
    490   // Tick count in microseconds.
    491   int64 ticks_;
    492 
    493 #if defined(OS_WIN)
    494   typedef DWORD (*TickFunctionType)(void);
    495   static TickFunctionType SetMockTickFunction(TickFunctionType ticker);
    496 #endif
    497 };
    498 
    499 inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
    500   return TimeTicks(t.ticks_ + delta_);
    501 }
    502 
    503 }  // namespace base
    504 
    505 #endif  // BASE_TIME_H_
    506