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.
4 :
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 :
22 : #ifndef BASE_TIME_H_
23 : #define BASE_TIME_H_
24 :
25 : #include <time.h>
26 :
27 : #include "base/basictypes.h"
28 :
29 : #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 :
35 : namespace base {
36 :
37 : class Time;
38 : class TimeTicks;
39 :
40 : // This unit test does a lot of manual time manipulation.
41 : class PageLoadTrackerUnitTest;
42 :
43 : // TimeDelta ------------------------------------------------------------------
44 :
45 : class TimeDelta {
46 : public:
47 0 : TimeDelta() : delta_(0) {
48 0 : }
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 1420 : int64 ToInternalValue() const {
62 1420 : 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;
69 : int InMinutes() const;
70 : double InSecondsF() const;
71 : int64 InSeconds() const;
72 : double InMillisecondsF() const;
73 : int64 InMilliseconds() const;
74 : int64 InMicroseconds() const;
75 :
76 0 : TimeDelta& operator=(TimeDelta other) {
77 0 : delta_ = other.delta_;
78 0 : 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 0 : TimeDelta& operator+=(TimeDelta other) {
90 0 : delta_ += other.delta_;
91 0 : 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 0 : bool operator!=(TimeDelta other) const {
130 0 : 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 0 : bool operator>(TimeDelta other) const {
139 0 : return delta_ > other.delta_;
140 : }
141 0 : bool operator>=(TimeDelta other) const {
142 0 : 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 1420 : explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
154 1420 : }
155 :
156 : // Delta in microseconds.
157 : int64 delta_;
158 : };
159 :
160 : inline TimeDelta operator*(int64 a, TimeDelta td) {
161 : return TimeDelta(a * td.delta_);
162 : }
163 :
164 : // Time -----------------------------------------------------------------------
165 :
166 : // Represents a wall clock time.
167 : class 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;
177 : static const int64 kNanosecondsPerMicrosecond = 1000;
178 : static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
179 : kMicrosecondsPerSecond;
180 :
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 : signed char month; // 1-based month (values 1 = January, etc.)
187 : signed char day_of_week; // 0-based day of week (0 = Sunday, etc.)
188 : signed char day_of_month; // 1-based day of month (1-31)
189 : signed char hour; // Hour within the current day (0-23)
190 : signed char minute; // Minute within the current hour (0-59)
191 : signed char second; // Second within the current minute (0-59 plus
192 : // leap 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 8517 : explicit Time() : us_(0) {
198 8517 : }
199 :
200 : // Returns true if the time object has not been initialized.
201 2839 : bool is_null() const {
202 2839 : 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 : // Returns the current time. Same as Now() except that this function always
211 : // uses system time so that there are no discrepancies between the returned
212 : // time and system time even on virtual environments including our test bot.
213 : // For timing sensitive unittests, this function should be used.
214 : static Time NowFromSystemTime();
215 :
216 : // Converts to/from time_t in UTC and a Time class.
217 : // TODO(brettw) this should be removed once everybody starts using the |Time|
218 : // class.
219 : static Time FromTimeT(time_t tt);
220 : time_t ToTimeT() const;
221 :
222 : // Converts time to/from a double which is the number of seconds since epoch
223 : // (Jan 1, 1970). Webkit uses this format to represent time.
224 : static Time FromDoubleT(double dt);
225 : double ToDoubleT() const;
226 :
227 :
228 : #if defined(OS_WIN)
229 : static Time FromFileTime(FILETIME ft);
230 : FILETIME ToFileTime() const;
231 : #endif
232 :
233 : // Converts an exploded structure representing either the local time or UTC
234 : // into a Time class.
235 : static Time FromUTCExploded(const Exploded& exploded) {
236 : return FromExploded(false, exploded);
237 : }
238 0 : static Time FromLocalExploded(const Exploded& exploded) {
239 0 : return FromExploded(true, exploded);
240 : }
241 :
242 : // Converts an integer value representing Time to a class. This is used
243 : // when deserializing a |Time| structure, using a value known to be
244 : // compatible. It is not provided as a constructor because the integer type
245 : // may be unclear from the perspective of a caller.
246 : static Time FromInternalValue(int64 us) {
247 : return Time(us);
248 : }
249 :
250 : // Converts a string representation of time to a Time object.
251 : // An example of a time string which is converted is as below:-
252 : // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
253 : // in the input string, we assume local time.
254 : // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to
255 : // a new time converter class.
256 : static bool FromString(const wchar_t* time_string, Time* parsed_time);
257 :
258 : // For serializing, use FromInternalValue to reconstitute. Please don't use
259 : // this and do arithmetic on it, as it is more error prone than using the
260 : // provided operators.
261 0 : int64 ToInternalValue() const {
262 0 : return us_;
263 : }
264 :
265 : // Fills the given exploded structure with either the local time or UTC from
266 : // this time structure (containing UTC).
267 : void UTCExplode(Exploded* exploded) const {
268 : return Explode(false, exploded);
269 : }
270 0 : void LocalExplode(Exploded* exploded) const {
271 0 : return Explode(true, exploded);
272 : }
273 :
274 : // Rounds this time down to the nearest day in local time. It will represent
275 : // midnight on that day.
276 : Time LocalMidnight() const;
277 :
278 4258 : Time& operator=(Time other) {
279 4258 : us_ = other.us_;
280 4258 : return *this;
281 : }
282 :
283 : // Compute the difference between two times.
284 0 : TimeDelta operator-(Time other) const {
285 0 : return TimeDelta(us_ - other.us_);
286 : }
287 :
288 : // Modify by some time delta.
289 : Time& operator+=(TimeDelta delta) {
290 : us_ += delta.delta_;
291 : return *this;
292 : }
293 : Time& operator-=(TimeDelta delta) {
294 : us_ -= delta.delta_;
295 : return *this;
296 : }
297 :
298 : // Return a new time modified by some delta.
299 1420 : Time operator+(TimeDelta delta) const {
300 1420 : return us_ + delta.delta_;
301 : }
302 : Time operator-(TimeDelta delta) const {
303 : return us_ - delta.delta_;
304 : }
305 :
306 : // Comparison operators
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 0 : bool operator<(Time other) const {
314 0 : return us_ < other.us_;
315 : }
316 : bool operator<=(Time other) const {
317 : return us_ <= other.us_;
318 : }
319 0 : bool operator>(Time other) const {
320 0 : return us_ > other.us_;
321 : }
322 0 : bool operator>=(Time other) const {
323 0 : return us_ >= other.us_;
324 : }
325 :
326 : private:
327 : friend class TimeDelta;
328 :
329 : // Explodes the given time to either local time |is_local = true| or UTC
330 : // |is_local = false|.
331 : void Explode(bool is_local, Exploded* exploded) const;
332 :
333 : // Unexplodes a given time assuming the source is either local time
334 : // |is_local = true| or UTC |is_local = false|.
335 : static Time FromExploded(bool is_local, const Exploded& exploded);
336 :
337 7096 : Time(int64 us) : us_(us) {
338 7096 : }
339 :
340 : // The representation of Jan 1, 1970 UTC in microseconds since the
341 : // platform-dependent epoch.
342 : static const int64 kTimeTToMicrosecondsOffset;
343 :
344 : // Time in microseconds in UTC.
345 : int64 us_;
346 : };
347 :
348 : inline Time TimeDelta::operator+(Time t) const {
349 : return Time(t.us_ + delta_);
350 : }
351 :
352 : // Inline the TimeDelta factory methods, for fast TimeDelta construction.
353 :
354 : // static
355 : inline TimeDelta TimeDelta::FromDays(int64 days) {
356 : return TimeDelta(days * Time::kMicrosecondsPerDay);
357 : }
358 :
359 : // static
360 : inline TimeDelta TimeDelta::FromHours(int64 hours) {
361 : return TimeDelta(hours * Time::kMicrosecondsPerHour);
362 : }
363 :
364 : // static
365 : inline TimeDelta TimeDelta::FromMinutes(int64 minutes) {
366 : return TimeDelta(minutes * Time::kMicrosecondsPerMinute);
367 : }
368 :
369 : // static
370 1420 : inline TimeDelta TimeDelta::FromSeconds(int64 secs) {
371 1420 : return TimeDelta(secs * Time::kMicrosecondsPerSecond);
372 : }
373 :
374 : // static
375 0 : inline TimeDelta TimeDelta::FromMilliseconds(int64 ms) {
376 0 : return TimeDelta(ms * Time::kMicrosecondsPerMillisecond);
377 : }
378 :
379 : // static
380 : inline TimeDelta TimeDelta::FromMicroseconds(int64 us) {
381 : return TimeDelta(us);
382 : }
383 :
384 : // TimeTicks ------------------------------------------------------------------
385 :
386 : class TimeTicks {
387 : public:
388 0 : TimeTicks() : ticks_(0) {
389 0 : }
390 :
391 : // Platform-dependent tick count representing "right now."
392 : // The resolution of this clock is ~1-15ms. Resolution varies depending
393 : // on hardware/operating system configuration.
394 : static TimeTicks Now();
395 :
396 : // Returns a platform-dependent high-resolution tick count. Implementation
397 : // is hardware dependent and may or may not return sub-millisecond
398 : // resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
399 : // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
400 : static TimeTicks HighResNow();
401 :
402 : // Returns true if this object has not been initialized.
403 : bool is_null() const {
404 : return ticks_ == 0;
405 : }
406 :
407 : // Returns the internal numeric value of the TimeTicks object.
408 : int64 ToInternalValue() const {
409 : return ticks_;
410 : }
411 :
412 0 : TimeTicks& operator=(TimeTicks other) {
413 0 : ticks_ = other.ticks_;
414 0 : return *this;
415 : }
416 :
417 : // Compute the difference between two times.
418 0 : TimeDelta operator-(TimeTicks other) const {
419 0 : return TimeDelta(ticks_ - other.ticks_);
420 : }
421 :
422 : // Modify by some time delta.
423 : TimeTicks& operator+=(TimeDelta delta) {
424 : ticks_ += delta.delta_;
425 : return *this;
426 : }
427 : TimeTicks& operator-=(TimeDelta delta) {
428 : ticks_ -= delta.delta_;
429 : return *this;
430 : }
431 :
432 : // Return a new TimeTicks modified by some delta.
433 : TimeTicks operator+(TimeDelta delta) const {
434 : return TimeTicks(ticks_ + delta.delta_);
435 : }
436 : TimeTicks operator-(TimeDelta delta) const {
437 : return TimeTicks(ticks_ - delta.delta_);
438 : }
439 :
440 : // Comparison operators
441 : bool operator==(TimeTicks other) const {
442 : return ticks_ == other.ticks_;
443 : }
444 : bool operator!=(TimeTicks other) const {
445 : return ticks_ != other.ticks_;
446 : }
447 : bool operator<(TimeTicks other) const {
448 : return ticks_ < other.ticks_;
449 : }
450 : bool operator<=(TimeTicks other) const {
451 : return ticks_ <= other.ticks_;
452 : }
453 : bool operator>(TimeTicks other) const {
454 : return ticks_ > other.ticks_;
455 : }
456 : bool operator>=(TimeTicks other) const {
457 : return ticks_ >= other.ticks_;
458 : }
459 :
460 : protected:
461 : friend class TimeDelta;
462 : friend class PageLoadTrackerUnitTest;
463 :
464 : // Please use Now() to create a new object. This is for internal use
465 : // and testing. Ticks is in microseconds.
466 0 : explicit TimeTicks(int64 ticks) : ticks_(ticks) {
467 0 : }
468 :
469 : // Tick count in microseconds.
470 : int64 ticks_;
471 :
472 : #if defined(OS_WIN)
473 : typedef DWORD (*TickFunctionType)(void);
474 : static TickFunctionType SetMockTickFunction(TickFunctionType ticker);
475 : #endif
476 : };
477 :
478 : inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
479 : return TimeTicks(t.ticks_ + delta_);
480 : }
481 :
482 : } // namespace base
483 :
484 : #endif // BASE_TIME_H_
|