| 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 * |
| 11 * The Initial Developer of the Original Code is | 11 * The Initial Developer of the Original Code is |
| 12 * Netscape Communications Corporation. | 12 * Netscape Communications Corporation. |
| 13 * Portions created by the Initial Developer are Copyright (C) 1998 | 13 * Portions created by the Initial Developer are Copyright (C) 1998 |
| 14 * the Initial Developer. All Rights Reserved. | 14 * the Initial Developer. All Rights Reserved. |
| 15 * | 15 * |
| 16 * This library is free software; you can redistribute it and/or | 16 * This library is free software; you can redistribute it and/or |
| 17 * modify it under the terms of the GNU Lesser General Public | 17 * modify it under the terms of the GNU Lesser General Public |
| 18 * License as published by the Free Software Foundation; either | 18 * License as published by the Free Software Foundation; either |
| 19 * version 2.1 of the License, or (at your option) any later version. | 19 * version 2.1 of the License, or (at your option) any later version. |
| 20 * | 20 * |
| 21 * This library is distributed in the hope that it will be useful, | 21 * This library is distributed in the hope that it will be useful, |
| 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 24 * Lesser General Public License for more details. | 24 * Lesser General Public License for more details. |
| 25 * | 25 * |
| 26 * You should have received a copy of the GNU Lesser General Public | 26 * You should have received a copy of the GNU Lesser General Public |
| 27 * License along with this library; if not, write to the Free Software | 27 * License along with this library; if not, write to the Free Software |
| 28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US
A | 28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 29 * | 29 * |
| 30 * Alternatively, the contents of this file may be used under the terms | 30 * Alternatively, the contents of this file may be used under the terms |
| 31 * of either the Mozilla Public License Version 1.1, found at | 31 * of either the Mozilla Public License Version 1.1, found at |
| 32 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public | 32 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public |
| 33 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html | 33 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html |
| 34 * (the "GPL"), in which case the provisions of the MPL or the GPL are | 34 * (the "GPL"), in which case the provisions of the MPL or the GPL are |
| 35 * applicable instead of those above. If you wish to allow use of your | 35 * applicable instead of those above. If you wish to allow use of your |
| 36 * version of this file only under the terms of one of those two | 36 * version of this file only under the terms of one of those two |
| 37 * licenses (the MPL or the GPL) and not to allow others to use your | 37 * licenses (the MPL or the GPL) and not to allow others to use your |
| 38 * version of this file under the LGPL, indicate your decision by | 38 * version of this file under the LGPL, indicate your decision by |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 | 95 |
| 96 /* Constants */ | 96 /* Constants */ |
| 97 | 97 |
| 98 static const double hoursPerDay = 24.0; | 98 static const double hoursPerDay = 24.0; |
| 99 static const double secondsPerDay = 24.0 * 60.0 * 60.0; | 99 static const double secondsPerDay = 24.0 * 60.0 * 60.0; |
| 100 | 100 |
| 101 static const double maxUnixTime = 2145859200.0; // 12/31/2037 | 101 static const double maxUnixTime = 2145859200.0; // 12/31/2037 |
| 102 static const double kMinimumECMADateInMs = -8640000000000000.0; | 102 static const double kMinimumECMADateInMs = -8640000000000000.0; |
| 103 static const double kMaximumECMADateInMs = 8640000000000000.0; | 103 static const double kMaximumECMADateInMs = 8640000000000000.0; |
| 104 | 104 |
| 105 // Day of year for the first day of each month, where index 0 is January, and da
y 0 is January 1. | 105 // Day of year for the first day of each month, where index 0 is January, and |
| 106 // First for non-leap years, then for leap years. | 106 // day 0 is January 1. First for non-leap years, then for leap years. |
| 107 static const int firstDayOfMonth[2][12] = { | 107 static const int firstDayOfMonth[2][12] = { |
| 108 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, | 108 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, |
| 109 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}}; | 109 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}}; |
| 110 | 110 |
| 111 static inline void getLocalTime(const time_t* localTime, struct tm* localTM) { | 111 static inline void getLocalTime(const time_t* localTime, struct tm* localTM) { |
| 112 #if COMPILER(MSVC) | 112 #if COMPILER(MSVC) |
| 113 localtime_s(localTM, localTime); | 113 localtime_s(localTM, localTime); |
| 114 #else | 114 #else |
| 115 localtime_r(localTime, localTM); | 115 localtime_r(localTime, localTM); |
| 116 #endif | 116 #endif |
| 117 } | 117 } |
| 118 | 118 |
| 119 bool isLeapYear(int year) { | 119 bool isLeapYear(int year) { |
| 120 if (year % 4 != 0) | 120 if (year % 4 != 0) |
| 121 return false; | 121 return false; |
| 122 if (year % 400 == 0) | 122 if (year % 400 == 0) |
| 123 return true; | 123 return true; |
| 124 if (year % 100 == 0) | 124 if (year % 100 == 0) |
| 125 return false; | 125 return false; |
| 126 return true; | 126 return true; |
| 127 } | 127 } |
| 128 | 128 |
| 129 static inline int daysInYear(int year) { | 129 static inline int daysInYear(int year) { |
| 130 return 365 + isLeapYear(year); | 130 return 365 + isLeapYear(year); |
| 131 } | 131 } |
| 132 | 132 |
| 133 static inline double daysFrom1970ToYear(int year) { | 133 static inline double daysFrom1970ToYear(int year) { |
| 134 // The Gregorian Calendar rules for leap years: | 134 // The Gregorian Calendar rules for leap years: |
| 135 // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years. | 135 // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years. |
| 136 // However, every hundredth year is not a leap year. 1900 and 2100 are not le
ap years. | 136 // However, every hundredth year is not a leap year. 1900 and 2100 are not |
| 137 // Every four hundred years, there's a leap year after all. 2000 and 2400 are
leap years. | 137 // leap years. |
| 138 // Every four hundred years, there's a leap year after all. 2000 and 2400 are |
| 139 // leap years. |
| 138 | 140 |
| 139 static const int leapDaysBefore1971By4Rule = 1970 / 4; | 141 static const int leapDaysBefore1971By4Rule = 1970 / 4; |
| 140 static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100; | 142 static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100; |
| 141 static const int leapDaysBefore1971By400Rule = 1970 / 400; | 143 static const int leapDaysBefore1971By400Rule = 1970 / 400; |
| 142 | 144 |
| 143 const double yearMinusOne = year - 1; | 145 const double yearMinusOne = year - 1; |
| 144 const double yearsToAddBy4Rule = | 146 const double yearsToAddBy4Rule = |
| 145 floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule; | 147 floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule; |
| 146 const double yearsToExcludeBy100Rule = | 148 const double yearsToExcludeBy100Rule = |
| 147 floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule; | 149 floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 } | 290 } |
| 289 | 291 |
| 290 static inline int minimumYearForDST() { | 292 static inline int minimumYearForDST() { |
| 291 // Because of the 2038 issue (see maximumYearForDST) if the current year is | 293 // Because of the 2038 issue (see maximumYearForDST) if the current year is |
| 292 // greater than the max year minus 27 (2010), we want to use the max year | 294 // greater than the max year minus 27 (2010), we want to use the max year |
| 293 // minus 27 instead, to ensure there is a range of 28 years that all years | 295 // minus 27 instead, to ensure there is a range of 28 years that all years |
| 294 // can map to. | 296 // can map to. |
| 295 return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27); | 297 return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27); |
| 296 } | 298 } |
| 297 | 299 |
| 298 /* | 300 // Find an equivalent year for the one given, where equivalence is deterined by |
| 299 * Find an equivalent year for the one given, where equivalence is deterined by | 301 // the two years having the same leapness and the first day of the year, falling |
| 300 * the two years having the same leapness and the first day of the year, falling | 302 // on the same day of the week. |
| 301 * on the same day of the week. | 303 // |
| 302 * | 304 // This function returns a year between this current year and 2037, however this |
| 303 * This function returns a year between this current year and 2037, however this | 305 // function will potentially return incorrect results if the current year is |
| 304 * function will potentially return incorrect results if the current year is aft
er | 306 // after 2010, (rdar://problem/5052975), if the year passed in is before 1900 |
| 305 * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after | 307 // or after 2100, (rdar://problem/5055038). |
| 306 * 2100, (rdar://problem/5055038). | |
| 307 */ | |
| 308 static int equivalentYearForDST(int year) { | 308 static int equivalentYearForDST(int year) { |
| 309 // It is ok if the cached year is not the current year as long as the rules | 309 // It is ok if the cached year is not the current year as long as the rules |
| 310 // for DST did not change between the two years; if they did the app would nee
d | 310 // for DST did not change between the two years; if they did the app would |
| 311 // to be restarted. | 311 // need to be restarted. |
| 312 static int minYear = minimumYearForDST(); | 312 static int minYear = minimumYearForDST(); |
| 313 int maxYear = maximumYearForDST(); | 313 int maxYear = maximumYearForDST(); |
| 314 | 314 |
| 315 int difference; | 315 int difference; |
| 316 if (year > maxYear) | 316 if (year > maxYear) |
| 317 difference = minYear - year; | 317 difference = minYear - year; |
| 318 else if (year < minYear) | 318 else if (year < minYear) |
| 319 difference = maxYear - year; | 319 difference = maxYear - year; |
| 320 else | 320 else |
| 321 return year; | 321 return year; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 time_t localTime = static_cast<time_t>(localTimeSeconds); | 362 time_t localTime = static_cast<time_t>(localTimeSeconds); |
| 363 | 363 |
| 364 tm localTM; | 364 tm localTM; |
| 365 getLocalTime(&localTime, &localTM); | 365 getLocalTime(&localTime, &localTM); |
| 366 | 366 |
| 367 return localTM.tm_isdst > 0 ? msPerHour : 0; | 367 return localTM.tm_isdst > 0 ? msPerHour : 0; |
| 368 } | 368 } |
| 369 | 369 |
| 370 // Get the DST offset, given a time in UTC | 370 // Get the DST offset, given a time in UTC |
| 371 static double calculateDSTOffset(double ms, double utcOffset) { | 371 static double calculateDSTOffset(double ms, double utcOffset) { |
| 372 // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will retu
rn historically accurate | 372 // On macOS, the call to localtime (see calculateDSTOffsetSimple) will return |
| 373 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) howev
er the JavaScript | 373 // historically accurate DST information (e.g. New Zealand did not have DST |
| 374 // standard explicitly dictates that historical information should not be cons
idered when | 374 // from 1946 to 1974) however the JavaScript standard explicitly dictates |
| 375 // determining DST. For this reason we shift away from years that localtime ca
n handle but would | 375 // that historical information should not be considered when determining DST. |
| 376 // return historically accurate information. | 376 // For this reason we shift away from years that localtime can handle but |
| 377 // would return historically accurate information. |
| 377 int year = msToYear(ms); | 378 int year = msToYear(ms); |
| 378 int equivalentYear = equivalentYearForDST(year); | 379 int equivalentYear = equivalentYearForDST(year); |
| 379 if (year != equivalentYear) { | 380 if (year != equivalentYear) { |
| 380 bool leapYear = isLeapYear(year); | 381 bool leapYear = isLeapYear(year); |
| 381 int dayInYearLocal = dayInYear(ms, year); | 382 int dayInYearLocal = dayInYear(ms, year); |
| 382 int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear); | 383 int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear); |
| 383 int month = monthFromDayInYear(dayInYearLocal, leapYear); | 384 int month = monthFromDayInYear(dayInYearLocal, leapYear); |
| 384 double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth); | 385 double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth); |
| 385 ms = (day * msPerDay) + msToMilliseconds(ms); | 386 ms = (day * msPerDay) + msToMilliseconds(ms); |
| 386 } | 387 } |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 return stringBuilder.toString(); | 832 return stringBuilder.toString(); |
| 832 } | 833 } |
| 833 | 834 |
| 834 double convertToLocalTime(double ms) { | 835 double convertToLocalTime(double ms) { |
| 835 double utcOffset = calculateUTCOffset(); | 836 double utcOffset = calculateUTCOffset(); |
| 836 double dstOffset = calculateDSTOffset(ms, utcOffset); | 837 double dstOffset = calculateDSTOffset(ms, utcOffset); |
| 837 return (ms + utcOffset + dstOffset); | 838 return (ms + utcOffset + dstOffset); |
| 838 } | 839 } |
| 839 | 840 |
| 840 } // namespace WTF | 841 } // namespace WTF |
| OLD | NEW |