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.
13 #include "base/basictypes.h"
14 #include "base/logging.h"
16 #if defined(OS_ANDROID)
17 #include "base/os_compat_android.h"
18 #elif defined(OS_NACL)
19 #include "base/os_compat_nacl.h"
24 #if defined(OS_ANDROID)
25 #define _POSIX_MONOTONIC_CLOCK 1
28 struct timespec
TimeDelta::ToTimeSpec() const {
29 int64 microseconds
= InMicroseconds();
31 if (microseconds
>= Time::kMicrosecondsPerSecond
) {
32 seconds
= InSeconds();
33 microseconds
-= seconds
* Time::kMicrosecondsPerSecond
;
35 struct timespec result
=
37 static_cast<long>(microseconds
* Time::kNanosecondsPerMicrosecond
)};
41 #if !defined(OS_MACOSX)
42 // The Time routines in this file use standard POSIX routines, or almost-
43 // standard routines in the case of timegm. We need to use a Mach-specific
44 // function for TimeTicks::Now() on Mac OS X.
46 // Time -----------------------------------------------------------------------
48 // Windows uses a Gregorian epoch of 1601. We need to match this internally
49 // so that our time representations match across all platforms. See bug 14734.
50 // irb(main):010:0> Time.at(0).getutc()
51 // => Thu Jan 01 00:00:00 UTC 1970
52 // irb(main):011:0> Time.at(-11644473600).getutc()
53 // => Mon Jan 01 00:00:00 UTC 1601
54 static const int64 kWindowsEpochDeltaSeconds
= GG_INT64_C(11644473600);
55 static const int64 kWindowsEpochDeltaMilliseconds
=
56 kWindowsEpochDeltaSeconds
* Time::kMillisecondsPerSecond
;
59 const int64
Time::kWindowsEpochDeltaMicroseconds
=
60 kWindowsEpochDeltaSeconds
* Time::kMicrosecondsPerSecond
;
62 // Some functions in time.cc use time_t directly, so we provide an offset
63 // to convert from time_t (Unix epoch) and internal (Windows epoch).
65 const int64
Time::kTimeTToMicrosecondsOffset
= kWindowsEpochDeltaMicroseconds
;
70 struct timezone tz
= { 0, 0 }; // UTC
71 if (gettimeofday(&tv
, &tz
) != 0) {
72 DCHECK(0) << "Could not determine time of day";
74 // Combine seconds and microseconds in a 64-bit field containing microseconds
75 // since the epoch. That's enough for nearly 600 centuries. Adjust from
76 // Unix (1970) to Windows (1601) epoch.
77 return Time((tv
.tv_sec
* kMicrosecondsPerSecond
+ tv
.tv_usec
) +
78 kWindowsEpochDeltaMicroseconds
);
82 Time
Time::NowFromSystemTime() {
83 // Just use Now() because Now() returns the system time.
87 void Time::Explode(bool is_local
, Exploded
* exploded
) const {
88 // Time stores times with microsecond resolution, but Exploded only carries
89 // millisecond resolution, so begin by being lossy. Adjust from Windows
90 // epoch (1601) to Unix epoch (1970);
91 int64 microseconds
= us_
- kWindowsEpochDeltaMicroseconds
;
92 // The following values are all rounded towards -infinity.
93 int64 milliseconds
; // Milliseconds since epoch.
94 time_t seconds
; // Seconds since epoch.
95 int millisecond
; // Exploded millisecond value (0-999).
96 if (microseconds
>= 0) {
97 // Rounding towards -infinity <=> rounding towards 0, in this case.
98 milliseconds
= microseconds
/ kMicrosecondsPerMillisecond
;
99 seconds
= milliseconds
/ kMillisecondsPerSecond
;
100 millisecond
= milliseconds
% kMillisecondsPerSecond
;
102 // Round these *down* (towards -infinity).
103 milliseconds
= (microseconds
- kMicrosecondsPerMillisecond
+ 1) /
104 kMicrosecondsPerMillisecond
;
105 seconds
= (milliseconds
- kMillisecondsPerSecond
+ 1) /
106 kMillisecondsPerSecond
;
107 // Make this nonnegative (and between 0 and 999 inclusive).
108 millisecond
= milliseconds
% kMillisecondsPerSecond
;
110 millisecond
+= kMillisecondsPerSecond
;
113 struct tm timestruct
;
115 localtime_r(&seconds
, ×truct
);
117 gmtime_r(&seconds
, ×truct
);
119 exploded
->year
= timestruct
.tm_year
+ 1900;
120 exploded
->month
= timestruct
.tm_mon
+ 1;
121 exploded
->day_of_week
= timestruct
.tm_wday
;
122 exploded
->day_of_month
= timestruct
.tm_mday
;
123 exploded
->hour
= timestruct
.tm_hour
;
124 exploded
->minute
= timestruct
.tm_min
;
125 exploded
->second
= timestruct
.tm_sec
;
126 exploded
->millisecond
= millisecond
;
130 Time
Time::FromExploded(bool is_local
, const Exploded
& exploded
) {
131 struct tm timestruct
;
132 timestruct
.tm_sec
= exploded
.second
;
133 timestruct
.tm_min
= exploded
.minute
;
134 timestruct
.tm_hour
= exploded
.hour
;
135 timestruct
.tm_mday
= exploded
.day_of_month
;
136 timestruct
.tm_mon
= exploded
.month
- 1;
137 timestruct
.tm_year
= exploded
.year
- 1900;
138 timestruct
.tm_wday
= exploded
.day_of_week
; // mktime/timegm ignore this
139 timestruct
.tm_yday
= 0; // mktime/timegm ignore this
140 timestruct
.tm_isdst
= -1; // attempt to figure it out
141 #if !defined(OS_NACL) && !defined(OS_SOLARIS)
142 timestruct
.tm_gmtoff
= 0; // not a POSIX field, so mktime/timegm ignore
143 timestruct
.tm_zone
= NULL
; // not a POSIX field, so mktime/timegm ignore
148 seconds
= mktime(×truct
);
150 seconds
= timegm(×truct
);
153 // Handle overflow. Clamping the range to what mktime and timegm might
154 // return is the best that can be done here. It's not ideal, but it's better
155 // than failing here or ignoring the overflow case and treating each time
156 // overflow as one second prior to the epoch.
158 (exploded
.year
< 1969 || exploded
.year
> 1970)) {
159 // If exploded.year is 1969 or 1970, take -1 as correct, with the
160 // time indicating 1 second prior to the epoch. (1970 is allowed to handle
161 // time zone and DST offsets.) Otherwise, return the most future or past
162 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC.
164 // The minimum and maximum representible times that mktime and timegm could
165 // return are used here instead of values outside that range to allow for
166 // proper round-tripping between exploded and counter-type time
167 // representations in the presence of possible truncation to time_t by
168 // division and use with other functions that accept time_t.
170 // When representing the most distant time in the future, add in an extra
171 // 999ms to avoid the time being less than any other possible value that
172 // this function can return.
173 if (exploded
.year
< 1969) {
174 milliseconds
= std::numeric_limits
<time_t>::min() *
175 kMillisecondsPerSecond
;
177 milliseconds
= (std::numeric_limits
<time_t>::max() *
178 kMillisecondsPerSecond
) +
179 kMillisecondsPerSecond
- 1;
182 milliseconds
= seconds
* kMillisecondsPerSecond
+ exploded
.millisecond
;
185 // Adjust from Unix (1970) to Windows (1601) epoch.
186 return Time((milliseconds
* kMicrosecondsPerMillisecond
) +
187 kWindowsEpochDeltaMicroseconds
);
190 // TimeTicks ------------------------------------------------------------------
191 // FreeBSD 6 has CLOCK_MONOLITHIC but defines _POSIX_MONOTONIC_CLOCK to -1.
192 #if (defined(OS_POSIX) && !defined(OS_NACL) && \
193 defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0) || \
194 defined(OS_BSD) || defined(OS_ANDROID)
197 TimeTicks
TimeTicks::Now() {
198 uint64_t absolute_micro
;
201 if (clock_gettime(CLOCK_MONOTONIC
, &ts
) != 0) {
202 NOTREACHED() << "clock_gettime(CLOCK_MONOTONIC) failed.";
207 (static_cast<int64
>(ts
.tv_sec
) * Time::kMicrosecondsPerSecond
) +
208 (static_cast<int64
>(ts
.tv_nsec
) / Time::kNanosecondsPerMicrosecond
);
210 return TimeTicks(absolute_micro
);
213 #elif defined(OS_NACL)
215 TimeTicks
TimeTicks::Now() {
216 // Sadly, Native Client does not have _POSIX_TIMERS enabled in sys/features.h
217 // Apparently NaCl only has CLOCK_REALTIME:
218 // http://code.google.com/p/nativeclient/issues/detail?id=1159
219 return TimeTicks(clock());
222 #else // _POSIX_MONOTONIC_CLOCK
223 #error No usable tick clock function on this platform.
224 #endif // _POSIX_MONOTONIC_CLOCK
227 TimeTicks
TimeTicks::HighResNow() {
231 #if defined(OS_CHROMEOS)
232 // Force definition of the system trace clock; it is a chromeos-only api
233 // at the moment and surfacing it in the right place requires mucking
235 #define CLOCK_SYSTEM_TRACE 11
238 TimeTicks
TimeTicks::NowFromSystemTraceTime() {
239 uint64_t absolute_micro
;
242 if (clock_gettime(CLOCK_SYSTEM_TRACE
, &ts
) != 0) {
243 // NB: fall-back for a chrome os build running on linux
248 (static_cast<int64
>(ts
.tv_sec
) * Time::kMicrosecondsPerSecond
) +
249 (static_cast<int64
>(ts
.tv_nsec
) / Time::kNanosecondsPerMicrosecond
);
251 return TimeTicks(absolute_micro
);
254 #else // !defined(OS_CHROMEOS)
257 TimeTicks
TimeTicks::NowFromSystemTraceTime() {
261 #endif // defined(OS_CHROMEOS)
266 Time
Time::FromTimeVal(struct timeval t
) {
267 DCHECK_LT(t
.tv_usec
, static_cast<int>(Time::kMicrosecondsPerSecond
));
268 DCHECK_GE(t
.tv_usec
, 0);
270 (static_cast<int64
>(t
.tv_sec
) * Time::kMicrosecondsPerSecond
) +
272 kTimeTToMicrosecondsOffset
);
275 struct timeval
Time::ToTimeVal() const {
276 struct timeval result
;
277 int64 us
= us_
- kTimeTToMicrosecondsOffset
;
278 result
.tv_sec
= us
/ Time::kMicrosecondsPerSecond
;
279 result
.tv_usec
= us
% Time::kMicrosecondsPerSecond
;