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