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__) |
11 #include <time64.h> | 11 #include <time64.h> |
12 #endif | 12 #endif |
13 #include <unistd.h> | 13 #include <unistd.h> |
14 | 14 |
15 #include <limits> | 15 #include <limits> |
16 #include <ostream> | 16 #include <ostream> |
17 | 17 |
18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/numerics/safe_math.h" |
19 #include "build/build_config.h" | 20 #include "build/build_config.h" |
20 | 21 |
21 #if defined(OS_ANDROID) | 22 #if defined(OS_ANDROID) |
22 #include "base/os_compat_android.h" | 23 #include "base/os_compat_android.h" |
23 #elif defined(OS_NACL) | 24 #elif defined(OS_NACL) |
24 #include "base/os_compat_nacl.h" | 25 #include "base/os_compat_nacl.h" |
25 #endif | 26 #endif |
26 | 27 |
27 #if !defined(OS_MACOSX) | 28 #if !defined(OS_MACOSX) |
28 #include "base/lazy_instance.h" | 29 #include "base/lazy_instance.h" |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 exploded->day_of_week = timestruct.tm_wday; | 221 exploded->day_of_week = timestruct.tm_wday; |
221 exploded->day_of_month = timestruct.tm_mday; | 222 exploded->day_of_month = timestruct.tm_mday; |
222 exploded->hour = timestruct.tm_hour; | 223 exploded->hour = timestruct.tm_hour; |
223 exploded->minute = timestruct.tm_min; | 224 exploded->minute = timestruct.tm_min; |
224 exploded->second = timestruct.tm_sec; | 225 exploded->second = timestruct.tm_sec; |
225 exploded->millisecond = millisecond; | 226 exploded->millisecond = millisecond; |
226 } | 227 } |
227 | 228 |
228 // static | 229 // static |
229 bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) { | 230 bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) { |
| 231 CheckedNumeric<int> month = exploded.month; |
| 232 month--; |
| 233 CheckedNumeric<int> year = exploded.year; |
| 234 year -= 1900; |
| 235 if (!month.IsValid() || !year.IsValid()) { |
| 236 *time = Time(0); |
| 237 return false; |
| 238 } |
| 239 |
230 struct tm timestruct; | 240 struct tm timestruct; |
231 timestruct.tm_sec = exploded.second; | 241 timestruct.tm_sec = exploded.second; |
232 timestruct.tm_min = exploded.minute; | 242 timestruct.tm_min = exploded.minute; |
233 timestruct.tm_hour = exploded.hour; | 243 timestruct.tm_hour = exploded.hour; |
234 timestruct.tm_mday = exploded.day_of_month; | 244 timestruct.tm_mday = exploded.day_of_month; |
235 timestruct.tm_mon = exploded.month - 1; | 245 timestruct.tm_mon = month.ValueOrDie(); |
236 timestruct.tm_year = exploded.year - 1900; | 246 timestruct.tm_year = year.ValueOrDie(); |
237 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this | 247 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this |
238 timestruct.tm_yday = 0; // mktime/timegm ignore this | 248 timestruct.tm_yday = 0; // mktime/timegm ignore this |
239 timestruct.tm_isdst = -1; // attempt to figure it out | 249 timestruct.tm_isdst = -1; // attempt to figure it out |
240 #if !defined(OS_NACL) && !defined(OS_SOLARIS) | 250 #if !defined(OS_NACL) && !defined(OS_SOLARIS) |
241 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore | 251 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore |
242 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore | 252 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore |
243 #endif | 253 #endif |
244 | 254 |
245 SysTime seconds; | 255 SysTime seconds; |
246 | 256 |
247 // Certain exploded dates do not really exist due to daylight saving times, | 257 // Certain exploded dates do not really exist due to daylight saving times, |
248 // and this causes mktime() to return implementation-defined values when | 258 // and this causes mktime() to return implementation-defined values when |
249 // tm_isdst is set to -1. On Android, the function will return -1, while the | 259 // tm_isdst is set to -1. On Android, the function will return -1, while the |
250 // C libraries of other platforms typically return a liberally-chosen value. | 260 // C libraries of other platforms typically return a liberally-chosen value. |
251 // Handling this requires the special code below. | 261 // Handling this requires the special code below. |
252 | 262 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; | 419 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; |
410 return result; | 420 return result; |
411 } | 421 } |
412 int64_t us = us_ - kTimeTToMicrosecondsOffset; | 422 int64_t us = us_ - kTimeTToMicrosecondsOffset; |
413 result.tv_sec = us / Time::kMicrosecondsPerSecond; | 423 result.tv_sec = us / Time::kMicrosecondsPerSecond; |
414 result.tv_usec = us % Time::kMicrosecondsPerSecond; | 424 result.tv_usec = us % Time::kMicrosecondsPerSecond; |
415 return result; | 425 return result; |
416 } | 426 } |
417 | 427 |
418 } // namespace base | 428 } // namespace base |
OLD | NEW |