OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/time.h" | 5 #include "base/time.h" |
6 | 6 |
7 #ifdef OS_MACOSX | 7 #ifdef OS_MACOSX |
8 #include <mach/mach_time.h> | 8 #include <mach/mach_time.h> |
9 #endif | 9 #endif |
10 #include <sys/time.h> | 10 #include <sys/time.h> |
11 #include <time.h> | 11 #include <time.h> |
12 | 12 |
13 #include <limits> | |
14 | |
13 #include "base/basictypes.h" | 15 #include "base/basictypes.h" |
14 #include "base/logging.h" | 16 #include "base/logging.h" |
15 | 17 |
16 namespace base { | 18 namespace base { |
17 | 19 |
18 // The Time routines in this file use standard POSIX routines, or almost- | 20 // The Time routines in this file use standard POSIX routines, or almost- |
19 // standard routines in the case of timegm. We need to use a Mach-specific | 21 // standard routines in the case of timegm. We need to use a Mach-specific |
20 // function for TimeTicks::Now() on Mac OS X. | 22 // function for TimeTicks::Now() on Mac OS X. |
21 | 23 |
22 // Time ----------------------------------------------------------------------- | 24 // Time ----------------------------------------------------------------------- |
(...skipping 28 matching lines...) Expand all Loading... | |
51 timestruct.tm_yday = 0; // mktime/timegm ignore this | 53 timestruct.tm_yday = 0; // mktime/timegm ignore this |
52 timestruct.tm_isdst = -1; // attempt to figure it out | 54 timestruct.tm_isdst = -1; // attempt to figure it out |
53 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore | 55 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore |
54 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore | 56 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore |
55 | 57 |
56 time_t seconds; | 58 time_t seconds; |
57 if (is_local) | 59 if (is_local) |
58 seconds = mktime(×truct); | 60 seconds = mktime(×truct); |
59 else | 61 else |
60 seconds = timegm(×truct); | 62 seconds = timegm(×truct); |
61 DCHECK(seconds >= 0) << "mktime/timegm could not convert from exploded"; | |
62 | 63 |
63 uint64 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; | 64 int64 milliseconds; |
65 // Handle overflow. | |
66 if (seconds == -1 && | |
67 (exploded.year < 1969 || exploded.year > 1970)) { | |
68 // If exploded.year is 1969 or 1970, take -1 as correct, with the | |
69 // time indicating 1 second prior to the epoch. (1970 is allowed to handle | |
70 // time zone and DST offsets.) Otherwise, return the most future or past | |
71 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. | |
72 if (exploded.year < 1969) { | |
73 milliseconds = std::numeric_limits<time_t>::min() * | |
wtc
2008/10/31 20:52:01
Some points to ponder:
- What if time_t is uint32
Mark Mentovai
2008/10/31 21:21:01
wtc wrote:
| |
74 kMillisecondsPerSecond; | |
75 } else { | |
76 milliseconds = (std::numeric_limits<time_t>::max() * | |
77 kMillisecondsPerSecond) + | |
78 kMillisecondsPerSecond - 1; | |
wtc
2008/10/31 20:52:01
The need to add 999 milliseconds is still not clea
Mark Mentovai
2008/10/31 21:21:01
wtc wrote:
| |
79 } | |
80 } else { | |
81 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; | |
82 } | |
83 | |
64 return Time(milliseconds * kMicrosecondsPerMillisecond); | 84 return Time(milliseconds * kMicrosecondsPerMillisecond); |
65 } | 85 } |
66 | 86 |
67 void Time::Explode(bool is_local, Exploded* exploded) const { | 87 void Time::Explode(bool is_local, Exploded* exploded) const { |
68 // Time stores times with microsecond resolution, but Exploded only carries | 88 // Time stores times with microsecond resolution, but Exploded only carries |
69 // millisecond resolution, so begin by being lossy. | 89 // millisecond resolution, so begin by being lossy. |
70 uint64 milliseconds = us_ / kMicrosecondsPerMillisecond; | 90 int64 milliseconds = us_ / kMicrosecondsPerMillisecond; |
71 time_t seconds = milliseconds / kMillisecondsPerSecond; | 91 time_t seconds = milliseconds / kMillisecondsPerSecond; |
72 | 92 |
73 struct tm timestruct; | 93 struct tm timestruct; |
74 if (is_local) | 94 if (is_local) |
75 localtime_r(&seconds, ×truct); | 95 localtime_r(&seconds, ×truct); |
76 else | 96 else |
77 gmtime_r(&seconds, ×truct); | 97 gmtime_r(&seconds, ×truct); |
78 | 98 |
79 exploded->year = timestruct.tm_year + 1900; | 99 exploded->year = timestruct.tm_year + 1900; |
80 exploded->month = timestruct.tm_mon + 1; | 100 exploded->month = timestruct.tm_mon + 1; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 | 157 |
138 return TimeTicks(absolute_micro); | 158 return TimeTicks(absolute_micro); |
139 } | 159 } |
140 | 160 |
141 // static | 161 // static |
142 TimeTicks TimeTicks::HighResNow() { | 162 TimeTicks TimeTicks::HighResNow() { |
143 return Now(); | 163 return Now(); |
144 } | 164 } |
145 | 165 |
146 } // namespace base | 166 } // namespace base |
OLD | NEW |