| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) | 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) |
| 3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
| 4 * Copyright (C) 2009 Google Inc. All rights reserved. | 4 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 5 * Copyright (C) 2007-2009 Torch Mobile, Inc. | 5 * Copyright (C) 2007-2009 Torch Mobile, Inc. |
| 6 * Copyright (C) 2010 &yet, LLC. (nate@andyet.net) | 6 * Copyright (C) 2010 &yet, LLC. (nate@andyet.net) |
| 7 * | 7 * |
| 8 * The Original Code is Mozilla Communicator client code, released | 8 * The Original Code is Mozilla Communicator client code, released |
| 9 * March 31, 1998. | 9 * March 31, 1998. |
| 10 * | 10 * |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 #endif | 96 #endif |
| 97 | 97 |
| 98 using namespace WTF; | 98 using namespace WTF; |
| 99 | 99 |
| 100 namespace WTF { | 100 namespace WTF { |
| 101 | 101 |
| 102 /* Constants */ | 102 /* Constants */ |
| 103 | 103 |
| 104 static const double hoursPerDay = 24.0; | 104 static const double hoursPerDay = 24.0; |
| 105 static const double secondsPerDay = 24.0 * 60.0 * 60.0; | 105 static const double secondsPerDay = 24.0 * 60.0 * 60.0; |
| 106 static const double secondsPerHour = 60.0 * 60.0; | |
| 107 | 106 |
| 108 static const double maxUnixTime = 2145859200.0; // 12/31/2037 | 107 static const double maxUnixTime = 2145859200.0; // 12/31/2037 |
| 109 | 108 |
| 110 // Day of year for the first day of each month, where index 0 is January, and da
y 0 is January 1. | 109 // Day of year for the first day of each month, where index 0 is January, and da
y 0 is January 1. |
| 111 // First for non-leap years, then for leap years. | 110 // First for non-leap years, then for leap years. |
| 112 static const int firstDayOfMonth[2][12] = { | 111 static const int firstDayOfMonth[2][12] = { |
| 113 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, | 112 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, |
| 114 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} | 113 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} |
| 115 }; | 114 }; |
| 116 | 115 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 } | 187 } |
| 189 | 188 |
| 190 static inline double msToMilliseconds(double ms) | 189 static inline double msToMilliseconds(double ms) |
| 191 { | 190 { |
| 192 double result = fmod(ms, msPerDay); | 191 double result = fmod(ms, msPerDay); |
| 193 if (result < 0) | 192 if (result < 0) |
| 194 result += msPerDay; | 193 result += msPerDay; |
| 195 return result; | 194 return result; |
| 196 } | 195 } |
| 197 | 196 |
| 198 static int msToMinutes(double ms) | |
| 199 { | |
| 200 double result = fmod(floor(ms / msPerMinute), minutesPerHour); | |
| 201 if (result < 0) | |
| 202 result += minutesPerHour; | |
| 203 return static_cast<int>(result); | |
| 204 } | |
| 205 | |
| 206 static int msToHours(double ms) | |
| 207 { | |
| 208 double result = fmod(floor(ms/msPerHour), hoursPerDay); | |
| 209 if (result < 0) | |
| 210 result += hoursPerDay; | |
| 211 return static_cast<int>(result); | |
| 212 } | |
| 213 | |
| 214 int monthFromDayInYear(int dayInYear, bool leapYear) | 197 int monthFromDayInYear(int dayInYear, bool leapYear) |
| 215 { | 198 { |
| 216 const int d = dayInYear; | 199 const int d = dayInYear; |
| 217 int step; | 200 int step; |
| 218 | 201 |
| 219 if (d < (step = 31)) | 202 if (d < (step = 31)) |
| 220 return 0; | 203 return 0; |
| 221 step += (leapYear ? 29 : 28); | 204 step += (leapYear ? 29 : 28); |
| 222 if (d < step) | 205 if (d < step) |
| 223 return 1; | 206 return 1; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 return year; | 334 return year; |
| 352 | 335 |
| 353 int quotient = difference / 28; | 336 int quotient = difference / 28; |
| 354 int product = (quotient) * 28; | 337 int product = (quotient) * 28; |
| 355 | 338 |
| 356 year += product; | 339 year += product; |
| 357 ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cas
t<int>(std::numeric_limits<double>::quiet_NaN()))); | 340 ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cas
t<int>(std::numeric_limits<double>::quiet_NaN()))); |
| 358 return year; | 341 return year; |
| 359 } | 342 } |
| 360 | 343 |
| 361 int32_t calculateUTCOffset() | 344 static double calculateUTCOffset() |
| 362 { | 345 { |
| 363 #if OS(WIN) | 346 #if OS(WIN) |
| 364 TIME_ZONE_INFORMATION timeZoneInformation; | 347 TIME_ZONE_INFORMATION timeZoneInformation; |
| 365 GetTimeZoneInformation(&timeZoneInformation); | 348 GetTimeZoneInformation(&timeZoneInformation); |
| 366 int32_t bias = timeZoneInformation.Bias + timeZoneInformation.StandardBias; | 349 int32_t bias = timeZoneInformation.Bias + timeZoneInformation.StandardBias; |
| 367 return -bias * 60 * 1000; | 350 return -bias * 60 * 1000; |
| 368 #else | 351 #else |
| 369 time_t localTime = time(0); | 352 time_t localTime = time(0); |
| 370 tm localt; | 353 tm localt; |
| 371 getLocalTime(&localTime, &localt); | 354 getLocalTime(&localTime, &localt); |
| 372 | 355 |
| 373 // Get the difference between this time zone and UTC on the 1st of January o
f this year. | 356 // tm_gmtoff includes any daylight savings offset, so subtract it. |
| 374 localt.tm_sec = 0; | 357 return static_cast<double>(localt.tm_gmtoff * msPerSecond - (localt.tm_isdst
> 0 ? msPerHour : 0)); |
| 375 localt.tm_min = 0; | |
| 376 localt.tm_hour = 0; | |
| 377 localt.tm_mday = 1; | |
| 378 localt.tm_mon = 0; | |
| 379 // Not setting localt.tm_year! | |
| 380 localt.tm_wday = 0; | |
| 381 localt.tm_yday = 0; | |
| 382 localt.tm_isdst = 0; | |
| 383 #if HAVE(TM_GMTOFF) | |
| 384 localt.tm_gmtoff = 0; | |
| 385 #endif | |
| 386 #if HAVE(TM_ZONE) | |
| 387 localt.tm_zone = 0; | |
| 388 #endif | |
| 389 | |
| 390 #if HAVE(TIMEGM) | |
| 391 time_t utcOffset = timegm(&localt) - mktime(&localt); | |
| 392 #else | |
| 393 // Using a canned date of 01/01/2009 on platforms with weaker date-handling
foo. | |
| 394 localt.tm_year = 109; | |
| 395 time_t utcOffset = 1230768000 - mktime(&localt); | |
| 396 #endif | |
| 397 | |
| 398 return static_cast<int32_t>(utcOffset * 1000); | |
| 399 #endif | 358 #endif |
| 400 } | 359 } |
| 401 | 360 |
| 402 /* | 361 /* |
| 403 * Get the DST offset for the time passed in. | 362 * Get the DST offset for the time passed in. |
| 404 */ | 363 */ |
| 405 static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset
) | 364 static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset
) |
| 406 { | 365 { |
| 407 if (localTimeSeconds > maxUnixTime) | 366 if (localTimeSeconds > maxUnixTime) |
| 408 localTimeSeconds = maxUnixTime; | 367 localTimeSeconds = maxUnixTime; |
| 409 else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (doe
s not work with 0) | 368 else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (doe
s not work with 0) |
| 410 localTimeSeconds += secondsPerDay; | 369 localTimeSeconds += secondsPerDay; |
| 411 | 370 |
| 412 //input is UTC so we have to shift back to local time to determine DST thus
the + getUTCOffset() | |
| 413 double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset; | |
| 414 | |
| 415 // Offset from UTC but doesn't include DST obviously | |
| 416 int offsetHour = msToHours(offsetTime); | |
| 417 int offsetMinute = msToMinutes(offsetTime); | |
| 418 | |
| 419 // FIXME: time_t has a potential problem in 2038 | 371 // FIXME: time_t has a potential problem in 2038 |
| 420 time_t localTime = static_cast<time_t>(localTimeSeconds); | 372 time_t localTime = static_cast<time_t>(localTimeSeconds); |
| 421 | 373 |
| 422 tm localTM; | 374 tm localTM; |
| 423 getLocalTime(&localTime, &localTM); | 375 getLocalTime(&localTime, &localTM); |
| 424 | 376 |
| 425 double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.
tm_min - offsetMinute) * 60); | 377 return localTM.tm_isdst > 0 ? msPerHour : 0; |
| 426 | |
| 427 if (diff < 0) | |
| 428 diff += secondsPerDay; | |
| 429 | |
| 430 return (diff * msPerSecond); | |
| 431 } | 378 } |
| 432 | 379 |
| 433 // Get the DST offset, given a time in UTC | 380 // Get the DST offset, given a time in UTC |
| 434 double calculateDSTOffset(double ms, double utcOffset) | 381 static double calculateDSTOffset(double ms, double utcOffset) |
| 435 { | 382 { |
| 436 // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will re
turn historically accurate | 383 // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will re
turn historically accurate |
| 437 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) how
ever the JavaScript | 384 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) how
ever the JavaScript |
| 438 // standard explicitly dictates that historical information should not be co
nsidered when | 385 // standard explicitly dictates that historical information should not be co
nsidered when |
| 439 // determining DST. For this reason we shift away from years that localtime
can handle but would | 386 // determining DST. For this reason we shift away from years that localtime
can handle but would |
| 440 // return historically accurate information. | 387 // return historically accurate information. |
| 441 int year = msToYear(ms); | 388 int year = msToYear(ms); |
| 442 int equivalentYear = equivalentYearForDST(year); | 389 int equivalentYear = equivalentYearForDST(year); |
| 443 if (year != equivalentYear) { | 390 if (year != equivalentYear) { |
| 444 bool leapYear = isLeapYear(year); | 391 bool leapYear = isLeapYear(year); |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 stringBuilder.append(' '); | 821 stringBuilder.append(' '); |
| 875 | 822 |
| 876 stringBuilder.append(utcOffset > 0 ? '+' : '-'); | 823 stringBuilder.append(utcOffset > 0 ? '+' : '-'); |
| 877 int absoluteUTCOffset = abs(utcOffset); | 824 int absoluteUTCOffset = abs(utcOffset); |
| 878 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset / 60)); | 825 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset / 60)); |
| 879 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset % 60)); | 826 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset % 60)); |
| 880 | 827 |
| 881 return stringBuilder.toString(); | 828 return stringBuilder.toString(); |
| 882 } | 829 } |
| 883 | 830 |
| 831 double convertToLocalTime(double ms) |
| 832 { |
| 833 double utcOffset = calculateUTCOffset(); |
| 834 double dstOffset = calculateDSTOffset(ms, utcOffset); |
| 835 return (ms + utcOffset + dstOffset); |
| 836 } |
| 837 |
| 884 } // namespace WTF | 838 } // namespace WTF |
| OLD | NEW |