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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 struct timespec ts; | 106 struct timespec ts; |
107 if (clock_gettime(clk_id, &ts) != 0) { | 107 if (clock_gettime(clk_id, &ts) != 0) { |
108 NOTREACHED() << "clock_gettime(" << clk_id << ") failed."; | 108 NOTREACHED() << "clock_gettime(" << clk_id << ") failed."; |
109 return 0; | 109 return 0; |
110 } | 110 } |
111 return ConvertTimespecToMicros(ts); | 111 return ConvertTimespecToMicros(ts); |
112 } | 112 } |
113 #else // _POSIX_MONOTONIC_CLOCK | 113 #else // _POSIX_MONOTONIC_CLOCK |
114 #error No usable tick clock function on this platform. | 114 #error No usable tick clock function on this platform. |
115 #endif // _POSIX_MONOTONIC_CLOCK | 115 #endif // _POSIX_MONOTONIC_CLOCK |
116 | |
117 // Safely multiplies |init_value| by |multiply_value| and adds |add_value| | |
118 // to that. Returns result or 0 value avoiding overflows. | |
119 int64_t MultiplyAndAdd(int64_t init_value, | |
miu
2016/10/18 19:55:13
This helper hides whether overflow occurs (i.e., i
maksims (do not use this acc)
2016/10/19 16:41:04
Removed
| |
120 int64_t multiply_value, | |
121 int64_t add_value) { | |
122 base::CheckedNumeric<int64_t> result(init_value); | |
123 result *= multiply_value; | |
124 result += add_value; | |
125 return result.ValueOrDefault(0); | |
126 } | |
127 | |
116 #endif // !defined(OS_MACOSX) | 128 #endif // !defined(OS_MACOSX) |
117 | 129 |
118 } // namespace | 130 } // namespace |
119 | 131 |
120 namespace base { | 132 namespace base { |
121 | 133 |
122 // static | 134 // static |
123 TimeDelta TimeDelta::FromTimeSpec(const timespec& ts) { | 135 TimeDelta TimeDelta::FromTimeSpec(const timespec& ts) { |
124 return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond + | 136 return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond + |
125 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); | 137 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
235 timestruct.tm_mon = exploded.month - 1; | 247 timestruct.tm_mon = exploded.month - 1; |
236 timestruct.tm_year = exploded.year - 1900; | 248 timestruct.tm_year = exploded.year - 1900; |
237 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this | 249 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this |
238 timestruct.tm_yday = 0; // mktime/timegm ignore this | 250 timestruct.tm_yday = 0; // mktime/timegm ignore this |
239 timestruct.tm_isdst = -1; // attempt to figure it out | 251 timestruct.tm_isdst = -1; // attempt to figure it out |
240 #if !defined(OS_NACL) && !defined(OS_SOLARIS) | 252 #if !defined(OS_NACL) && !defined(OS_SOLARIS) |
241 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore | 253 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 | 254 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore |
243 #endif | 255 #endif |
244 | 256 |
245 int64_t milliseconds; | 257 int64_t milliseconds = 0; |
miu
2016/10/18 19:55:13
nit: Please move the declaration of |milliseconds|
maksims (do not use this acc)
2016/10/19 16:41:04
Done.
| |
246 SysTime seconds; | 258 SysTime seconds; |
247 | 259 |
248 // Certain exploded dates do not really exist due to daylight saving times, | 260 // Certain exploded dates do not really exist due to daylight saving times, |
249 // and this causes mktime() to return implementation-defined values when | 261 // and this causes mktime() to return implementation-defined values when |
250 // tm_isdst is set to -1. On Android, the function will return -1, while the | 262 // tm_isdst is set to -1. On Android, the function will return -1, while the |
251 // C libraries of other platforms typically return a liberally-chosen value. | 263 // C libraries of other platforms typically return a liberally-chosen value. |
252 // Handling this requires the special code below. | 264 // Handling this requires the special code below. |
253 | 265 |
254 // SysTimeFromTimeStruct() modifies the input structure, save current value. | 266 // SysTimeFromTimeStruct() modifies the input structure, save current value. |
255 struct tm timestruct0 = timestruct; | 267 struct tm timestruct0 = timestruct; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 const int64_t max_seconds = (sizeof(SysTime) < sizeof(int64_t)) | 317 const int64_t max_seconds = (sizeof(SysTime) < sizeof(int64_t)) |
306 ? std::numeric_limits<SysTime>::max() | 318 ? std::numeric_limits<SysTime>::max() |
307 : std::numeric_limits<int32_t>::max(); | 319 : std::numeric_limits<int32_t>::max(); |
308 if (exploded.year < 1969) { | 320 if (exploded.year < 1969) { |
309 milliseconds = min_seconds * kMillisecondsPerSecond; | 321 milliseconds = min_seconds * kMillisecondsPerSecond; |
310 } else { | 322 } else { |
311 milliseconds = max_seconds * kMillisecondsPerSecond; | 323 milliseconds = max_seconds * kMillisecondsPerSecond; |
312 milliseconds += (kMillisecondsPerSecond - 1); | 324 milliseconds += (kMillisecondsPerSecond - 1); |
313 } | 325 } |
314 } else { | 326 } else { |
315 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; | 327 milliseconds = |
miu
2016/10/18 19:55:13
Suggestion (to return false if overflow occurs):
maksims (do not use this acc)
2016/10/19 16:41:04
Done.
| |
328 MultiplyAndAdd(seconds, kMillisecondsPerSecond, exploded.millisecond); | |
316 } | 329 } |
317 | 330 |
318 // Adjust from Unix (1970) to Windows (1601) epoch. | 331 // Adjust from Unix (1970) to Windows (1601) epoch. |
319 base::Time converted_time = | 332 int64_t microseconds_win_epoch = |
miu
2016/10/18 19:55:13
Similar suggestion here: Declare |microseconds_win
maksims (do not use this acc)
2016/10/19 16:41:04
Done.
| |
320 Time((milliseconds * kMicrosecondsPerMillisecond) + | 333 MultiplyAndAdd(milliseconds, kMicrosecondsPerMillisecond, |
321 kWindowsEpochDeltaMicroseconds); | 334 kWindowsEpochDeltaMicroseconds); |
335 base::Time converted_time(microseconds_win_epoch); | |
322 | 336 |
323 // If |exploded.day_of_month| is set to 31 on a 28-30 day month, it will | 337 // If |exploded.day_of_month| is set to 31 on a 28-30 day month, it will |
324 // return the first day of the next month. Thus round-trip the time and | 338 // return the first day of the next month. Thus round-trip the time and |
325 // compare the initial |exploded| with |utc_to_exploded| time. | 339 // compare the initial |exploded| with |utc_to_exploded| time. |
326 base::Time::Exploded to_exploded; | 340 base::Time::Exploded to_exploded; |
327 if (!is_local) | 341 if (!is_local) |
328 converted_time.UTCExplode(&to_exploded); | 342 converted_time.UTCExplode(&to_exploded); |
329 else | 343 else |
330 converted_time.LocalExplode(&to_exploded); | 344 converted_time.LocalExplode(&to_exploded); |
331 | 345 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
397 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; | 411 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; |
398 return result; | 412 return result; |
399 } | 413 } |
400 int64_t us = us_ - kTimeTToMicrosecondsOffset; | 414 int64_t us = us_ - kTimeTToMicrosecondsOffset; |
401 result.tv_sec = us / Time::kMicrosecondsPerSecond; | 415 result.tv_sec = us / Time::kMicrosecondsPerSecond; |
402 result.tv_usec = us % Time::kMicrosecondsPerSecond; | 416 result.tv_usec = us % Time::kMicrosecondsPerSecond; |
403 return result; | 417 return result; |
404 } | 418 } |
405 | 419 |
406 } // namespace base | 420 } // namespace base |
OLD | NEW |