blob: c25419fe84860bc67e246897f2d72490a033e028 [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// 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.commit3f4a7322008-07-27 06:49:38 +09004
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
brettw@google.come3c034a2008-08-08 03:31:40 +090022#ifndef BASE_TIME_H_
23#define BASE_TIME_H_
initial.commit3f4a7322008-07-27 06:49:38 +090024
25#include <time.h>
mmentovai@google.com7ba78d72008-08-12 03:15:10 +090026
initial.commit3f4a7322008-07-27 06:49:38 +090027#include "base/basictypes.h"
28#include "testing/gtest/include/gtest/gtest_prod.h"
29
brettw@google.come3c034a2008-08-08 03:31:40 +090030#if defined(OS_WIN)
31// For FILETIME in FromFileTime, until it moves to a new converter class.
32// See TODO(iyengar) below.
33#include <windows.h>
34#endif
35
initial.commit3f4a7322008-07-27 06:49:38 +090036class Time;
37class TimeTicks;
38
39// This unit test does a lot of manual time manipulation.
40class PageLoadTrackerUnitTest;
41
42// TimeDelta ------------------------------------------------------------------
43
44class TimeDelta {
45 public:
46 TimeDelta() : delta_(0) {
47 }
48
49 // Converts units of time to TimeDeltas.
50 static TimeDelta FromDays(int64 days);
51 static TimeDelta FromHours(int64 hours);
52 static TimeDelta FromMinutes(int64 minutes);
53 static TimeDelta FromSeconds(int64 secs);
54 static TimeDelta FromMilliseconds(int64 ms);
55 static TimeDelta FromMicroseconds(int64 us);
56
57 // Returns the internal numeric value of the TimeDelta object. Please don't
58 // use this and do arithmetic on it, as it is more error prone than using the
59 // provided operators.
60 int64 ToInternalValue() const {
61 return delta_;
62 }
63
64 // Returns the time delta in some unit. The F versions return a floating
65 // point value, the "regular" versions return a rounded-down value.
66 int InDays() const;
67 int InHours() const;
deanm@google.com02781222008-08-19 18:16:49 +090068 int InMinutes() const;
initial.commit3f4a7322008-07-27 06:49:38 +090069 double InSecondsF() const;
70 int64 InSeconds() const;
71 double InMillisecondsF() const;
72 int64 InMilliseconds() const;
73 int64 InMicroseconds() const;
74
75 TimeDelta& operator=(TimeDelta other) {
76 delta_ = other.delta_;
77 return *this;
78 }
79
80 // Computations with other deltas.
81 TimeDelta operator+(TimeDelta other) const {
82 return TimeDelta(delta_ + other.delta_);
83 }
84 TimeDelta operator-(TimeDelta other) const {
85 return TimeDelta(delta_ - other.delta_);
86 }
87
88 TimeDelta& operator+=(TimeDelta other) {
89 delta_ += other.delta_;
90 return *this;
91 }
92 TimeDelta& operator-=(TimeDelta other) {
93 delta_ -= other.delta_;
94 return *this;
95 }
96 TimeDelta operator-() const {
97 return TimeDelta(-delta_);
98 }
99
100 // Computations with ints, note that we only allow multiplicative operations
101 // with ints, and additive operations with other deltas.
102 TimeDelta operator*(int64 a) const {
103 return TimeDelta(delta_ * a);
104 }
105 TimeDelta operator/(int64 a) const {
106 return TimeDelta(delta_ / a);
107 }
108 TimeDelta& operator*=(int64 a) {
109 delta_ *= a;
110 return *this;
111 }
112 TimeDelta& operator/=(int64 a) {
113 delta_ /= a;
114 return *this;
115 }
116 int64 operator/(TimeDelta a) const {
117 return delta_ / a.delta_;
118 }
119
120 // Defined below because it depends on the definition of the other classes.
121 Time operator+(Time t) const;
122 TimeTicks operator+(TimeTicks t) const;
123
124 // Comparison operators.
125 bool operator==(TimeDelta other) const {
126 return delta_ == other.delta_;
127 }
128 bool operator!=(TimeDelta other) const {
129 return delta_ != other.delta_;
130 }
131 bool operator<(TimeDelta other) const {
132 return delta_ < other.delta_;
133 }
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
144 private:
145 friend class Time;
146 friend class TimeTicks;
147 friend TimeDelta operator*(int64 a, TimeDelta td);
148
149 // Constructs a delta given the duration in microseconds. This is private
150 // to avoid confusion by callers with an integer constructor. Use
151 // FromSeconds, FromMilliseconds, etc. instead.
152 explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
153 }
154
155 // Delta in microseconds.
156 int64 delta_;
157};
158
159inline TimeDelta operator*(int64 a, TimeDelta td) {
160 return TimeDelta(a * td.delta_);
161}
162
163// Time -----------------------------------------------------------------------
164
165// Represents a wall clock time.
166class Time {
167 public:
168 static const int64 kMillisecondsPerSecond = 1000;
169 static const int64 kMicrosecondsPerMillisecond = 1000;
170 static const int64 kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
171 kMillisecondsPerSecond;
172 static const int64 kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
173 static const int64 kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
174 static const int64 kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
175 static const int64 kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
mmentovai@google.com7ba78d72008-08-12 03:15:10 +0900176 static const int64 kNanosecondsPerMicrosecond = 1000;
177 static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
178 kMicrosecondsPerSecond;
initial.commit3f4a7322008-07-27 06:49:38 +0900179
180 // Represents an exploded time that can be formatted nicely. This is kind of
181 // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
182 // additions and changes to prevent errors.
183 struct Exploded {
184 int year; // Four digit year "2007"
185 int month; // 1-based month (values 1 = January, etc.)
186 int day_of_week; // 0-based day of week (0 = Sunday, etc.)
187 int day_of_month; // 1-based day of month (1-31)
188 int hour; // Hour within the current day (0-23)
189 int minute; // Minute within the current hour (0-59)
190 int second; // Second within the current minute (0-59 plus leap
191 // seconds which may take it up to 60).
192 int millisecond; // Milliseconds within the current second (0-999)
193 };
194
195 // Contains the NULL time. Use Time::Now() to get the current time.
196 explicit Time() : us_(0) {
197 }
198
199 // Returns true if the time object has not been initialized.
200 bool is_null() const {
201 return us_ == 0;
202 }
203
204 // Returns the current time. Watch out, the system might adjust its clock
205 // in which case time will actually go backwards. We don't guarantee that
206 // times are increasing, or that two calls to Now() won't be the same.
207 static Time Now();
208
209 // Converts to/from time_t in UTC and a Time class.
210 // TODO(brettw) this should be removed once everybody starts using the |Time|
211 // class.
212 static Time FromTimeT(time_t tt);
213 time_t ToTimeT() const;
214
215 // Converts time to a double which is the number of seconds since epoch
216 // (Jan 1, 1970). Webkit uses this format to represent time.
217 double ToDoubleT() const;
218
brettw@google.come3c034a2008-08-08 03:31:40 +0900219#if defined(OS_WIN)
initial.commit3f4a7322008-07-27 06:49:38 +0900220 static Time FromFileTime(FILETIME ft);
221 FILETIME ToFileTime() const;
222#endif
223
224 // Converts an exploded structure representing either the local time or UTC
225 // into a Time class.
226 static Time FromUTCExploded(const Exploded& exploded) {
227 return FromExploded(false, exploded);
228 }
229 static Time FromLocalExploded(const Exploded& exploded) {
230 return FromExploded(true, exploded);
231 }
232
233 // Converts an integer value representing Time to a class. This is used
234 // when deserializing a |Time| structure, using a value known to be
235 // compatible. It is not provided as a constructor because the integer type
236 // may be unclear from the perspective of a caller.
237 static Time FromInternalValue(int64 us) {
238 return Time(us);
239 }
240
241 // Converts a string representation of time to a Time object.
242 // An example of a time string which is converted is as below:-
243 // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
244 // in the input string, we assume local time.
245 // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to
246 // a new time converter class.
247 static bool FromString(const wchar_t* time_string, Time* parsed_time);
248
249 // For serializing, use FromInternalValue to reconstitute. Please don't use
250 // this and do arithmetic on it, as it is more error prone than using the
251 // provided operators.
252 int64 ToInternalValue() const {
253 return us_;
254 }
255
256 // Fills the given exploded structure with either the local time or UTC from
257 // this time structure (containing UTC).
258 void UTCExplode(Exploded* exploded) const {
259 return Explode(false, exploded);
260 }
261 void LocalExplode(Exploded* exploded) const {
262 return Explode(true, exploded);
263 }
264
265 // Rounds this time down to the nearest day in local time. It will represent
266 // midnight on that day.
267 Time LocalMidnight() const;
268
269 Time& operator=(Time other) {
270 us_ = other.us_;
271 return *this;
272 }
273
274 // Compute the difference between two times.
275 TimeDelta operator-(Time other) const {
276 return TimeDelta(us_ - other.us_);
277 }
278
279 // Modify by some time delta.
280 Time& operator+=(TimeDelta delta) {
281 us_ += delta.delta_;
282 return *this;
283 }
284 Time& operator-=(TimeDelta delta) {
285 us_ -= delta.delta_;
286 return *this;
287 }
288
289 // Return a new time modified by some delta.
290 Time operator+(TimeDelta delta) const {
291 return us_ + delta.delta_;
292 }
293 Time operator-(TimeDelta delta) const {
294 return us_ - delta.delta_;
295 }
296
297 // Comparison operators
298 bool operator==(Time other) const {
299 return us_ == other.us_;
300 }
301 bool operator!=(Time other) const {
302 return us_ != other.us_;
303 }
304 bool operator<(Time other) const {
305 return us_ < other.us_;
306 }
307 bool operator<=(Time other) const {
308 return us_ <= other.us_;
309 }
310 bool operator>(Time other) const {
311 return us_ > other.us_;
312 }
313 bool operator>=(Time other) const {
314 return us_ >= other.us_;
315 }
316
317 private:
318 friend class TimeDelta;
319
320 // Platform-dependent wall clock interface
321 static int64 CurrentWallclockMicroseconds();
322
323 // Initialize or resynchronize the clock.
324 static void InitializeClock();
325
326 // Explodes the given time to either local time |is_local = true| or UTC
327 // |is_local = false|.
328 void Explode(bool is_local, Exploded* exploded) const;
329
330 // Unexplodes a given time assuming the source is either local time
331 // |is_local = true| or UTC |is_local = false|.
332 static Time FromExploded(bool is_local, const Exploded& exploded);
333
334 Time(int64 us) : us_(us) {
335 }
336
337 // The representation of Jan 1, 1970 UTC in microseconds since the
338 // platform-dependent epoch.
339 static const int64 kTimeTToMicrosecondsOffset;
340
341 // Time in microseconds in UTC.
342 int64 us_;
343
344 // The initial time sampled via this API.
345 static int64 initial_time_;
346
347 // The initial clock counter sampled via this API.
348 static TimeTicks initial_ticks_;
349};
350
351inline Time TimeDelta::operator+(Time t) const {
352 return Time(t.us_ + delta_);
353}
354
355// TimeTicks ------------------------------------------------------------------
356
357class TimeTicks {
358 public:
359 TimeTicks() : ticks_(0) {
360 }
361
362 // Platform-dependent tick count representing "right now."
363 // The resolution of this clock is ~1-5ms. Resolution varies depending
364 // on hardware/operating system configuration.
365 static TimeTicks Now();
366
367 // Returns a platform-dependent high-resolution tick count. IT IS BROKEN ON
368 // SOME HARDWARE and is designed to be used for profiling and perf testing
369 // only (see the impl for more information).
370 static TimeTicks UnreliableHighResNow();
371
372
373 // Returns true if this object has not been initialized.
374 bool is_null() const {
375 return ticks_ == 0;
376 }
377
378 TimeTicks& operator=(TimeTicks other) {
379 ticks_ = other.ticks_;
380 return *this;
381 }
382
383 // Compute the difference between two times.
384 TimeDelta operator-(TimeTicks other) const {
385 return TimeDelta(ticks_ - other.ticks_);
386 }
387
388 // Modify by some time delta.
389 TimeTicks& operator+=(TimeDelta delta) {
390 ticks_ += delta.delta_;
391 return *this;
392 }
393 TimeTicks& operator-=(TimeDelta delta) {
394 ticks_ -= delta.delta_;
395 return *this;
396 }
397
398 // Return a new TimeTicks modified by some delta.
399 TimeTicks operator+(TimeDelta delta) const {
400 return TimeTicks(ticks_ + delta.delta_);
401 }
402 TimeTicks operator-(TimeDelta delta) const {
403 return TimeTicks(ticks_ - delta.delta_);
404 }
405
406 // Comparison operators
407 bool operator==(TimeTicks other) const {
408 return ticks_ == other.ticks_;
409 }
410 bool operator!=(TimeTicks other) const {
411 return ticks_ != other.ticks_;
412 }
413 bool operator<(TimeTicks other) const {
414 return ticks_ < other.ticks_;
415 }
416 bool operator<=(TimeTicks other) const {
417 return ticks_ <= other.ticks_;
418 }
419 bool operator>(TimeTicks other) const {
420 return ticks_ > other.ticks_;
421 }
422 bool operator>=(TimeTicks other) const {
423 return ticks_ >= other.ticks_;
424 }
425
426 protected:
427 friend class TimeDelta;
428 friend class PageLoadTrackerUnitTest;
429
430 // Please use Now() to create a new object. This is for internal use
431 // and testing. Ticks is in microseconds.
432 explicit TimeTicks(int64 ticks) : ticks_(ticks) {
433 }
434
435 // Tick count in microseconds.
436 int64 ticks_;
437
brettw@google.come3c034a2008-08-08 03:31:40 +0900438#if defined(OS_WIN)
initial.commit3f4a7322008-07-27 06:49:38 +0900439 // The function to use for counting ticks.
440 typedef int (__stdcall *TickFunction)(void);
441 static TickFunction tick_function_;
442#endif
443};
444
445inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
446 return TimeTicks(t.ticks_ + delta_);
447}
448
brettw@google.come3c034a2008-08-08 03:31:40 +0900449#endif // BASE_TIME_H_
license.botf003cfe2008-08-24 09:55:55 +0900450