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