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 | |
| 5 | #include "base/time.h" |
| 6 | #include "base/string_util.h" |
| 7 | #include "base/third_party/nspr/prtime.h" |
| 8 | |
| 9 | #include "base/logging.h" |
| 10 | |
| 11 | namespace { |
| 12 | |
| 13 | // Time between resampling the un-granular clock for this API. 60 seconds. |
| 14 | const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond; |
| 15 | |
| 16 | } // namespace |
| 17 | |
| 18 | // TimeDelta ------------------------------------------------------------------ |
| 19 | |
| 20 | // static |
| 21 | TimeDelta TimeDelta::FromDays(int64 days) { |
| 22 | return TimeDelta(days * Time::kMicrosecondsPerDay); |
| 23 | } |
| 24 | |
| 25 | // static |
| 26 | TimeDelta TimeDelta::FromHours(int64 hours) { |
| 27 | return TimeDelta(hours * Time::kMicrosecondsPerHour); |
| 28 | } |
| 29 | |
| 30 | // static |
| 31 | TimeDelta TimeDelta::FromMinutes(int64 minutes) { |
| 32 | return TimeDelta(minutes * Time::kMicrosecondsPerMinute); |
| 33 | } |
| 34 | |
| 35 | // static |
| 36 | TimeDelta TimeDelta::FromSeconds(int64 secs) { |
| 37 | return TimeDelta(secs * Time::kMicrosecondsPerSecond); |
| 38 | } |
| 39 | |
| 40 | // static |
| 41 | TimeDelta TimeDelta::FromMilliseconds(int64 ms) { |
| 42 | return TimeDelta(ms * Time::kMicrosecondsPerMillisecond); |
| 43 | } |
| 44 | |
| 45 | // static |
| 46 | TimeDelta TimeDelta::FromMicroseconds(int64 us) { |
| 47 | return TimeDelta(us); |
| 48 | } |
| 49 | |
| 50 | int TimeDelta::InDays() const { |
| 51 | return static_cast<int>(delta_ / Time::kMicrosecondsPerDay); |
| 52 | } |
| 53 | |
| 54 | int TimeDelta::InHours() const { |
| 55 | return static_cast<int>(delta_ / Time::kMicrosecondsPerHour); |
| 56 | } |
| 57 | |
deanm@google.com | 0278122 | 2008-08-19 18:16:49 +0900 | [diff] [blame] | 58 | int TimeDelta::InMinutes() const { |
| 59 | return static_cast<int>(delta_ / Time::kMicrosecondsPerMinute); |
| 60 | } |
| 61 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 62 | double TimeDelta::InSecondsF() const { |
| 63 | return static_cast<double>(delta_) / Time::kMicrosecondsPerSecond; |
| 64 | } |
| 65 | |
| 66 | int64 TimeDelta::InSeconds() const { |
| 67 | return delta_ / Time::kMicrosecondsPerSecond; |
| 68 | } |
| 69 | |
| 70 | double TimeDelta::InMillisecondsF() const { |
| 71 | return static_cast<double>(delta_) / Time::kMicrosecondsPerMillisecond; |
| 72 | } |
| 73 | |
| 74 | int64 TimeDelta::InMilliseconds() const { |
| 75 | return delta_ / Time::kMicrosecondsPerMillisecond; |
| 76 | } |
| 77 | |
| 78 | int64 TimeDelta::InMicroseconds() const { |
| 79 | return delta_; |
| 80 | } |
| 81 | |
| 82 | // Time ----------------------------------------------------------------------- |
| 83 | |
| 84 | int64 Time::initial_time_ = 0; |
| 85 | TimeTicks Time::initial_ticks_; |
| 86 | |
| 87 | // static |
| 88 | void Time::InitializeClock() |
| 89 | { |
| 90 | initial_ticks_ = TimeTicks::Now(); |
| 91 | initial_time_ = CurrentWallclockMicroseconds(); |
| 92 | } |
| 93 | |
| 94 | // static |
| 95 | Time Time::Now() { |
| 96 | if (initial_time_ == 0) |
| 97 | InitializeClock(); |
| 98 | |
| 99 | // We implement time using the high-resolution timers so that we can get |
| 100 | // timeouts which are smaller than 10-15ms. If we just used |
| 101 | // CurrentWallclockMicroseconds(), we'd have the less-granular timer. |
| 102 | // |
| 103 | // To make this work, we initialize the clock (initial_time) and the |
| 104 | // counter (initial_ctr). To compute the initial time, we can check |
| 105 | // the number of ticks that have elapsed, and compute the delta. |
| 106 | // |
| 107 | // To avoid any drift, we periodically resync the counters to the system |
| 108 | // clock. |
| 109 | while(true) { |
| 110 | TimeTicks ticks = TimeTicks::Now(); |
| 111 | |
| 112 | // Calculate the time elapsed since we started our timer |
| 113 | TimeDelta elapsed = ticks - initial_ticks_; |
| 114 | |
| 115 | // Check if enough time has elapsed that we need to resync the clock. |
| 116 | if (elapsed.InMilliseconds() > kMaxMillisecondsToAvoidDrift) { |
| 117 | InitializeClock(); |
| 118 | continue; |
| 119 | } |
| 120 | |
| 121 | return elapsed + initial_time_; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | // static |
| 126 | Time Time::FromTimeT(time_t tt) { |
| 127 | if (tt == 0) |
| 128 | return Time(); // Preserve 0 so we can tell it doesn't exist. |
| 129 | return (tt * kMicrosecondsPerSecond) + kTimeTToMicrosecondsOffset; |
| 130 | } |
| 131 | |
| 132 | time_t Time::ToTimeT() const { |
| 133 | if (us_ == 0) |
| 134 | return 0; // Preserve 0 so we can tell it doesn't exist. |
| 135 | return (us_ - kTimeTToMicrosecondsOffset) / kMicrosecondsPerSecond; |
| 136 | } |
| 137 | |
| 138 | double Time::ToDoubleT() const { |
| 139 | if (us_ == 0) |
| 140 | return 0; // Preserve 0 so we can tell it doesn't exist. |
| 141 | return (static_cast<double>(us_ - kTimeTToMicrosecondsOffset) / |
| 142 | static_cast<double>(kMicrosecondsPerSecond)); |
| 143 | } |
| 144 | |
| 145 | Time Time::LocalMidnight() const { |
| 146 | Exploded exploded; |
| 147 | LocalExplode(&exploded); |
| 148 | exploded.hour = 0; |
| 149 | exploded.minute = 0; |
| 150 | exploded.second = 0; |
| 151 | exploded.millisecond = 0; |
| 152 | return FromLocalExploded(exploded); |
| 153 | } |
| 154 | |
| 155 | // static |
| 156 | bool Time::FromString(const wchar_t* time_string, Time* parsed_time) { |
| 157 | DCHECK((time_string != NULL) && (parsed_time != NULL)); |
| 158 | std::string ascii_time_string = WideToUTF8(time_string); |
| 159 | if (ascii_time_string.length() == 0) |
| 160 | return false; |
| 161 | PRTime result_time = 0; |
| 162 | PRStatus result = PR_ParseTimeString(ascii_time_string.c_str(), PR_FALSE, |
| 163 | &result_time); |
| 164 | if (PR_SUCCESS != result) |
| 165 | return false; |
| 166 | result_time += kTimeTToMicrosecondsOffset; |
| 167 | *parsed_time = Time(result_time); |
| 168 | return true; |
| 169 | } |
license.bot | f003cfe | 2008-08-24 09:55:55 +0900 | [diff] [blame^] | 170 | |