Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/time.h" | 5 #include "base/time/time.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <sys/time.h> | 8 #include <sys/time.h> |
| 9 #include <time.h> | 9 #include <time.h> |
| 10 #if defined(OS_ANDROID) && !defined(__LP64__) | 10 #if defined(OS_ANDROID) && !defined(__LP64__) |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 milliseconds = min_seconds * kMillisecondsPerSecond; | 294 milliseconds = min_seconds * kMillisecondsPerSecond; |
| 295 } else { | 295 } else { |
| 296 milliseconds = max_seconds * kMillisecondsPerSecond; | 296 milliseconds = max_seconds * kMillisecondsPerSecond; |
| 297 milliseconds += (kMillisecondsPerSecond - 1); | 297 milliseconds += (kMillisecondsPerSecond - 1); |
| 298 } | 298 } |
| 299 } else { | 299 } else { |
| 300 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; | 300 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; |
| 301 } | 301 } |
| 302 | 302 |
| 303 // Adjust from Unix (1970) to Windows (1601) epoch. | 303 // Adjust from Unix (1970) to Windows (1601) epoch. |
| 304 return Time((milliseconds * kMicrosecondsPerMillisecond) + | 304 base::Time t_time = Time((milliseconds * kMicrosecondsPerMillisecond) + |
| 305 kWindowsEpochDeltaMicroseconds); | 305 kWindowsEpochDeltaMicroseconds); |
|
mmenke
2016/05/20 19:44:57
Again, suggest just calling this |time|, unless th
maksims (do not use this acc)
2016/05/24 09:14:21
Done.
| |
| 306 // If |exploded.day_of_month| is set to 31 | |
| 307 // on a 28-30 day month, it will return the first day of the next month. | |
| 308 // Thus round-trip the time and compare the initial |exploded| with | |
| 309 // |utc_to_exploded| time. | |
| 310 base::Time::Exploded to_exploded; | |
| 311 if (!is_local) | |
| 312 t_time.UTCExplode(&to_exploded); | |
| 313 else | |
| 314 t_time.LocalExplode(&to_exploded); | |
| 315 | |
| 316 // If time is null, return false | |
| 317 // which means time conversion failed | |
| 318 return to_exploded != exploded ? Time(0) : t_time; | |
|
mmenke
2016/05/20 19:44:57
nit: Fix indent. You can automatically format ev
maksims (do not use this acc)
2016/05/24 09:14:21
Done.
| |
| 319 } | |
| 320 | |
| 321 // static | |
| 322 bool Time::FromExploded(bool is_local, const Exploded& exploded, Time& time) { | |
| 323 struct tm timestruct; | |
| 324 timestruct.tm_sec = exploded.second; | |
| 325 timestruct.tm_min = exploded.minute; | |
| 326 timestruct.tm_hour = exploded.hour; | |
| 327 timestruct.tm_mday = exploded.day_of_month; | |
| 328 timestruct.tm_mon = exploded.month - 1; | |
| 329 timestruct.tm_year = exploded.year - 1900; | |
| 330 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this | |
| 331 timestruct.tm_yday = 0; // mktime/timegm ignore this | |
| 332 timestruct.tm_isdst = -1; // attempt to figure it out | |
| 333 #if !defined(OS_NACL) && !defined(OS_SOLARIS) | |
| 334 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore | |
| 335 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore | |
| 336 #endif | |
| 337 | |
| 338 int64_t milliseconds; | |
| 339 SysTime seconds; | |
| 340 | |
| 341 // Certain exploded dates do not really exist due to daylight saving times, | |
| 342 // and this causes mktime() to return implementation-defined values when | |
| 343 // tm_isdst is set to -1. On Android, the function will return -1, while the | |
| 344 // C libraries of other platforms typically return a liberally-chosen value. | |
| 345 // Handling this requires the special code below. | |
| 346 | |
| 347 // SysTimeFromTimeStruct() modifies the input structure, save current value. | |
| 348 struct tm timestruct0 = timestruct; | |
| 349 | |
| 350 seconds = SysTimeFromTimeStruct(×truct, is_local); | |
| 351 if (seconds == -1) { | |
| 352 // Get the time values with tm_isdst == 0 and 1, then select the closest one | |
| 353 // to UTC 00:00:00 that isn't -1. | |
| 354 timestruct = timestruct0; | |
| 355 timestruct.tm_isdst = 0; | |
| 356 int64_t seconds_isdst0 = SysTimeFromTimeStruct(×truct, is_local); | |
| 357 | |
| 358 timestruct = timestruct0; | |
| 359 timestruct.tm_isdst = 1; | |
| 360 int64_t seconds_isdst1 = SysTimeFromTimeStruct(×truct, is_local); | |
| 361 | |
| 362 // seconds_isdst0 or seconds_isdst1 can be -1 for some timezones. | |
| 363 // E.g. "CLST" (Chile Summer Time) returns -1 for 'tm_isdt == 1'. | |
| 364 if (seconds_isdst0 < 0) | |
| 365 seconds = seconds_isdst1; | |
| 366 else if (seconds_isdst1 < 0) | |
| 367 seconds = seconds_isdst0; | |
| 368 else | |
| 369 seconds = std::min(seconds_isdst0, seconds_isdst1); | |
| 370 } | |
| 371 | |
| 372 // Handle overflow. Clamping the range to what mktime and timegm might | |
| 373 // return is the best that can be done here. It's not ideal, but it's better | |
| 374 // than failing here or ignoring the overflow case and treating each time | |
| 375 // overflow as one second prior to the epoch. | |
| 376 if (seconds == -1 && | |
| 377 (exploded.year < 1969 || exploded.year > 1970)) { | |
| 378 // If exploded.year is 1969 or 1970, take -1 as correct, with the | |
| 379 // time indicating 1 second prior to the epoch. (1970 is allowed to handle | |
| 380 // time zone and DST offsets.) Otherwise, return the most future or past | |
| 381 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. | |
| 382 // | |
| 383 // The minimum and maximum representible times that mktime and timegm could | |
| 384 // return are used here instead of values outside that range to allow for | |
| 385 // proper round-tripping between exploded and counter-type time | |
| 386 // representations in the presence of possible truncation to time_t by | |
| 387 // division and use with other functions that accept time_t. | |
| 388 // | |
| 389 // When representing the most distant time in the future, add in an extra | |
| 390 // 999ms to avoid the time being less than any other possible value that | |
| 391 // this function can return. | |
| 392 | |
| 393 // On Android, SysTime is int64_t, special care must be taken to avoid | |
| 394 // overflows. | |
| 395 const int64_t min_seconds = (sizeof(SysTime) < sizeof(int64_t)) | |
| 396 ? std::numeric_limits<SysTime>::min() | |
| 397 : std::numeric_limits<int32_t>::min(); | |
| 398 const int64_t max_seconds = (sizeof(SysTime) < sizeof(int64_t)) | |
| 399 ? std::numeric_limits<SysTime>::max() | |
| 400 : std::numeric_limits<int32_t>::max(); | |
| 401 if (exploded.year < 1969) { | |
| 402 milliseconds = min_seconds * kMillisecondsPerSecond; | |
| 403 } else { | |
| 404 milliseconds = max_seconds * kMillisecondsPerSecond; | |
| 405 milliseconds += (kMillisecondsPerSecond - 1); | |
| 406 } | |
| 407 } else { | |
| 408 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; | |
| 409 } | |
| 410 | |
| 411 // Adjust from Unix (1970) to Windows (1601) epoch. | |
| 412 base::Time t_time = Time((milliseconds * kMicrosecondsPerMillisecond) + | |
| 413 kWindowsEpochDeltaMicroseconds); | |
| 414 // If |exploded.day_of_month| is set to 31 | |
| 415 // on a 28-30 day month, it will return the first day of the next month. | |
| 416 // Thus round-trip the time and compare the initial |exploded| with | |
| 417 // |utc_to_exploded| time. | |
| 418 base::Time::Exploded to_exploded; | |
| 419 if (!is_local) | |
| 420 t_time.UTCExplode(&to_exploded); | |
| 421 else | |
| 422 t_time.LocalExplode(&to_exploded); | |
| 423 | |
| 424 time = to_exploded != exploded ? Time(0) : t_time; | |
| 425 | |
| 426 // If time is null, return false | |
| 427 // which means time conversion failed | |
| 428 return time.is_null() ? false : true; | |
| 306 } | 429 } |
| 307 | 430 |
| 308 // TimeTicks ------------------------------------------------------------------ | 431 // TimeTicks ------------------------------------------------------------------ |
| 309 // static | 432 // static |
| 310 TimeTicks TimeTicks::Now() { | 433 TimeTicks TimeTicks::Now() { |
| 311 return TimeTicks(ClockNow(CLOCK_MONOTONIC)); | 434 return TimeTicks(ClockNow(CLOCK_MONOTONIC)); |
| 312 } | 435 } |
| 313 | 436 |
| 314 // static | 437 // static |
| 315 TimeTicks::Clock TimeTicks::GetClock() { | 438 TimeTicks::Clock TimeTicks::GetClock() { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; | 482 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; |
| 360 return result; | 483 return result; |
| 361 } | 484 } |
| 362 int64_t us = us_ - kTimeTToMicrosecondsOffset; | 485 int64_t us = us_ - kTimeTToMicrosecondsOffset; |
| 363 result.tv_sec = us / Time::kMicrosecondsPerSecond; | 486 result.tv_sec = us / Time::kMicrosecondsPerSecond; |
| 364 result.tv_usec = us % Time::kMicrosecondsPerSecond; | 487 result.tv_usec = us % Time::kMicrosecondsPerSecond; |
| 365 return result; | 488 return result; |
| 366 } | 489 } |
| 367 | 490 |
| 368 } // namespace base | 491 } // namespace base |
| OLD | NEW |