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. 4 5 #include "base/time/time.h" 6 7 #include <stdint.h> 8 #include <sys/time.h> 9 #include <time.h> 10 #if defined(OS_ANDROID) 11 #include <time64.h> 12 #endif 13 #include <unistd.h> 14 15 #include <limits> 16 #include <ostream> 17 18 #include "base/basictypes.h" 19 #include "base/logging.h" 20 #include "base/port.h" 21 #include "build/build_config.h" 22 23 #if defined(OS_ANDROID) 24 #include "base/os_compat_android.h" 25 #elif defined(OS_NACL) 26 #include "base/os_compat_nacl.h" 27 #endif 28 29 namespace { 30 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) 36 typedef time64_t SysTime; 37 38 SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { 39 if (is_local) 40 return mktime64(timestruct); 41 else 42 return timegm64(timestruct); 43 } 44 45 void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { 46 if (is_local) 47 localtime64_r(&t, timestruct); 48 else 49 gmtime64_r(&t, timestruct); 50 } 51 52 #else // OS_ANDROID 53 typedef time_t SysTime; 54 55 SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { 56 if (is_local) 57 return mktime(timestruct); 58 else 59 return timegm(timestruct); 60 } 61 62 void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { 63 if (is_local) 64 localtime_r(&t, timestruct); 65 else 66 gmtime_r(&t, timestruct); 67 } 68 #endif // OS_ANDROID 69 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; 78 79 struct timespec ts; 80 if (clock_gettime(clk_id, &ts) != 0) { 81 NOTREACHED() << "clock_gettime(" << clk_id << ") failed."; 82 return base::TimeTicks(); 83 } 84 85 absolute_micro = 86 (static_cast<int64>(ts.tv_sec) * base::Time::kMicrosecondsPerSecond) + 87 (static_cast<int64>(ts.tv_nsec) / base::Time::kNanosecondsPerMicrosecond); 88 89 return base::TimeTicks::FromInternalValue(absolute_micro); 90 } 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) 95 96 } // namespace 97 98 namespace base { 99 100 struct timespec TimeDelta::ToTimeSpec() const { 101 int64 microseconds = InMicroseconds(); 102 time_t seconds = 0; 103 if (microseconds >= Time::kMicrosecondsPerSecond) { 104 seconds = InSeconds(); 105 microseconds -= seconds * Time::kMicrosecondsPerSecond; 106 } 107 struct timespec result = 108 {seconds, 109 static_cast<long>(microseconds * Time::kNanosecondsPerMicrosecond)}; 110 return result; 111 } 112 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. 117 118 // Time ----------------------------------------------------------------------- 119 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); 127 128 // static 129 const int64 Time::kWindowsEpochDeltaMicroseconds = 130 kWindowsEpochDeltaSeconds * Time::kMicrosecondsPerSecond; 131 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). 134 // static 135 const int64 Time::kTimeTToMicrosecondsOffset = kWindowsEpochDeltaMicroseconds; 136 137 // static 138 Time Time::Now() { 139 struct timeval tv; 140 struct timezone tz = { 0, 0 }; // UTC 141 if (gettimeofday(&tv, &tz) != 0) { 142 DCHECK(0) << "Could not determine time of day"; 143 LOG_ERRNO(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. 146 return Time(); 147 } 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); 153 } 154 155 // static 156 Time Time::NowFromSystemTime() { 157 // Just use Now() because Now() returns the system time. 158 return Now(); 159 } 160 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; 175 } else { 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; 183 if (millisecond < 0) 184 millisecond += kMillisecondsPerSecond; 185 } 186 187 struct tm timestruct; 188 SysTimeToTimeStruct(seconds, ×truct, is_local); 189 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; 198 } 199 200 // static 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 215 #endif 216 217 218 int64 milliseconds; 219 SysTime seconds; 220 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. 226 227 // SysTimeFromTimeStruct() modifies the input structure, save current value. 228 struct tm timestruct0 = timestruct; 229 230 seconds = SysTimeFromTimeStruct(×truct, is_local); 231 if (seconds == -1) { 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); 237 238 timestruct = timestruct0; 239 timestruct.tm_isdst = 1; 240 int64 seconds_isdst1 = SysTimeFromTimeStruct(×truct, is_local); 241 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; 248 else 249 seconds = std::min(seconds_isdst0, seconds_isdst1); 250 } 251 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. 256 if (seconds == -1 && 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. 262 // 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. 268 // 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. 272 273 // On Android, SysTime is int64, special care must be taken to avoid 274 // overflows. 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; 283 } else { 284 milliseconds = max_seconds * kMillisecondsPerSecond; 285 milliseconds += (kMillisecondsPerSecond - 1); 286 } 287 } else { 288 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; 289 } 290 291 // Adjust from Unix (1970) to Windows (1601) epoch. 292 return Time((milliseconds * kMicrosecondsPerMillisecond) + 293 kWindowsEpochDeltaMicroseconds); 294 } 295 296 // TimeTicks ------------------------------------------------------------------ 297 // static 298 TimeTicks TimeTicks::Now() { 299 return ClockNow(CLOCK_MONOTONIC); 300 } 301 302 // static 303 TimeTicks TimeTicks::HighResNow() { 304 return Now(); 305 } 306 307 // static 308 bool TimeTicks::IsHighResNowFastAndReliable() { 309 return true; 310 } 311 312 // static 313 TimeTicks TimeTicks::ThreadNow() { 314 #if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \ 315 defined(OS_ANDROID) 316 return ClockNow(CLOCK_THREAD_CPUTIME_ID); 317 #else 318 NOTREACHED(); 319 return TimeTicks(); 320 #endif 321 } 322 323 #if defined(OS_CHROMEOS) 324 // Force definition of the system trace clock; it is a chromeos-only api 325 // at the moment and surfacing it in the right place requires mucking 326 // with glibc et al. 327 #define CLOCK_SYSTEM_TRACE 11 328 329 // static 330 TimeTicks TimeTicks::NowFromSystemTraceTime() { 331 uint64_t absolute_micro; 332 333 struct timespec ts; 334 if (clock_gettime(CLOCK_SYSTEM_TRACE, &ts) != 0) { 335 // NB: fall-back for a chrome os build running on linux 336 return HighResNow(); 337 } 338 339 absolute_micro = 340 (static_cast<int64>(ts.tv_sec) * Time::kMicrosecondsPerSecond) + 341 (static_cast<int64>(ts.tv_nsec) / Time::kNanosecondsPerMicrosecond); 342 343 return TimeTicks(absolute_micro); 344 } 345 346 #else // !defined(OS_CHROMEOS) 347 348 // static 349 TimeTicks TimeTicks::NowFromSystemTraceTime() { 350 return HighResNow(); 351 } 352 353 #endif // defined(OS_CHROMEOS) 354 355 #endif // !OS_MACOSX 356 357 // static 358 Time Time::FromTimeVal(struct timeval t) { 359 DCHECK_LT(t.tv_usec, static_cast<int>(Time::kMicrosecondsPerSecond)); 360 DCHECK_GE(t.tv_usec, 0); 361 if (t.tv_usec == 0 && t.tv_sec == 0) 362 return Time(); 363 if (t.tv_usec == static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1 && 364 t.tv_sec == std::numeric_limits<time_t>::max()) 365 return Max(); 366 return Time( 367 (static_cast<int64>(t.tv_sec) * Time::kMicrosecondsPerSecond) + 368 t.tv_usec + 369 kTimeTToMicrosecondsOffset); 370 } 371 372 struct timeval Time::ToTimeVal() const { 373 struct timeval result; 374 if (is_null()) { 375 result.tv_sec = 0; 376 result.tv_usec = 0; 377 return result; 378 } 379 if (is_max()) { 380 result.tv_sec = std::numeric_limits<time_t>::max(); 381 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; 382 return result; 383 } 384 int64 us = us_ - kTimeTToMicrosecondsOffset; 385 result.tv_sec = us / Time::kMicrosecondsPerSecond; 386 result.tv_usec = us % Time::kMicrosecondsPerSecond; 387 return result; 388 } 389 390 } // namespace base 391