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