tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

time.h (14043B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 
      7 // Time represents an absolute point in time, internally represented as
      8 // microseconds (s/1,000,000) since a platform-dependent epoch.  Each
      9 // platform's epoch, along with other system-dependent clock interface
     10 // routines, is defined in time_PLATFORM.cc.
     11 //
     12 // TimeDelta represents a duration of time, internally represented in
     13 // microseconds.
     14 //
     15 // TimeTicks represents an abstract time that is always incrementing for use
     16 // in measuring time durations. It is internally represented in microseconds.
     17 // It can not be converted to a human-readable time, but is guaranteed not to
     18 // decrease (if the user changes the computer clock, Time::Now() may actually
     19 // decrease or jump).
     20 //
     21 // These classes are represented as only a 64-bit value, so they can be
     22 // efficiently passed by value.
     23 
     24 #ifndef BASE_TIME_H_
     25 #define BASE_TIME_H_
     26 
     27 #include <time.h>
     28 
     29 #include "base/basictypes.h"
     30 
     31 namespace base {
     32 
     33 class Time;
     34 class TimeTicks;
     35 
     36 // This unit test does a lot of manual time manipulation.
     37 class PageLoadTrackerUnitTest;
     38 
     39 // TimeDelta ------------------------------------------------------------------
     40 
     41 class TimeDelta {
     42 public:
     43  TimeDelta() : delta_(0) {}
     44 
     45  // Converts units of time to TimeDeltas.
     46  static TimeDelta FromDays(int64_t days);
     47  static TimeDelta FromHours(int64_t hours);
     48  static TimeDelta FromMinutes(int64_t minutes);
     49  static TimeDelta FromSeconds(int64_t secs);
     50  static TimeDelta FromMilliseconds(int64_t ms);
     51  static TimeDelta FromMicroseconds(int64_t us);
     52 
     53  // Returns the internal numeric value of the TimeDelta object. Please don't
     54  // use this and do arithmetic on it, as it is more error prone than using the
     55  // provided operators.
     56  int64_t ToInternalValue() const { return delta_; }
     57 
     58  // Returns the time delta in some unit. The F versions return a floating
     59  // point value, the "regular" versions return a rounded-down value.
     60  int InDays() const;
     61  int InHours() const;
     62  int InMinutes() const;
     63  double InSecondsF() const;
     64  int64_t InSeconds() const;
     65  double InMillisecondsF() const;
     66  int64_t InMilliseconds() const;
     67  int64_t InMicroseconds() const;
     68 
     69  TimeDelta& operator=(TimeDelta other) {
     70    delta_ = other.delta_;
     71    return *this;
     72  }
     73 
     74  // Computations with other deltas.
     75  TimeDelta operator+(TimeDelta other) const {
     76    return TimeDelta(delta_ + other.delta_);
     77  }
     78  TimeDelta operator-(TimeDelta other) const {
     79    return TimeDelta(delta_ - other.delta_);
     80  }
     81 
     82  TimeDelta& operator+=(TimeDelta other) {
     83    delta_ += other.delta_;
     84    return *this;
     85  }
     86  TimeDelta& operator-=(TimeDelta other) {
     87    delta_ -= other.delta_;
     88    return *this;
     89  }
     90  TimeDelta operator-() const { return TimeDelta(-delta_); }
     91 
     92  // Computations with ints, note that we only allow multiplicative operations
     93  // with ints, and additive operations with other deltas.
     94  TimeDelta operator*(int64_t a) const { return TimeDelta(delta_ * a); }
     95  TimeDelta operator/(int64_t a) const { return TimeDelta(delta_ / a); }
     96  TimeDelta& operator*=(int64_t a) {
     97    delta_ *= a;
     98    return *this;
     99  }
    100  TimeDelta& operator/=(int64_t a) {
    101    delta_ /= a;
    102    return *this;
    103  }
    104  int64_t operator/(TimeDelta a) const { return delta_ / a.delta_; }
    105 
    106  // Defined below because it depends on the definition of the other classes.
    107  Time operator+(Time t) const;
    108  TimeTicks operator+(TimeTicks t) const;
    109 
    110  // Comparison operators.
    111  bool operator==(TimeDelta other) const { return delta_ == other.delta_; }
    112  bool operator!=(TimeDelta other) const { return delta_ != other.delta_; }
    113  bool operator<(TimeDelta other) const { return delta_ < other.delta_; }
    114  bool operator<=(TimeDelta other) const { return delta_ <= other.delta_; }
    115  bool operator>(TimeDelta other) const { return delta_ > other.delta_; }
    116  bool operator>=(TimeDelta other) const { return delta_ >= other.delta_; }
    117 
    118 private:
    119  friend class Time;
    120  friend class TimeTicks;
    121  friend TimeDelta operator*(int64_t a, TimeDelta td);
    122 
    123  // Constructs a delta given the duration in microseconds. This is private
    124  // to avoid confusion by callers with an integer constructor. Use
    125  // FromSeconds, FromMilliseconds, etc. instead.
    126  explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {}
    127 
    128  // Delta in microseconds.
    129  int64_t delta_;
    130 };
    131 
    132 inline TimeDelta operator*(int64_t a, TimeDelta td) {
    133  return TimeDelta(a * td.delta_);
    134 }
    135 
    136 // Time -----------------------------------------------------------------------
    137 
    138 // Represents a wall clock time.
    139 class Time {
    140 public:
    141  static const int64_t kMillisecondsPerSecond = 1000;
    142  static const int64_t kMicrosecondsPerMillisecond = 1000;
    143  static const int64_t kMicrosecondsPerSecond =
    144      kMicrosecondsPerMillisecond * kMillisecondsPerSecond;
    145  static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
    146  static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
    147  static const int64_t kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
    148  static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
    149  static const int64_t kNanosecondsPerMicrosecond = 1000;
    150  static const int64_t kNanosecondsPerSecond =
    151      kNanosecondsPerMicrosecond * kMicrosecondsPerSecond;
    152 
    153  // Represents an exploded time that can be formatted nicely. This is kind of
    154  // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
    155  // additions and changes to prevent errors.
    156  struct Exploded {
    157    int year;                  // Four digit year "2007"
    158    signed char month;         // 1-based month (values 1 = January, etc.)
    159    signed char day_of_week;   // 0-based day of week (0 = Sunday, etc.)
    160    signed char day_of_month;  // 1-based day of month (1-31)
    161    signed char hour;          // Hour within the current day (0-23)
    162    signed char minute;        // Minute within the current hour (0-59)
    163    signed char second;        // Second within the current minute (0-59 plus
    164                               // leap seconds which may take it up to 60).
    165    int millisecond;           // Milliseconds within the current second (0-999)
    166  };
    167 
    168  // Contains the NULL time. Use Time::Now() to get the current time.
    169  explicit Time() : us_(0) {}
    170 
    171  // Returns true if the time object has not been initialized.
    172  bool is_null() const { return us_ == 0; }
    173 
    174  // Returns the current time. Watch out, the system might adjust its clock
    175  // in which case time will actually go backwards. We don't guarantee that
    176  // times are increasing, or that two calls to Now() won't be the same.
    177  static Time Now();
    178 
    179  // Returns the current time. Same as Now() except that this function always
    180  // uses system time so that there are no discrepancies between the returned
    181  // time and system time even on virtual environments including our test bot.
    182  // For timing sensitive unittests, this function should be used.
    183  static Time NowFromSystemTime();
    184 
    185  // Converts to/from time_t in UTC and a Time class.
    186  // TODO(brettw) this should be removed once everybody starts using the |Time|
    187  // class.
    188  static Time FromTimeT(time_t tt);
    189  time_t ToTimeT() const;
    190 
    191  // Converts time to/from a double which is the number of seconds since epoch
    192  // (Jan 1, 1970).  Webkit uses this format to represent time.
    193  static Time FromDoubleT(double dt);
    194  double ToDoubleT() const;
    195 
    196  // Converts an exploded structure representing either the local time or UTC
    197  // into a Time class.
    198  static Time FromUTCExploded(const Exploded& exploded) {
    199    return FromExploded(false, exploded);
    200  }
    201  static Time FromLocalExploded(const Exploded& exploded) {
    202    return FromExploded(true, exploded);
    203  }
    204 
    205  // Converts an integer value representing Time to a class. This is used
    206  // when deserializing a |Time| structure, using a value known to be
    207  // compatible. It is not provided as a constructor because the integer type
    208  // may be unclear from the perspective of a caller.
    209  static Time FromInternalValue(int64_t us) { return Time(us); }
    210 
    211  // Converts a string representation of time to a Time object.
    212  // An example of a time string which is converted is as below:-
    213  // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
    214  // in the input string, we assume local time.
    215  // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to
    216  // a new time converter class.
    217  static bool FromString(const wchar_t* time_string, Time* parsed_time);
    218 
    219  // For serializing, use FromInternalValue to reconstitute. Please don't use
    220  // this and do arithmetic on it, as it is more error prone than using the
    221  // provided operators.
    222  int64_t ToInternalValue() const { return us_; }
    223 
    224  // Fills the given exploded structure with either the local time or UTC from
    225  // this time structure (containing UTC).
    226  void UTCExplode(Exploded* exploded) const { return Explode(false, exploded); }
    227  void LocalExplode(Exploded* exploded) const {
    228    return Explode(true, exploded);
    229  }
    230 
    231  // Rounds this time down to the nearest day in local time. It will represent
    232  // midnight on that day.
    233  Time LocalMidnight() const;
    234 
    235  Time& operator=(Time other) {
    236    us_ = other.us_;
    237    return *this;
    238  }
    239 
    240  // Compute the difference between two times.
    241  TimeDelta operator-(Time other) const { return TimeDelta(us_ - other.us_); }
    242 
    243  // Modify by some time delta.
    244  Time& operator+=(TimeDelta delta) {
    245    us_ += delta.delta_;
    246    return *this;
    247  }
    248  Time& operator-=(TimeDelta delta) {
    249    us_ -= delta.delta_;
    250    return *this;
    251  }
    252 
    253  // Return a new time modified by some delta.
    254  Time operator+(TimeDelta delta) const { return Time(us_ + delta.delta_); }
    255  Time operator-(TimeDelta delta) const { return Time(us_ - delta.delta_); }
    256 
    257  // Comparison operators
    258  bool operator==(Time other) const { return us_ == other.us_; }
    259  bool operator!=(Time other) const { return us_ != other.us_; }
    260  bool operator<(Time other) const { return us_ < other.us_; }
    261  bool operator<=(Time other) const { return us_ <= other.us_; }
    262  bool operator>(Time other) const { return us_ > other.us_; }
    263  bool operator>=(Time other) const { return us_ >= other.us_; }
    264 
    265 private:
    266  friend class TimeDelta;
    267 
    268  // Explodes the given time to either local time |is_local = true| or UTC
    269  // |is_local = false|.
    270  void Explode(bool is_local, Exploded* exploded) const;
    271 
    272  // Unexplodes a given time assuming the source is either local time
    273  // |is_local = true| or UTC |is_local = false|.
    274  static Time FromExploded(bool is_local, const Exploded& exploded);
    275 
    276  explicit Time(int64_t us) : us_(us) {}
    277 
    278  // The representation of Jan 1, 1970 UTC in microseconds since the
    279  // platform-dependent epoch.
    280  static const int64_t kTimeTToMicrosecondsOffset;
    281 
    282  // Time in microseconds in UTC.
    283  int64_t us_;
    284 };
    285 
    286 inline Time TimeDelta::operator+(Time t) const { return Time(t.us_ + delta_); }
    287 
    288 // Inline the TimeDelta factory methods, for fast TimeDelta construction.
    289 
    290 // static
    291 inline TimeDelta TimeDelta::FromDays(int64_t days) {
    292  return TimeDelta(days * Time::kMicrosecondsPerDay);
    293 }
    294 
    295 // static
    296 inline TimeDelta TimeDelta::FromHours(int64_t hours) {
    297  return TimeDelta(hours * Time::kMicrosecondsPerHour);
    298 }
    299 
    300 // static
    301 inline TimeDelta TimeDelta::FromMinutes(int64_t minutes) {
    302  return TimeDelta(minutes * Time::kMicrosecondsPerMinute);
    303 }
    304 
    305 // static
    306 inline TimeDelta TimeDelta::FromSeconds(int64_t secs) {
    307  return TimeDelta(secs * Time::kMicrosecondsPerSecond);
    308 }
    309 
    310 // static
    311 inline TimeDelta TimeDelta::FromMilliseconds(int64_t ms) {
    312  return TimeDelta(ms * Time::kMicrosecondsPerMillisecond);
    313 }
    314 
    315 // static
    316 inline TimeDelta TimeDelta::FromMicroseconds(int64_t us) {
    317  return TimeDelta(us);
    318 }
    319 
    320 // TimeTicks ------------------------------------------------------------------
    321 
    322 class TimeTicks {
    323 public:
    324  TimeTicks() : ticks_(0) {}
    325  TimeTicks(const TimeTicks&) = default;
    326 
    327  // Platform-dependent tick count representing "right now."
    328  // The resolution of this clock is ~1-15ms.  Resolution varies depending
    329  // on hardware/operating system configuration.
    330  static TimeTicks Now();
    331 
    332  // Returns true if this object has not been initialized.
    333  bool is_null() const { return ticks_ == 0; }
    334 
    335  // Returns the internal numeric value of the TimeTicks object.
    336  int64_t ToInternalValue() const { return ticks_; }
    337 
    338  TimeTicks& operator=(TimeTicks other) {
    339    ticks_ = other.ticks_;
    340    return *this;
    341  }
    342 
    343  // Compute the difference between two times.
    344  TimeDelta operator-(TimeTicks other) const {
    345    return TimeDelta(ticks_ - other.ticks_);
    346  }
    347 
    348  // Modify by some time delta.
    349  TimeTicks& operator+=(TimeDelta delta) {
    350    ticks_ += delta.delta_;
    351    return *this;
    352  }
    353  TimeTicks& operator-=(TimeDelta delta) {
    354    ticks_ -= delta.delta_;
    355    return *this;
    356  }
    357 
    358  // Return a new TimeTicks modified by some delta.
    359  TimeTicks operator+(TimeDelta delta) const {
    360    return TimeTicks(ticks_ + delta.delta_);
    361  }
    362  TimeTicks operator-(TimeDelta delta) const {
    363    return TimeTicks(ticks_ - delta.delta_);
    364  }
    365 
    366  // Comparison operators
    367  bool operator==(TimeTicks other) const { return ticks_ == other.ticks_; }
    368  bool operator!=(TimeTicks other) const { return ticks_ != other.ticks_; }
    369  bool operator<(TimeTicks other) const { return ticks_ < other.ticks_; }
    370  bool operator<=(TimeTicks other) const { return ticks_ <= other.ticks_; }
    371  bool operator>(TimeTicks other) const { return ticks_ > other.ticks_; }
    372  bool operator>=(TimeTicks other) const { return ticks_ >= other.ticks_; }
    373 
    374 protected:
    375  friend class TimeDelta;
    376  friend class PageLoadTrackerUnitTest;
    377 
    378  // Please use Now() to create a new object. This is for internal use
    379  // and testing. Ticks is in microseconds.
    380  explicit TimeTicks(int64_t ticks) : ticks_(ticks) {}
    381 
    382  // Tick count in microseconds.
    383  int64_t ticks_;
    384 };
    385 
    386 inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
    387  return TimeTicks(t.ticks_ + delta_);
    388 }
    389 
    390 }  // namespace base
    391 
    392 #endif  // BASE_TIME_H_