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) | 10 #if defined(OS_ANDROID) |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 timestruct.tm_mon = exploded.month - 1; | 207 timestruct.tm_mon = exploded.month - 1; |
208 timestruct.tm_year = exploded.year - 1900; | 208 timestruct.tm_year = exploded.year - 1900; |
209 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this | 209 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this |
210 timestruct.tm_yday = 0; // mktime/timegm ignore this | 210 timestruct.tm_yday = 0; // mktime/timegm ignore this |
211 timestruct.tm_isdst = -1; // attempt to figure it out | 211 timestruct.tm_isdst = -1; // attempt to figure it out |
212 #if !defined(OS_NACL) && !defined(OS_SOLARIS) | 212 #if !defined(OS_NACL) && !defined(OS_SOLARIS) |
213 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore | 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 | 214 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore |
215 #endif | 215 #endif |
216 | 216 |
217 SysTime seconds = SysTimeFromTimeStruct(×truct, is_local); | |
218 | 217 |
219 int64 milliseconds; | 218 int64 milliseconds; |
219 SysTime seconds; | |
220 | |
221 #if defined(OS_ANDROID) | |
jar (doing other things)
2013/10/18 02:14:17
This probably isn't an android only problem. It r
digit1
2013/10/18 08:54:59
Thanks, I've remove the #if defined(OS_ANDROID) no
| |
222 // Certain exploded dates do not really exist due to daylight saving times, | |
223 // and this causes mktime() to return implementation-defined values when | |
224 // tm_isdst is set to -1. On Android, the function will return -1, while the | |
225 // C libraries of other platforms typically return a liberally chosen value. | |
226 // Handling this requires the special code below. | |
227 | |
228 // SysTimeFromTimeStruct() modifies the input structure, save current value. | |
229 struct tm timestruct0 = timestruct; | |
230 | |
231 seconds = SysTimeFromTimeStruct(×truct, is_local); | |
232 if (seconds == -1) { | |
233 // Get the time values with tm_isdst == 0 and 1, then select the closest one | |
234 // to UTC 00:00:00 that isn't -1. | |
235 timestruct = timestruct0; | |
236 timestruct.tm_isdst = 0; | |
237 int64 seconds_isdst0 = SysTimeFromTimeStruct(×truct, is_local); | |
238 | |
239 timestruct = timestruct0; | |
240 timestruct.tm_isdst = 1; | |
241 int64 seconds_isdst1 = SysTimeFromTimeStruct(×truct, is_local); | |
242 | |
243 // seconds_isdst0 or seconds_isdst1 can be -1 for some timezones. | |
244 // E.g. "CLST" (Chile Summer Time) returns -1 for 'tm_isdt == 1'. | |
245 if (seconds_isdst0 < 0) | |
246 seconds = seconds_isdst1; | |
247 else if (seconds_isdst1 < 0) | |
248 seconds = seconds_isdst0; | |
249 else | |
250 seconds = std::min(seconds_isdst0, seconds_isdst1); | |
251 } | |
252 #else | |
253 seconds = SysTimeFromTimeStruct(×truct, is_local); | |
254 #endif | |
255 | |
220 // Handle overflow. Clamping the range to what mktime and timegm might | 256 // Handle overflow. Clamping the range to what mktime and timegm might |
221 // return is the best that can be done here. It's not ideal, but it's better | 257 // return is the best that can be done here. It's not ideal, but it's better |
222 // than failing here or ignoring the overflow case and treating each time | 258 // than failing here or ignoring the overflow case and treating each time |
223 // overflow as one second prior to the epoch. | 259 // overflow as one second prior to the epoch. |
224 if (seconds == -1 && | 260 if (seconds == -1 && |
225 (exploded.year < 1969 || exploded.year > 1970)) { | 261 (exploded.year < 1969 || exploded.year > 1970)) { |
226 // If exploded.year is 1969 or 1970, take -1 as correct, with the | 262 // If exploded.year is 1969 or 1970, take -1 as correct, with the |
227 // time indicating 1 second prior to the epoch. (1970 is allowed to handle | 263 // time indicating 1 second prior to the epoch. (1970 is allowed to handle |
228 // time zone and DST offsets.) Otherwise, return the most future or past | 264 // time zone and DST offsets.) Otherwise, return the most future or past |
229 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. | 265 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. |
230 // | 266 // |
231 // The minimum and maximum representible times that mktime and timegm could | 267 // The minimum and maximum representible times that mktime and timegm could |
232 // return are used here instead of values outside that range to allow for | 268 // return are used here instead of values outside that range to allow for |
233 // proper round-tripping between exploded and counter-type time | 269 // proper round-tripping between exploded and counter-type time |
234 // representations in the presence of possible truncation to time_t by | 270 // representations in the presence of possible truncation to time_t by |
235 // division and use with other functions that accept time_t. | 271 // division and use with other functions that accept time_t. |
236 // | 272 // |
237 // When representing the most distant time in the future, add in an extra | 273 // When representing the most distant time in the future, add in an extra |
238 // 999ms to avoid the time being less than any other possible value that | 274 // 999ms to avoid the time being less than any other possible value that |
239 // this function can return. | 275 // this function can return. |
276 | |
277 // On Android, SysTime is int64, special care must be taken to avoid | |
278 // overflows. | |
279 const int64 min_seconds = (sizeof(SysTime) < sizeof(int64)) | |
280 ? std::numeric_limits<SysTime>::min() | |
281 : std::numeric_limits<int32_t>::min(); | |
282 const int64 max_seconds = (sizeof(SysTime) < sizeof(int64)) | |
283 ? std::numeric_limits<SysTime>::max() | |
284 : std::numeric_limits<int32_t>::max(); | |
240 if (exploded.year < 1969) { | 285 if (exploded.year < 1969) { |
241 CHECK(sizeof(SysTime) < sizeof(int64)) << "integer overflow"; | 286 milliseconds = min_seconds * kMillisecondsPerSecond; |
242 milliseconds = std::numeric_limits<SysTime>::min(); | |
243 milliseconds *= kMillisecondsPerSecond; | |
244 } else { | 287 } else { |
245 CHECK(sizeof(SysTime) < sizeof(int64)) << "integer overflow"; | 288 milliseconds = max_seconds * kMillisecondsPerSecond; |
246 milliseconds = std::numeric_limits<SysTime>::max(); | |
247 milliseconds *= kMillisecondsPerSecond; | |
248 milliseconds += (kMillisecondsPerSecond - 1); | 289 milliseconds += (kMillisecondsPerSecond - 1); |
249 } | 290 } |
250 } else { | 291 } else { |
251 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; | 292 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; |
252 } | 293 } |
253 | 294 |
254 // Adjust from Unix (1970) to Windows (1601) epoch. | 295 // Adjust from Unix (1970) to Windows (1601) epoch. |
255 return Time((milliseconds * kMicrosecondsPerMillisecond) + | 296 return Time((milliseconds * kMicrosecondsPerMillisecond) + |
256 kWindowsEpochDeltaMicroseconds); | 297 kWindowsEpochDeltaMicroseconds); |
257 } | 298 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; | 384 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; |
344 return result; | 385 return result; |
345 } | 386 } |
346 int64 us = us_ - kTimeTToMicrosecondsOffset; | 387 int64 us = us_ - kTimeTToMicrosecondsOffset; |
347 result.tv_sec = us / Time::kMicrosecondsPerSecond; | 388 result.tv_sec = us / Time::kMicrosecondsPerSecond; |
348 result.tv_usec = us % Time::kMicrosecondsPerSecond; | 389 result.tv_usec = us % Time::kMicrosecondsPerSecond; |
349 return result; | 390 return result; |
350 } | 391 } |
351 | 392 |
352 } // namespace base | 393 } // namespace base |
OLD | NEW |