blob: b43aecef9d3ea800984584d9efad3d3375e5af2c [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"
initial.commit3f4a7322008-07-27 06:49:38 +090028
brettw@google.come3c034a2008-08-08 03:31:40 +090029#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
dsh@google.com0f8dd262008-10-28 05:43:33 +090035namespace base {
36
initial.commit3f4a7322008-07-27 06:49:38 +090037class Time;
38class TimeTicks;
39
40// This unit test does a lot of manual time manipulation.
41class PageLoadTrackerUnitTest;
42
43// TimeDelta ------------------------------------------------------------------
44
45class 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 // Returns the time delta in some unit. The F versions return a floating
66 // point value, the "regular" versions return a rounded-down value.
67 int InDays() const;
68 int InHours() const;
deanm@google.com02781222008-08-19 18:16:49 +090069 int InMinutes() const;
initial.commit3f4a7322008-07-27 06:49:38 +090070 double InSecondsF() const;
71 int64 InSeconds() const;
72 double InMillisecondsF() const;
73 int64 InMilliseconds() const;
74 int64 InMicroseconds() const;
75
76 TimeDelta& operator=(TimeDelta other) {
77 delta_ = other.delta_;
78 return *this;
79 }
80
81 // Computations with other deltas.
82 TimeDelta operator+(TimeDelta other) const {
83 return TimeDelta(delta_ + other.delta_);
84 }
85 TimeDelta operator-(TimeDelta other) const {
86 return TimeDelta(delta_ - other.delta_);
87 }
88
89 TimeDelta& operator+=(TimeDelta other) {
90 delta_ += other.delta_;
91 return *this;
92 }
93 TimeDelta& operator-=(TimeDelta other) {
94 delta_ -= other.delta_;
95 return *this;
96 }
97 TimeDelta operator-() const {
98 return TimeDelta(-delta_);
99 }
100
101 // Computations with ints, note that we only allow multiplicative operations
102 // with ints, and additive operations with other deltas.
103 TimeDelta operator*(int64 a) const {
104 return TimeDelta(delta_ * a);
105 }
106 TimeDelta operator/(int64 a) const {
107 return TimeDelta(delta_ / a);
108 }
109 TimeDelta& operator*=(int64 a) {
110 delta_ *= a;
111 return *this;
112 }
113 TimeDelta& operator/=(int64 a) {
114 delta_ /= a;
115 return *this;
116 }
117 int64 operator/(TimeDelta a) const {
118 return delta_ / a.delta_;
119 }
120
121 // Defined below because it depends on the definition of the other classes.
122 Time operator+(Time t) const;
123 TimeTicks operator+(TimeTicks t) const;
124
125 // Comparison operators.
126 bool operator==(TimeDelta other) const {
127 return delta_ == other.delta_;
128 }
129 bool operator!=(TimeDelta other) const {
130 return delta_ != other.delta_;
131 }
132 bool operator<(TimeDelta other) const {
133 return delta_ < other.delta_;
134 }
135 bool operator<=(TimeDelta other) const {
136 return delta_ <= other.delta_;
137 }
138 bool operator>(TimeDelta other) const {
139 return delta_ > other.delta_;
140 }
141 bool operator>=(TimeDelta other) const {
142 return delta_ >= other.delta_;
143 }
144
145 private:
146 friend class Time;
147 friend class TimeTicks;
148 friend TimeDelta operator*(int64 a, TimeDelta td);
149
150 // Constructs a delta given the duration in microseconds. This is private
151 // to avoid confusion by callers with an integer constructor. Use
152 // FromSeconds, FromMilliseconds, etc. instead.
153 explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
154 }
155
156 // Delta in microseconds.
157 int64 delta_;
158};
159
160inline TimeDelta operator*(int64 a, TimeDelta td) {
161 return TimeDelta(a * td.delta_);
162}
163
164// Time -----------------------------------------------------------------------
165
166// Represents a wall clock time.
167class Time {
168 public:
169 static const int64 kMillisecondsPerSecond = 1000;
170 static const int64 kMicrosecondsPerMillisecond = 1000;
171 static const int64 kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
172 kMillisecondsPerSecond;
173 static const int64 kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
174 static const int64 kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
175 static const int64 kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
176 static const int64 kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
mmentovai@google.com7ba78d72008-08-12 03:15:10 +0900177 static const int64 kNanosecondsPerMicrosecond = 1000;
178 static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
179 kMicrosecondsPerSecond;
initial.commit3f4a7322008-07-27 06:49:38 +0900180
181 // Represents an exploded time that can be formatted nicely. This is kind of
182 // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
183 // additions and changes to prevent errors.
184 struct Exploded {
185 int year; // Four digit year "2007"
186 int month; // 1-based month (values 1 = January, etc.)
187 int day_of_week; // 0-based day of week (0 = Sunday, etc.)
188 int day_of_month; // 1-based day of month (1-31)
189 int hour; // Hour within the current day (0-23)
190 int minute; // Minute within the current hour (0-59)
191 int second; // Second within the current minute (0-59 plus leap
192 // seconds which may take it up to 60).
193 int millisecond; // Milliseconds within the current second (0-999)
194 };
195
196 // Contains the NULL time. Use Time::Now() to get the current time.
197 explicit Time() : us_(0) {
198 }
199
200 // Returns true if the time object has not been initialized.
201 bool is_null() const {
202 return us_ == 0;
203 }
204
205 // Returns the current time. Watch out, the system might adjust its clock
206 // in which case time will actually go backwards. We don't guarantee that
207 // times are increasing, or that two calls to Now() won't be the same.
208 static Time Now();
209
210 // Converts to/from time_t in UTC and a Time class.
211 // TODO(brettw) this should be removed once everybody starts using the |Time|
212 // class.
213 static Time FromTimeT(time_t tt);
214 time_t ToTimeT() const;
215
216 // Converts time to a double which is the number of seconds since epoch
217 // (Jan 1, 1970). Webkit uses this format to represent time.
218 double ToDoubleT() const;
219
brettw@google.come3c034a2008-08-08 03:31:40 +0900220#if defined(OS_WIN)
initial.commit3f4a7322008-07-27 06:49:38 +0900221 static Time FromFileTime(FILETIME ft);
222 FILETIME ToFileTime() const;
223#endif
224
225 // Converts an exploded structure representing either the local time or UTC
226 // into a Time class.
227 static Time FromUTCExploded(const Exploded& exploded) {
228 return FromExploded(false, exploded);
229 }
230 static Time FromLocalExploded(const Exploded& exploded) {
231 return FromExploded(true, exploded);
232 }
233
234 // Converts an integer value representing Time to a class. This is used
235 // when deserializing a |Time| structure, using a value known to be
236 // compatible. It is not provided as a constructor because the integer type
237 // may be unclear from the perspective of a caller.
238 static Time FromInternalValue(int64 us) {
239 return Time(us);
240 }
241
242 // Converts a string representation of time to a Time object.
243 // An example of a time string which is converted is as below:-
244 // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
245 // in the input string, we assume local time.
246 // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to
247 // a new time converter class.
248 static bool FromString(const wchar_t* time_string, Time* parsed_time);
249
250 // For serializing, use FromInternalValue to reconstitute. Please don't use
251 // this and do arithmetic on it, as it is more error prone than using the
252 // provided operators.
253 int64 ToInternalValue() const {
254 return us_;
255 }
256
257 // Fills the given exploded structure with either the local time or UTC from
258 // this time structure (containing UTC).
259 void UTCExplode(Exploded* exploded) const {
260 return Explode(false, exploded);
261 }
262 void LocalExplode(Exploded* exploded) const {
263 return Explode(true, exploded);
264 }
265
266 // Rounds this time down to the nearest day in local time. It will represent
267 // midnight on that day.
268 Time LocalMidnight() const;
269
270 Time& operator=(Time other) {
271 us_ = other.us_;
272 return *this;
273 }
274
275 // Compute the difference between two times.
276 TimeDelta operator-(Time other) const {
277 return TimeDelta(us_ - other.us_);
278 }
279
280 // Modify by some time delta.
281 Time& operator+=(TimeDelta delta) {
282 us_ += delta.delta_;
283 return *this;
284 }
285 Time& operator-=(TimeDelta delta) {
286 us_ -= delta.delta_;
287 return *this;
288 }
289
290 // Return a new time modified by some delta.
291 Time operator+(TimeDelta delta) const {
292 return us_ + delta.delta_;
293 }
294 Time operator-(TimeDelta delta) const {
295 return us_ - delta.delta_;
296 }
297
298 // Comparison operators
299 bool operator==(Time other) const {
300 return us_ == other.us_;
301 }
302 bool operator!=(Time other) const {
303 return us_ != other.us_;
304 }
305 bool operator<(Time other) const {
306 return us_ < other.us_;
307 }
308 bool operator<=(Time other) const {
309 return us_ <= other.us_;
310 }
311 bool operator>(Time other) const {
312 return us_ > other.us_;
313 }
314 bool operator>=(Time other) const {
315 return us_ >= other.us_;
316 }
317
318 private:
319 friend class TimeDelta;
320
initial.commit3f4a7322008-07-27 06:49:38 +0900321 // Explodes the given time to either local time |is_local = true| or UTC
322 // |is_local = false|.
323 void Explode(bool is_local, Exploded* exploded) const;
324
325 // Unexplodes a given time assuming the source is either local time
326 // |is_local = true| or UTC |is_local = false|.
327 static Time FromExploded(bool is_local, const Exploded& exploded);
328
329 Time(int64 us) : us_(us) {
330 }
331
332 // The representation of Jan 1, 1970 UTC in microseconds since the
333 // platform-dependent epoch.
334 static const int64 kTimeTToMicrosecondsOffset;
335
336 // Time in microseconds in UTC.
337 int64 us_;
initial.commit3f4a7322008-07-27 06:49:38 +0900338};
339
340inline Time TimeDelta::operator+(Time t) const {
341 return Time(t.us_ + delta_);
342}
343
deanm@chromium.orgd08e9e62009-01-14 00:20:06 +0900344// Inline the TimeDelta factory methods, for fast TimeDelta construction.
345
346// static
347inline TimeDelta TimeDelta::FromDays(int64 days) {
348 return TimeDelta(days * Time::kMicrosecondsPerDay);
349}
350
351// static
352inline TimeDelta TimeDelta::FromHours(int64 hours) {
353 return TimeDelta(hours * Time::kMicrosecondsPerHour);
354}
355
356// static
357inline TimeDelta TimeDelta::FromMinutes(int64 minutes) {
358 return TimeDelta(minutes * Time::kMicrosecondsPerMinute);
359}
360
361// static
362inline TimeDelta TimeDelta::FromSeconds(int64 secs) {
363 return TimeDelta(secs * Time::kMicrosecondsPerSecond);
364}
365
366// static
367inline TimeDelta TimeDelta::FromMilliseconds(int64 ms) {
368 return TimeDelta(ms * Time::kMicrosecondsPerMillisecond);
369}
370
371// static
372inline TimeDelta TimeDelta::FromMicroseconds(int64 us) {
373 return TimeDelta(us);
374}
375
initial.commit3f4a7322008-07-27 06:49:38 +0900376// TimeTicks ------------------------------------------------------------------
377
378class TimeTicks {
379 public:
380 TimeTicks() : ticks_(0) {
381 }
382
383 // Platform-dependent tick count representing "right now."
mbelshe@google.com556bc842008-09-26 12:00:00 +0900384 // The resolution of this clock is ~1-15ms. Resolution varies depending
initial.commit3f4a7322008-07-27 06:49:38 +0900385 // on hardware/operating system configuration.
386 static TimeTicks Now();
387
mbelshe@google.com556bc842008-09-26 12:00:00 +0900388 // Returns a platform-dependent high-resolution tick count. Implementation
389 // is hardware dependent and may or may not return sub-millisecond
390 // resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
391 // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
392 static TimeTicks HighResNow();
initial.commit3f4a7322008-07-27 06:49:38 +0900393
394 // Returns true if this object has not been initialized.
395 bool is_null() const {
396 return ticks_ == 0;
397 }
398
avi@google.com6f9d6822008-09-10 03:33:11 +0900399 // Returns the internal numeric value of the TimeTicks object.
400 int64 ToInternalValue() const {
401 return ticks_;
402 }
403
initial.commit3f4a7322008-07-27 06:49:38 +0900404 TimeTicks& operator=(TimeTicks other) {
405 ticks_ = other.ticks_;
406 return *this;
407 }
408
409 // Compute the difference between two times.
410 TimeDelta operator-(TimeTicks other) const {
411 return TimeDelta(ticks_ - other.ticks_);
412 }
413
414 // Modify by some time delta.
415 TimeTicks& operator+=(TimeDelta delta) {
416 ticks_ += delta.delta_;
417 return *this;
418 }
419 TimeTicks& operator-=(TimeDelta delta) {
420 ticks_ -= delta.delta_;
421 return *this;
422 }
423
424 // Return a new TimeTicks modified by some delta.
425 TimeTicks operator+(TimeDelta delta) const {
426 return TimeTicks(ticks_ + delta.delta_);
427 }
428 TimeTicks operator-(TimeDelta delta) const {
429 return TimeTicks(ticks_ - delta.delta_);
430 }
431
432 // Comparison operators
433 bool operator==(TimeTicks other) const {
434 return ticks_ == other.ticks_;
435 }
436 bool operator!=(TimeTicks other) const {
437 return ticks_ != other.ticks_;
438 }
439 bool operator<(TimeTicks other) const {
440 return ticks_ < other.ticks_;
441 }
442 bool operator<=(TimeTicks other) const {
443 return ticks_ <= other.ticks_;
444 }
445 bool operator>(TimeTicks other) const {
446 return ticks_ > other.ticks_;
447 }
448 bool operator>=(TimeTicks other) const {
449 return ticks_ >= other.ticks_;
450 }
451
452 protected:
453 friend class TimeDelta;
454 friend class PageLoadTrackerUnitTest;
455
456 // Please use Now() to create a new object. This is for internal use
457 // and testing. Ticks is in microseconds.
458 explicit TimeTicks(int64 ticks) : ticks_(ticks) {
459 }
460
461 // Tick count in microseconds.
462 int64 ticks_;
463
brettw@google.come3c034a2008-08-08 03:31:40 +0900464#if defined(OS_WIN)
deanm@google.com1fdfd512008-09-09 17:58:51 +0900465 typedef DWORD (*TickFunctionType)(void);
466 static TickFunctionType SetMockTickFunction(TickFunctionType ticker);
initial.commit3f4a7322008-07-27 06:49:38 +0900467#endif
468};
469
470inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
471 return TimeTicks(t.ticks_ + delta_);
472}
473
dsh@google.com0f8dd262008-10-28 05:43:33 +0900474} // namespace base
475
brettw@google.come3c034a2008-08-08 03:31:40 +0900476#endif // BASE_TIME_H_