diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/DateMath.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/DateMath.cpp')
-rw-r--r-- | Source/WTF/wtf/DateMath.cpp | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/Source/WTF/wtf/DateMath.cpp b/Source/WTF/wtf/DateMath.cpp index 654bd8d2d..1350e3040 100644 --- a/Source/WTF/wtf/DateMath.cpp +++ b/Source/WTF/wtf/DateMath.cpp @@ -121,18 +121,16 @@ static const int firstDayOfMonth[2][12] = { {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} }; -#if !OS(WINCE) static inline void getLocalTime(const time_t* localTime, struct tm* localTM) { -#if COMPILER(MINGW) - *localTM = *localtime(localTime); -#elif COMPILER(MSVC) +#if COMPILER(MSVC) localtime_s(localTM, localTime); -#else +#elif HAVE(LOCALTIME_R) localtime_r(localTime, localTM); +#else + localtime_s(localTime, localTM); #endif } -#endif bool isLeapYear(int year) { @@ -166,7 +164,7 @@ static inline double daysFrom1970ToYear(int year) const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule; const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule; - return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule; + return 365.0 * (year - 1970.0) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule; } double msToDays(double ms) @@ -359,16 +357,56 @@ int equivalentYearForDST(int year) int product = (quotient) * 28; year += product; - ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cast<int>(std::numeric_limits<double>::quiet_NaN()))); return year; } +#if OS(WINDOWS) +typedef BOOL(WINAPI* callGetTimeZoneInformationForYear_t)(USHORT, PDYNAMIC_TIME_ZONE_INFORMATION, LPTIME_ZONE_INFORMATION); + +static callGetTimeZoneInformationForYear_t timeZoneInformationForYearFunction() +{ + static callGetTimeZoneInformationForYear_t getTimeZoneInformationForYear = nullptr; + + if (getTimeZoneInformationForYear) + return getTimeZoneInformationForYear; + + HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); + if (!module) + return nullptr; + + getTimeZoneInformationForYear = reinterpret_cast<callGetTimeZoneInformationForYear_t>(::GetProcAddress(module, "GetTimeZoneInformationForYear")); + + return getTimeZoneInformationForYear; +} +#endif + static int32_t calculateUTCOffset() { #if OS(WINDOWS) TIME_ZONE_INFORMATION timeZoneInformation; - GetTimeZoneInformation(&timeZoneInformation); - int32_t bias = timeZoneInformation.Bias + timeZoneInformation.StandardBias; + DWORD rc = 0; + + if (callGetTimeZoneInformationForYear_t timeZoneFunction = timeZoneInformationForYearFunction()) { + // If available, use the Windows API call that takes into account the varying DST from + // year to year. + SYSTEMTIME systemTime; + ::GetSystemTime(&systemTime); + rc = timeZoneFunction(systemTime.wYear, nullptr, &timeZoneInformation); + if (rc == TIME_ZONE_ID_INVALID) + return 0; + } else { + rc = ::GetTimeZoneInformation(&timeZoneInformation); + if (rc == TIME_ZONE_ID_INVALID) + return 0; + } + + int32_t bias = timeZoneInformation.Bias; + + if (rc == TIME_ZONE_ID_DAYLIGHT) + bias += timeZoneInformation.DaylightBias; + else if (rc == TIME_ZONE_ID_STANDARD || rc == TIME_ZONE_ID_UNKNOWN) + bias += timeZoneInformation.StandardBias; + return -bias * 60 * 1000; #else time_t localTime = time(0); @@ -424,16 +462,14 @@ static void UnixTimeToFileTime(time_t t, LPFILETIME pft) */ static double calculateDSTOffset(time_t localTime, double utcOffset) { -#if OS(WINCE) - UNUSED_PARAM(localTime); - UNUSED_PARAM(utcOffset); - return 0; -#elif OS(WINDOWS) +#if OS(WINDOWS) FILETIME utcFileTime; UnixTimeToFileTime(localTime, &utcFileTime); SYSTEMTIME utcSystemTime, localSystemTime; - FileTimeToSystemTime(&utcFileTime, &utcSystemTime); - SystemTimeToTzSpecificLocalTime(0, &utcSystemTime, &localSystemTime); + if (!::FileTimeToSystemTime(&utcFileTime, &utcSystemTime)) + return 0; + if (!::SystemTimeToTzSpecificLocalTime(nullptr, &utcSystemTime, &localSystemTime)) + return 0; double offsetTime = (localTime * msPerSecond) + utcOffset; @@ -524,12 +560,10 @@ void initializeDates() static inline double ymdhmsToSeconds(int year, long mon, long day, long hour, long minute, double second) { - double days = (day - 32075) - + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4) - + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4) - - 2440588; - return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second; + int mday = firstDayOfMonth[isLeapYear(year)][mon - 1]; + double ydays = daysFrom1970ToYear(year); + + return (second + minute * secondsPerMinute + hour * secondsPerHour + (mday + day - 1 + ydays) * secondsPerDay); } // We follow the recommendation of RFC 2822 to consider all |