1 // Copyright (c) 2012 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.
5 #include "base/time/time.h"
10 #if defined(OS_ANDROID) && !defined(__LP64__)
18 #include "base/basictypes.h"
19 #include "base/logging.h"
20 #include "base/port.h"
21 #include "build/build_config.h"
23 #if defined(OS_ANDROID)
24 #include "base/os_compat_android.h"
25 #elif defined(OS_NACL)
26 #include "base/os_compat_nacl.h"
31 #if !defined(OS_MACOSX)
32 // Define a system-specific SysTime that wraps either to a time_t or
33 // a time64_t depending on the host system, and associated convertion.
34 // See crbug.com/162007
35 #if defined(OS_ANDROID) && !defined(__LP64__)
36 typedef time64_t SysTime
;
38 SysTime
SysTimeFromTimeStruct(struct tm
* timestruct
, bool is_local
) {
40 return mktime64(timestruct
);
42 return timegm64(timestruct
);
45 void SysTimeToTimeStruct(SysTime t
, struct tm
* timestruct
, bool is_local
) {
47 localtime64_r(&t
, timestruct
);
49 gmtime64_r(&t
, timestruct
);
52 #else // OS_ANDROID && !__LP64__
53 typedef time_t SysTime
;
55 SysTime
SysTimeFromTimeStruct(struct tm
* timestruct
, bool is_local
) {
57 return mktime(timestruct
);
59 return timegm(timestruct
);
62 void SysTimeToTimeStruct(SysTime t
, struct tm
* timestruct
, bool is_local
) {
64 localtime_r(&t
, timestruct
);
66 gmtime_r(&t
, timestruct
);
70 // Helper function to get results from clock_gettime() as TimeTicks object.
71 // Minimum requirement is MONOTONIC_CLOCK to be supported on the system.
72 // FreeBSD 6 has CLOCK_MONOTONIC but defines _POSIX_MONOTONIC_CLOCK to -1.
73 #if (defined(OS_POSIX) && \
74 defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0) || \
75 defined(OS_BSD) || defined(OS_ANDROID)
76 base::TimeTicks
ClockNow(clockid_t clk_id
) {
77 uint64_t absolute_micro
;
80 if (clock_gettime(clk_id
, &ts
) != 0) {
81 NOTREACHED() << "clock_gettime(" << clk_id
<< ") failed.";
82 return base::TimeTicks();
86 (static_cast<int64
>(ts
.tv_sec
) * base::Time::kMicrosecondsPerSecond
) +
87 (static_cast<int64
>(ts
.tv_nsec
) / base::Time::kNanosecondsPerMicrosecond
);
89 return base::TimeTicks::FromInternalValue(absolute_micro
);
91 #else // _POSIX_MONOTONIC_CLOCK
92 #error No usable tick clock function on this platform.
93 #endif // _POSIX_MONOTONIC_CLOCK
94 #endif // !defined(OS_MACOSX)
100 struct timespec
TimeDelta::ToTimeSpec() const {
101 int64 microseconds
= InMicroseconds();
103 if (microseconds
>= Time::kMicrosecondsPerSecond
) {
104 seconds
= InSeconds();
105 microseconds
-= seconds
* Time::kMicrosecondsPerSecond
;
107 struct timespec result
=
109 static_cast<long>(microseconds
* Time::kNanosecondsPerMicrosecond
)};
113 #if !defined(OS_MACOSX)
114 // The Time routines in this file use standard POSIX routines, or almost-
115 // standard routines in the case of timegm. We need to use a Mach-specific
116 // function for TimeTicks::Now() on Mac OS X.
118 // Time -----------------------------------------------------------------------
120 // Windows uses a Gregorian epoch of 1601. We need to match this internally
121 // so that our time representations match across all platforms. See bug 14734.
122 // irb(main):010:0> Time.at(0).getutc()
123 // => Thu Jan 01 00:00:00 UTC 1970
124 // irb(main):011:0> Time.at(-11644473600).getutc()
125 // => Mon Jan 01 00:00:00 UTC 1601
126 static const int64 kWindowsEpochDeltaSeconds
= GG_INT64_C(11644473600);
129 const int64
Time::kWindowsEpochDeltaMicroseconds
=
130 kWindowsEpochDeltaSeconds
* Time::kMicrosecondsPerSecond
;
132 // Some functions in time.cc use time_t directly, so we provide an offset
133 // to convert from time_t (Unix epoch) and internal (Windows epoch).
135 const int64
Time::kTimeTToMicrosecondsOffset
= kWindowsEpochDeltaMicroseconds
;
140 struct timezone tz
= { 0, 0 }; // UTC
141 if (gettimeofday(&tv
, &tz
) != 0) {
142 DCHECK(0) << "Could not determine time of day";
143 PLOG(ERROR
) << "Call to gettimeofday failed.";
144 // Return null instead of uninitialized |tv| value, which contains random
145 // garbage data. This may result in the crash seen in crbug.com/147570.
148 // Combine seconds and microseconds in a 64-bit field containing microseconds
149 // since the epoch. That's enough for nearly 600 centuries. Adjust from
150 // Unix (1970) to Windows (1601) epoch.
151 return Time((tv
.tv_sec
* kMicrosecondsPerSecond
+ tv
.tv_usec
) +
152 kWindowsEpochDeltaMicroseconds
);
156 Time
Time::NowFromSystemTime() {
157 // Just use Now() because Now() returns the system time.
161 void Time::Explode(bool is_local
, Exploded
* exploded
) const {
162 // Time stores times with microsecond resolution, but Exploded only carries
163 // millisecond resolution, so begin by being lossy. Adjust from Windows
164 // epoch (1601) to Unix epoch (1970);
165 int64 microseconds
= us_
- kWindowsEpochDeltaMicroseconds
;
166 // The following values are all rounded towards -infinity.
167 int64 milliseconds
; // Milliseconds since epoch.
168 SysTime seconds
; // Seconds since epoch.
169 int millisecond
; // Exploded millisecond value (0-999).
170 if (microseconds
>= 0) {
171 // Rounding towards -infinity <=> rounding towards 0, in this case.
172 milliseconds
= microseconds
/ kMicrosecondsPerMillisecond
;
173 seconds
= milliseconds
/ kMillisecondsPerSecond
;
174 millisecond
= milliseconds
% kMillisecondsPerSecond
;
176 // Round these *down* (towards -infinity).
177 milliseconds
= (microseconds
- kMicrosecondsPerMillisecond
+ 1) /
178 kMicrosecondsPerMillisecond
;
179 seconds
= (milliseconds
- kMillisecondsPerSecond
+ 1) /
180 kMillisecondsPerSecond
;
181 // Make this nonnegative (and between 0 and 999 inclusive).
182 millisecond
= milliseconds
% kMillisecondsPerSecond
;
184 millisecond
+= kMillisecondsPerSecond
;
187 struct tm timestruct
;
188 SysTimeToTimeStruct(seconds
, ×truct
, is_local
);
190 exploded
->year
= timestruct
.tm_year
+ 1900;
191 exploded
->month
= timestruct
.tm_mon
+ 1;
192 exploded
->day_of_week
= timestruct
.tm_wday
;
193 exploded
->day_of_month
= timestruct
.tm_mday
;
194 exploded
->hour
= timestruct
.tm_hour
;
195 exploded
->minute
= timestruct
.tm_min
;
196 exploded
->second
= timestruct
.tm_sec
;
197 exploded
->millisecond
= millisecond
;
201 Time
Time::FromExploded(bool is_local
, const Exploded
& exploded
) {
202 struct tm timestruct
;
203 timestruct
.tm_sec
= exploded
.second
;
204 timestruct
.tm_min
= exploded
.minute
;
205 timestruct
.tm_hour
= exploded
.hour
;
206 timestruct
.tm_mday
= exploded
.day_of_month
;
207 timestruct
.tm_mon
= exploded
.month
- 1;
208 timestruct
.tm_year
= exploded
.year
- 1900;
209 timestruct
.tm_wday
= exploded
.day_of_week
; // mktime/timegm ignore this
210 timestruct
.tm_yday
= 0; // mktime/timegm ignore this
211 timestruct
.tm_isdst
= -1; // attempt to figure it out
212 #if !defined(OS_NACL) && !defined(OS_SOLARIS)
213 timestruct
.tm_gmtoff
= 0; // not a POSIX field, so mktime/timegm ignore
214 timestruct
.tm_zone
= NULL
; // not a POSIX field, so mktime/timegm ignore
221 // Certain exploded dates do not really exist due to daylight saving times,
222 // and this causes mktime() to return implementation-defined values when
223 // tm_isdst is set to -1. On Android, the function will return -1, while the
224 // C libraries of other platforms typically return a liberally-chosen value.
225 // Handling this requires the special code below.
227 // SysTimeFromTimeStruct() modifies the input structure, save current value.
228 struct tm timestruct0
= timestruct
;
230 seconds
= SysTimeFromTimeStruct(×truct
, is_local
);
232 // Get the time values with tm_isdst == 0 and 1, then select the closest one
233 // to UTC 00:00:00 that isn't -1.
234 timestruct
= timestruct0
;
235 timestruct
.tm_isdst
= 0;
236 int64 seconds_isdst0
= SysTimeFromTimeStruct(×truct
, is_local
);
238 timestruct
= timestruct0
;
239 timestruct
.tm_isdst
= 1;
240 int64 seconds_isdst1
= SysTimeFromTimeStruct(×truct
, is_local
);
242 // seconds_isdst0 or seconds_isdst1 can be -1 for some timezones.
243 // E.g. "CLST" (Chile Summer Time) returns -1 for 'tm_isdt == 1'.
244 if (seconds_isdst0
< 0)
245 seconds
= seconds_isdst1
;
246 else if (seconds_isdst1
< 0)
247 seconds
= seconds_isdst0
;
249 seconds
= std::min(seconds_isdst0
, seconds_isdst1
);
252 // Handle overflow. Clamping the range to what mktime and timegm might
253 // return is the best that can be done here. It's not ideal, but it's better
254 // than failing here or ignoring the overflow case and treating each time
255 // overflow as one second prior to the epoch.
257 (exploded
.year
< 1969 || exploded
.year
> 1970)) {
258 // If exploded.year is 1969 or 1970, take -1 as correct, with the
259 // time indicating 1 second prior to the epoch. (1970 is allowed to handle
260 // time zone and DST offsets.) Otherwise, return the most future or past
261 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC.
263 // The minimum and maximum representible times that mktime and timegm could
264 // return are used here instead of values outside that range to allow for
265 // proper round-tripping between exploded and counter-type time
266 // representations in the presence of possible truncation to time_t by
267 // division and use with other functions that accept time_t.
269 // When representing the most distant time in the future, add in an extra
270 // 999ms to avoid the time being less than any other possible value that
271 // this function can return.
273 // On Android, SysTime is int64, special care must be taken to avoid
275 const int64 min_seconds
= (sizeof(SysTime
) < sizeof(int64
))
276 ? std::numeric_limits
<SysTime
>::min()
277 : std::numeric_limits
<int32_t>::min();
278 const int64 max_seconds
= (sizeof(SysTime
) < sizeof(int64
))
279 ? std::numeric_limits
<SysTime
>::max()
280 : std::numeric_limits
<int32_t>::max();
281 if (exploded
.year
< 1969) {
282 milliseconds
= min_seconds
* kMillisecondsPerSecond
;
284 milliseconds
= max_seconds
* kMillisecondsPerSecond
;
285 milliseconds
+= (kMillisecondsPerSecond
- 1);
288 milliseconds
= seconds
* kMillisecondsPerSecond
+ exploded
.millisecond
;
291 // Adjust from Unix (1970) to Windows (1601) epoch.
292 return Time((milliseconds
* kMicrosecondsPerMillisecond
) +
293 kWindowsEpochDeltaMicroseconds
);
296 // TimeTicks ------------------------------------------------------------------
298 TimeTicks
TimeTicks::Now() {
299 return ClockNow(CLOCK_MONOTONIC
);
303 TimeTicks
TimeTicks::HighResNow() {
308 bool TimeTicks::IsHighResNowFastAndReliable() {
313 TimeTicks
TimeTicks::ThreadNow() {
314 #if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \
316 return ClockNow(CLOCK_THREAD_CPUTIME_ID
);
323 // NaCl IRT does not support the Chrome OS specific clock
324 // ID. build/common.gypi sets OS_CHROMEOS without any other OS_*
325 // macros for untrusted NaCl build so we need to check
326 // __native_client__ explicitly.
327 // TODO(hamaji): Do not specify OS_CHROMEOS for untrusted NaCl build
328 // and remove !defined(__native_client__).
329 #if defined(OS_CHROMEOS) && !defined(__native_client__)
331 TimeTicks
TimeTicks::NowFromSystemTraceTime() {
332 uint64_t absolute_micro
;
335 if (clock_gettime(kClockSystemTrace
, &ts
) != 0) {
336 // NB: fall-back for a chrome os build running on linux
341 (static_cast<int64
>(ts
.tv_sec
) * Time::kMicrosecondsPerSecond
) +
342 (static_cast<int64
>(ts
.tv_nsec
) / Time::kNanosecondsPerMicrosecond
);
344 return TimeTicks(absolute_micro
);
347 #else // !(defined(OS_CHROMEOS) && !defined(__native_client__))
350 TimeTicks
TimeTicks::NowFromSystemTraceTime() {
354 #endif // defined(OS_CHROMEOS) && !defined(__native_client__)
359 Time
Time::FromTimeVal(struct timeval t
) {
360 DCHECK_LT(t
.tv_usec
, static_cast<int>(Time::kMicrosecondsPerSecond
));
361 DCHECK_GE(t
.tv_usec
, 0);
362 if (t
.tv_usec
== 0 && t
.tv_sec
== 0)
364 if (t
.tv_usec
== static_cast<suseconds_t
>(Time::kMicrosecondsPerSecond
) - 1 &&
365 t
.tv_sec
== std::numeric_limits
<time_t>::max())
368 (static_cast<int64
>(t
.tv_sec
) * Time::kMicrosecondsPerSecond
) +
370 kTimeTToMicrosecondsOffset
);
373 struct timeval
Time::ToTimeVal() const {
374 struct timeval result
;
381 result
.tv_sec
= std::numeric_limits
<time_t>::max();
382 result
.tv_usec
= static_cast<suseconds_t
>(Time::kMicrosecondsPerSecond
) - 1;
385 int64 us
= us_
- kTimeTToMicrosecondsOffset
;
386 result
.tv_sec
= us
/ Time::kMicrosecondsPerSecond
;
387 result
.tv_usec
= us
% Time::kMicrosecondsPerSecond
;