Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.3:Staging:E
libqt4
0001-Fix-DateTime-with-recent-versions-of-tzdat...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Fix-DateTime-with-recent-versions-of-tzdata.patch of Package libqt4
From 6a7f06d70e1267d3d995a3c863ba8f748d45e531 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@digia.com> Date: Fri, 19 Sep 2014 16:24:44 +0400 Subject: [PATCH] Fix DateTime with recent versions of tzdata An backport of http://trac.webkit.org/changeset/150833 needed for correct time KRAT, YAKT and MOS timezones. Task-number: QTBUG-41422 Change-Id: I6e9d1db690fee8d77faa1d76c836bd7b345ce854 Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com> --- .../JavaScriptCore/runtime/DateConstructor.cpp | 6 +- .../JavaScriptCore/runtime/JSGlobalData.cpp | 4 +- .../JavaScriptCore/runtime/JSGlobalData.h | 18 +-- .../javascriptcore/JavaScriptCore/wtf/DateMath.cpp | 135 ++++++++++----------- .../javascriptcore/JavaScriptCore/wtf/DateMath.h | 60 ++++----- .../JavaScriptCore/runtime/DateConstructor.cpp | 6 +- .../Source/JavaScriptCore/runtime/JSGlobalData.cpp | 4 +- .../Source/JavaScriptCore/runtime/JSGlobalData.h | 18 +-- .../webkit/Source/JavaScriptCore/wtf/DateMath.cpp | 135 ++++++++++----------- .../webkit/Source/JavaScriptCore/wtf/DateMath.h | 64 +++++----- .../WebCore/html/BaseDateAndTimeInputType.cpp | 4 +- .../webkit/Source/WebCore/html/MonthInputType.cpp | 4 +- .../webkit/Source/WebCore/html/TimeInputType.cpp | 4 +- 13 files changed, 218 insertions(+), 244 deletions(-) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp index e9a5c29..532eedb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp @@ -129,10 +129,8 @@ ConstructType DateConstructor::getConstructData(ConstructData& constructData) // ECMA 15.9.2 static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const ArgList&) { - time_t localTime = time(0); - tm localTM; - getLocalTime(&localTime, &localTM); - GregorianDateTime ts(exec, localTM); + GregorianDateTime ts; + msToGregorianDateTime(exec, currentTimeMS(), false, ts); DateConversionBuffer date; DateConversionBuffer time; formatDate(ts, date); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp index 1c25c16..f90d495 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp @@ -143,7 +143,6 @@ JSGlobalData::JSGlobalData(bool isShared) , functionCodeBlockBeingReparsed(0) , firstStringifierToMark(0) , markStack(jsArrayVPtr) - , cachedUTCOffset(NaN) #ifndef NDEBUG , mainThreadOnly(false) #endif @@ -259,8 +258,7 @@ JSGlobalData::ClientData::~ClientData() void JSGlobalData::resetDateCache() { - cachedUTCOffset = NaN; - dstOffsetCache.reset(); + localTimeOffsetCache.reset(); cachedDateString = UString(); dateInstanceCache.reset(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h index dcd3289..fc60b84 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h @@ -39,6 +39,7 @@ #include "SmallStrings.h" #include "TimeoutChecker.h" #include "WeakRandom.h" +#include <wtf/DateMath.h> #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/RefCounted.h> @@ -63,21 +64,23 @@ namespace JSC { struct HashTable; struct Instruction; - struct DSTOffsetCache { - DSTOffsetCache() + struct LocalTimeOffsetCache { + LocalTimeOffsetCache() + : start(0.0) + , end(-1.0) + , increment(0.0) { - reset(); } - + void reset() { - offset = 0.0; + offset = LocalTimeOffset(); start = 0.0; end = -1.0; increment = 0.0; } - double offset; + LocalTimeOffset offset; double start; double end; double increment; @@ -179,8 +182,7 @@ namespace JSC { MarkStack markStack; - double cachedUTCOffset; - DSTOffsetCache dstOffsetCache; + LocalTimeOffsetCache localTimeOffsetCache; UString cachedDateString; double cachedDateStringValue; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp index b9a0207..e72f94b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp @@ -377,6 +377,8 @@ int equivalentYearForDST(int year) return year; } +#if !HAVE(TM_GMTOFF) + static int32_t calculateUTCOffset() { #if PLATFORM(BREWMP) @@ -418,23 +420,15 @@ static int32_t calculateUTCOffset() /* * Get the DST offset for the time passed in. */ -static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset) +static double calculateDSTOffset(time_t localTime, double utcOffset) { - if (localTimeSeconds > maxUnixTime) - localTimeSeconds = maxUnixTime; - else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0) - localTimeSeconds += secondsPerDay; - //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset() - double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset; + double offsetTime = (localTime * msPerSecond) + utcOffset; // Offset from UTC but doesn't include DST obviously int offsetHour = msToHours(offsetTime); int offsetMinute = msToMinutes(offsetTime); - // FIXME: time_t has a potential problem in 2038 - time_t localTime = static_cast<time_t>(localTimeSeconds); - tm localTM; getLocalTime(&localTime, &localTM); @@ -446,10 +440,12 @@ static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset return (diff * msPerSecond); } -// Get the DST offset, given a time in UTC -static double calculateDSTOffset(double ms, double utcOffset) +#endif + +// Returns combined offset in millisecond (UTC + DST). +LocalTimeOffset calculateLocalTimeOffset(double ms) { - // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate + // On Mac OS X, the call to localtime (see calculateDSTOffset) will return historically accurate // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript // standard explicitly dictates that historical information should not be considered when // determining DST. For this reason we shift away from years that localtime can handle but would @@ -465,7 +461,23 @@ static double calculateDSTOffset(double ms, double utcOffset) ms = (day * msPerDay) + msToMilliseconds(ms); } - return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset); + double localTimeSeconds = ms / msPerSecond; + if (localTimeSeconds > maxUnixTime) + localTimeSeconds = maxUnixTime; + else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0). + localTimeSeconds += secondsPerDay; + // FIXME: time_t has a potential problem in 2038. + time_t localTime = static_cast<time_t>(localTimeSeconds); + +#if HAVE(TM_GMTOFF) + tm localTM; + getLocalTime(&localTime, &localTM); + return LocalTimeOffset(localTM.tm_isdst, localTM.tm_gmtoff * msPerSecond); +#else + double utcOffset = calculateUTCOffset(); + double dstOffset = calculateDSTOffset(localTime, utcOffset); + return LocalTimeOffset(dstOffset, utcOffset + dstOffset); +#endif } void initializeDates() @@ -838,11 +850,9 @@ double parseDateFromNullTerminatedCharacters(const char* dateString) return NaN; // fall back to local timezone - if (!haveTZ) { - double utcOffset = calculateUTCOffset(); - double dstOffset = calculateDSTOffset(ms, utcOffset); - offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); - } + if (!haveTZ) + offset = calculateLocalTimeOffset(ms).offset / msPerMinute; + return ms - (offset * msPerMinute); } @@ -859,14 +869,14 @@ double timeClip(double t) #if USE(JSC) namespace JSC { -// Get the DST offset for the time passed in. +// Get the combined UTC + DST offset for the time passed in. // // NOTE: The implementation relies on the fact that no time zones have // more than one daylight savings offset change per month. // If this function is called with NaN it returns NaN. -static double getDSTOffset(ExecState* exec, double ms, double utcOffset) +static LocalTimeOffset localTimeOffset(ExecState* exec, double ms) { - DSTOffsetCache& cache = exec->globalData().dstOffsetCache; + LocalTimeOffsetCache& cache = exec->globalData().localTimeOffsetCache; double start = cache.start; double end = cache.end; @@ -878,7 +888,7 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset) double newEnd = end + cache.increment; if (ms <= newEnd) { - double endOffset = calculateDSTOffset(newEnd, utcOffset); + LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd); if (cache.offset == endOffset) { // If the offset at the end of the new interval still matches // the offset in the cache, we grow the cached time interval @@ -886,34 +896,33 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset) cache.end = newEnd; cache.increment = msPerMonth; return endOffset; + } + LocalTimeOffset offset = calculateLocalTimeOffset(ms); + if (offset == endOffset) { + // The offset at the given time is equal to the offset at the + // new end of the interval, so that means that we've just skipped + // the point in time where the DST offset change occurred. Updated + // the interval to reflect this and reset the increment. + cache.start = ms; + cache.end = newEnd; + cache.increment = msPerMonth; } else { - double offset = calculateDSTOffset(ms, utcOffset); - if (offset == endOffset) { - // The offset at the given time is equal to the offset at the - // new end of the interval, so that means that we've just skipped - // the point in time where the DST offset change occurred. Updated - // the interval to reflect this and reset the increment. - cache.start = ms; - cache.end = newEnd; - cache.increment = msPerMonth; - } else { - // The interval contains a DST offset change and the given time is - // before it. Adjust the increment to avoid a linear search for - // the offset change point and change the end of the interval. - cache.increment /= 3; - cache.end = ms; - } - // Update the offset in the cache and return it. - cache.offset = offset; - return offset; + // The interval contains a DST offset change and the given time is + // before it. Adjust the increment to avoid a linear search for + // the offset change point and change the end of the interval. + cache.increment /= 3; + cache.end = ms; } + // Update the offset in the cache and return it. + cache.offset = offset; + return offset; } } // Compute the DST offset for the time and shrink the cache interval // to only contain the time. This allows fast repeated DST offset // computations for the same time. - double offset = calculateDSTOffset(ms, utcOffset); + LocalTimeOffset offset = calculateLocalTimeOffset(ms); cache.offset = offset; cache.start = ms; cache.end = ms; @@ -921,30 +930,14 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset) return offset; } -/* - * Get the difference in milliseconds between this time zone and UTC (GMT) - * NOT including DST. - */ -double getUTCOffset(ExecState* exec) -{ - double utcOffset = exec->globalData().cachedUTCOffset; - if (!isnan(utcOffset)) - return utcOffset; - exec->globalData().cachedUTCOffset = calculateUTCOffset(); - return exec->globalData().cachedUTCOffset; -} - double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC) { double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay); double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds); double result = (day * WTF::msPerDay) + ms; - if (!inputIsUTC) { // convert to UTC - double utcOffset = getUTCOffset(exec); - result -= utcOffset; - result -= getDSTOffset(exec, result, utcOffset); - } + if (!inputIsUTC) + result -= localTimeOffset(exec, result).offset; return result; } @@ -952,12 +945,10 @@ double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double // input is UTC void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm) { - double dstOff = 0.0; - double utcOff = 0.0; + LocalTimeOffset localTime(false, 0); if (!outputIsUTC) { - utcOff = getUTCOffset(exec); - dstOff = getDSTOffset(exec, ms, utcOff); - ms += dstOff + utcOff; + localTime = localTimeOffset(exec, ms); + ms += localTime.offset; } const int year = msToYear(ms); @@ -969,8 +960,8 @@ void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, Gregori tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.year = year - 1900; - tm.isDST = dstOff != 0.0; - tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond); + tm.isDST = localTime.isDST; + tm.utcOffset = localTime.offset / WTF::msPerSecond; tm.timeZone = NULL; } @@ -984,11 +975,9 @@ double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateSt return NaN; // fall back to local timezone - if (!haveTZ) { - double utcOffset = getUTCOffset(exec); - double dstOffset = getDSTOffset(exec, ms, utcOffset); - offset = static_cast<int>((utcOffset + dstOffset) / WTF::msPerMinute); - } + if (!haveTZ) + offset = calculateLocalTimeOffset(ms).offset / msPerMinute; + return ms - (offset * WTF::msPerMinute); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h index 033d25e..15a19bd 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h @@ -50,6 +50,34 @@ #include <wtf/UnusedParam.h> namespace WTF { + +struct LocalTimeOffset { + LocalTimeOffset() + : isDST(false) + , offset(0) + { + } + + LocalTimeOffset(bool isDST, int offset) + : isDST(isDST) + , offset(offset) + { + } + + bool operator==(const LocalTimeOffset& other) + { + return isDST == other.isDST && offset == other.offset; + } + + bool operator!=(const LocalTimeOffset& other) + { + return isDST != other.isDST || offset != other.offset; + } + + bool isDST; + int offset; +}; + void initializeDates(); int equivalentYearForDST(int year); @@ -83,6 +111,9 @@ int dayInYear(double ms, int year); int monthFromDayInYear(int dayInYear, bool leapYear); int dayInMonthFromDayInYear(int dayInYear, bool leapYear); +// Returns combined offset in millisecond (UTC + DST). +LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds); + } // namespace WTF using WTF::dateToDaysFrom1970; @@ -94,6 +125,8 @@ using WTF::msPerDay; using WTF::msPerSecond; using WTF::msToYear; using WTF::secondsPerMinute; +using WTF::LocalTimeOffset; +using WTF::calculateLocalTimeOffset; #if USE(JSC) namespace JSC { @@ -128,33 +161,6 @@ struct GregorianDateTime : Noncopyable { delete [] timeZone; } - GregorianDateTime(ExecState* exec, const tm& inTm) - : second(inTm.tm_sec) - , minute(inTm.tm_min) - , hour(inTm.tm_hour) - , weekDay(inTm.tm_wday) - , monthDay(inTm.tm_mday) - , yearDay(inTm.tm_yday) - , month(inTm.tm_mon) - , year(inTm.tm_year) - , isDST(inTm.tm_isdst) - { - UNUSED_PARAM(exec); -#if HAVE(TM_GMTOFF) - utcOffset = static_cast<int>(inTm.tm_gmtoff); -#else - utcOffset = static_cast<int>(getUTCOffset(exec) / WTF::msPerSecond + (isDST ? WTF::secondsPerHour : 0)); -#endif - -#if HAVE(TM_ZONE) - int inZoneSize = strlen(inTm.tm_zone) + 1; - timeZone = new char[inZoneSize]; - strncpy(timeZone, inTm.tm_zone, inZoneSize); -#else - timeZone = 0; -#endif - } - operator tm() const { tm ret; diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/DateConstructor.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/DateConstructor.cpp index 9bbb688..5f44d2c 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/DateConstructor.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/DateConstructor.cpp @@ -139,10 +139,8 @@ ConstructType DateConstructor::getConstructData(ConstructData& constructData) // ECMA 15.9.2 static EncodedJSValue JSC_HOST_CALL callDate(ExecState* exec) { - time_t localTime = time(0); - tm localTM; - getLocalTime(&localTime, &localTM); - GregorianDateTime ts(exec, localTM); + GregorianDateTime ts; + msToGregorianDateTime(exec, currentTimeMS(), false, ts); DateConversionBuffer date; DateConversionBuffer time; formatDate(ts, date); diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.cpp index 61bbea0..8ddb7d2 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.cpp @@ -165,7 +165,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread , heap(this) , globalObjectCount(0) , dynamicGlobalObject(0) - , cachedUTCOffset(NaN) , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth) , m_regExpCache(new RegExpCache(this)) #if ENABLE(REGEXP_TRACING) @@ -377,8 +376,7 @@ JSGlobalData::ClientData::~ClientData() void JSGlobalData::resetDateCache() { - cachedUTCOffset = NaN; - dstOffsetCache.reset(); + localTimeOffsetCache.reset(); cachedDateString = UString(); cachedDateStringValue = NaN; dateInstanceCache.reset(); diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.h index df36016..6df6390 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSGlobalData.h @@ -42,6 +42,7 @@ #include "TimeoutChecker.h" #include "WeakRandom.h" #include <wtf/BumpPointerAllocator.h> +#include <wtf/DateMath.h> #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/RefCounted.h> @@ -77,21 +78,23 @@ namespace JSC { struct HashTable; struct Instruction; - struct DSTOffsetCache { - DSTOffsetCache() + struct LocalTimeOffsetCache { + LocalTimeOffsetCache() + : start(0.0) + , end(-1.0) + , increment(0.0) { - reset(); } - + void reset() { - offset = 0.0; + offset = LocalTimeOffset(); start = 0.0; end = -1.0; increment = 0.0; } - double offset; + LocalTimeOffset offset; double start; double end; double increment; @@ -233,8 +236,7 @@ namespace JSC { HashSet<JSObject*> stringRecursionCheckVisitedObjects; - double cachedUTCOffset; - DSTOffsetCache dstOffsetCache; + LocalTimeOffsetCache localTimeOffsetCache; UString cachedDateString; double cachedDateStringValue; diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp index b181ee2..d13042b 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp @@ -385,6 +385,8 @@ int equivalentYearForDST(int year) return year; } +#if !HAVE(TM_GMTOFF) + int32_t calculateUTCOffset() { #if PLATFORM(BREWMP) @@ -426,23 +428,15 @@ int32_t calculateUTCOffset() /* * Get the DST offset for the time passed in. */ -static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset) +static double calculateDSTOffset(time_t localTime, double utcOffset) { - if (localTimeSeconds > maxUnixTime) - localTimeSeconds = maxUnixTime; - else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0) - localTimeSeconds += secondsPerDay; - //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset() - double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset; + double offsetTime = (localTime * msPerSecond) + utcOffset; // Offset from UTC but doesn't include DST obviously int offsetHour = msToHours(offsetTime); int offsetMinute = msToMinutes(offsetTime); - // FIXME: time_t has a potential problem in 2038 - time_t localTime = static_cast<time_t>(localTimeSeconds); - tm localTM; getLocalTime(&localTime, &localTM); @@ -454,10 +448,12 @@ static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset return (diff * msPerSecond); } -// Get the DST offset, given a time in UTC -double calculateDSTOffset(double ms, double utcOffset) +#endif + +// Returns combined offset in millisecond (UTC + DST). +LocalTimeOffset calculateLocalTimeOffset(double ms) { - // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate + // On Mac OS X, the call to localtime (see calculateDSTOffset) will return historically accurate // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript // standard explicitly dictates that historical information should not be considered when // determining DST. For this reason we shift away from years that localtime can handle but would @@ -473,7 +469,23 @@ double calculateDSTOffset(double ms, double utcOffset) ms = (day * msPerDay) + msToMilliseconds(ms); } - return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset); + double localTimeSeconds = ms / msPerSecond; + if (localTimeSeconds > maxUnixTime) + localTimeSeconds = maxUnixTime; + else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0). + localTimeSeconds += secondsPerDay; + // FIXME: time_t has a potential problem in 2038. + time_t localTime = static_cast<time_t>(localTimeSeconds); + +#if HAVE(TM_GMTOFF) + tm localTM; + getLocalTime(&localTime, &localTM); + return LocalTimeOffset(localTM.tm_isdst, localTM.tm_gmtoff * msPerSecond); +#else + double utcOffset = calculateUTCOffset(); + double dstOffset = calculateDSTOffset(localTime, utcOffset); + return LocalTimeOffset(dstOffset, utcOffset + dstOffset); +#endif } void initializeDates() @@ -1002,11 +1014,9 @@ double parseDateFromNullTerminatedCharacters(const char* dateString) return NaN; // fall back to local timezone - if (!haveTZ) { - double utcOffset = calculateUTCOffset(); - double dstOffset = calculateDSTOffset(ms, utcOffset); - offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); - } + if (!haveTZ) + offset = calculateLocalTimeOffset(ms).offset / msPerMinute; + return ms - (offset * msPerMinute); } @@ -1023,14 +1033,14 @@ double timeClip(double t) #if USE(JSC) namespace JSC { -// Get the DST offset for the time passed in. +// Get the combined UTC + DST offset for the time passed in. // // NOTE: The implementation relies on the fact that no time zones have // more than one daylight savings offset change per month. // If this function is called with NaN it returns NaN. -static double getDSTOffset(ExecState* exec, double ms, double utcOffset) +static LocalTimeOffset localTimeOffset(ExecState* exec, double ms) { - DSTOffsetCache& cache = exec->globalData().dstOffsetCache; + LocalTimeOffsetCache& cache = exec->globalData().localTimeOffsetCache; double start = cache.start; double end = cache.end; @@ -1042,7 +1052,7 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset) double newEnd = end + cache.increment; if (ms <= newEnd) { - double endOffset = calculateDSTOffset(newEnd, utcOffset); + LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd); if (cache.offset == endOffset) { // If the offset at the end of the new interval still matches // the offset in the cache, we grow the cached time interval @@ -1050,34 +1060,33 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset) cache.end = newEnd; cache.increment = msPerMonth; return endOffset; + } + LocalTimeOffset offset = calculateLocalTimeOffset(ms); + if (offset == endOffset) { + // The offset at the given time is equal to the offset at the + // new end of the interval, so that means that we've just skipped + // the point in time where the DST offset change occurred. Updated + // the interval to reflect this and reset the increment. + cache.start = ms; + cache.end = newEnd; + cache.increment = msPerMonth; } else { - double offset = calculateDSTOffset(ms, utcOffset); - if (offset == endOffset) { - // The offset at the given time is equal to the offset at the - // new end of the interval, so that means that we've just skipped - // the point in time where the DST offset change occurred. Updated - // the interval to reflect this and reset the increment. - cache.start = ms; - cache.end = newEnd; - cache.increment = msPerMonth; - } else { - // The interval contains a DST offset change and the given time is - // before it. Adjust the increment to avoid a linear search for - // the offset change point and change the end of the interval. - cache.increment /= 3; - cache.end = ms; - } - // Update the offset in the cache and return it. - cache.offset = offset; - return offset; + // The interval contains a DST offset change and the given time is + // before it. Adjust the increment to avoid a linear search for + // the offset change point and change the end of the interval. + cache.increment /= 3; + cache.end = ms; } + // Update the offset in the cache and return it. + cache.offset = offset; + return offset; } } // Compute the DST offset for the time and shrink the cache interval // to only contain the time. This allows fast repeated DST offset // computations for the same time. - double offset = calculateDSTOffset(ms, utcOffset); + LocalTimeOffset offset = calculateLocalTimeOffset(ms); cache.offset = offset; cache.start = ms; cache.end = ms; @@ -1085,30 +1094,14 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset) return offset; } -/* - * Get the difference in milliseconds between this time zone and UTC (GMT) - * NOT including DST. - */ -double getUTCOffset(ExecState* exec) -{ - double utcOffset = exec->globalData().cachedUTCOffset; - if (!isnan(utcOffset)) - return utcOffset; - exec->globalData().cachedUTCOffset = calculateUTCOffset(); - return exec->globalData().cachedUTCOffset; -} - double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC) { double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay); double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds); double result = (day * WTF::msPerDay) + ms; - if (!inputIsUTC) { // convert to UTC - double utcOffset = getUTCOffset(exec); - result -= utcOffset; - result -= getDSTOffset(exec, result, utcOffset); - } + if (!inputIsUTC) + result -= localTimeOffset(exec, result).offset; return result; } @@ -1116,12 +1109,10 @@ double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double // input is UTC void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm) { - double dstOff = 0.0; - double utcOff = 0.0; + LocalTimeOffset localTime(false, 0); if (!outputIsUTC) { - utcOff = getUTCOffset(exec); - dstOff = getDSTOffset(exec, ms, utcOff); - ms += dstOff + utcOff; + localTime = localTimeOffset(exec, ms); + ms += localTime.offset; } const int year = msToYear(ms); @@ -1133,8 +1124,8 @@ void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, Gregori tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.year = year - 1900; - tm.isDST = dstOff != 0.0; - tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond); + tm.isDST = localTime.isDST; + tm.utcOffset = localTime.offset / WTF::msPerSecond; tm.timeZone = nullptr; } @@ -1148,11 +1139,9 @@ double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateSt return NaN; // fall back to local timezone - if (!haveTZ) { - double utcOffset = getUTCOffset(exec); - double dstOffset = getDSTOffset(exec, ms, utcOffset); - offset = static_cast<int>((utcOffset + dstOffset) / WTF::msPerMinute); - } + if (!haveTZ) + offset = calculateLocalTimeOffset(ms).offset / msPerMinute; + return ms - (offset * WTF::msPerMinute); } diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.h b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.h index 2ac284e..bb59c8d 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.h @@ -54,6 +54,34 @@ #include <wtf/UnusedParam.h> namespace WTF { + +struct LocalTimeOffset { + LocalTimeOffset() + : isDST(false) + , offset(0) + { + } + + LocalTimeOffset(bool isDST, int offset) + : isDST(isDST) + , offset(offset) + { + } + + bool operator==(const LocalTimeOffset& other) + { + return isDST == other.isDST && offset == other.offset; + } + + bool operator!=(const LocalTimeOffset& other) + { + return isDST != other.isDST || offset != other.offset; + } + + bool isDST; + int offset; +}; + void initializeDates(); int equivalentYearForDST(int year); @@ -88,9 +116,8 @@ int dayInYear(double ms, int year); int monthFromDayInYear(int dayInYear, bool leapYear); int dayInMonthFromDayInYear(int dayInYear, bool leapYear); -// Returns offset milliseconds for UTC and DST. -int32_t calculateUTCOffset(); -double calculateDSTOffset(double ms, double utcOffset); +// Returns combined offset in millisecond (UTC + DST). +LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds); } // namespace WTF @@ -106,8 +133,8 @@ using WTF::msPerSecond; using WTF::msToYear; using WTF::secondsPerMinute; using WTF::parseDateFromNullTerminatedCharacters; -using WTF::calculateUTCOffset; -using WTF::calculateDSTOffset; +using WTF::LocalTimeOffset; +using WTF::calculateLocalTimeOffset; #if USE(JSC) namespace JSC { @@ -138,33 +165,6 @@ public: { } - GregorianDateTime(ExecState* exec, const tm& inTm) - : second(inTm.tm_sec) - , minute(inTm.tm_min) - , hour(inTm.tm_hour) - , weekDay(inTm.tm_wday) - , monthDay(inTm.tm_mday) - , yearDay(inTm.tm_yday) - , month(inTm.tm_mon) - , year(inTm.tm_year) - , isDST(inTm.tm_isdst) - { - UNUSED_PARAM(exec); -#if HAVE(TM_GMTOFF) - utcOffset = static_cast<int>(inTm.tm_gmtoff); -#else - utcOffset = static_cast<int>(getUTCOffset(exec) / WTF::msPerSecond + (isDST ? WTF::secondsPerHour : 0)); -#endif - -#if HAVE(TM_ZONE) - int inZoneSize = strlen(inTm.tm_zone) + 1; - timeZone = adoptArrayPtr(new char[inZoneSize]); - strncpy(timeZone.get(), inTm.tm_zone, inZoneSize); -#else - timeZone = nullptr; -#endif - } - operator tm() const { tm ret; diff --git a/src/3rdparty/webkit/Source/WebCore/html/BaseDateAndTimeInputType.cpp b/src/3rdparty/webkit/Source/WebCore/html/BaseDateAndTimeInputType.cpp index e52c103..e24379a 100644 --- a/src/3rdparty/webkit/Source/WebCore/html/BaseDateAndTimeInputType.cpp +++ b/src/3rdparty/webkit/Source/WebCore/html/BaseDateAndTimeInputType.cpp @@ -102,9 +102,7 @@ bool BaseDateAndTimeInputType::supportsRangeLimitation() const double BaseDateAndTimeInputType::defaultValueForStepUp() const { double ms = currentTimeMS(); - double utcOffset = calculateUTCOffset(); - double dstOffset = calculateDSTOffset(ms, utcOffset); - int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); + int offset = calculateLocalTimeOffset(ms).offset / msPerMinute; return ms + (offset * msPerMinute); } diff --git a/src/3rdparty/webkit/Source/WebCore/html/MonthInputType.cpp b/src/3rdparty/webkit/Source/WebCore/html/MonthInputType.cpp index 06e3726..9390a07 100644 --- a/src/3rdparty/webkit/Source/WebCore/html/MonthInputType.cpp +++ b/src/3rdparty/webkit/Source/WebCore/html/MonthInputType.cpp @@ -82,9 +82,7 @@ String MonthInputType::serializeWithMilliseconds(double value) const double MonthInputType::defaultValueForStepUp() const { double current = currentTimeMS(); - double utcOffset = calculateUTCOffset(); - double dstOffset = calculateDSTOffset(current, utcOffset); - int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); + int offset = calculateLocalTimeOffset(current).offset / msPerMinute; current += offset * msPerMinute; DateComponents date; diff --git a/src/3rdparty/webkit/Source/WebCore/html/TimeInputType.cpp b/src/3rdparty/webkit/Source/WebCore/html/TimeInputType.cpp index f89ec33..bbfc86d 100644 --- a/src/3rdparty/webkit/Source/WebCore/html/TimeInputType.cpp +++ b/src/3rdparty/webkit/Source/WebCore/html/TimeInputType.cpp @@ -64,9 +64,7 @@ DateComponents::Type TimeInputType::dateType() const double TimeInputType::defaultValueForStepUp() const { double current = currentTimeMS(); - double utcOffset = calculateUTCOffset(); - double dstOffset = calculateDSTOffset(current, utcOffset); - int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); + int offset = calculateLocalTimeOffset(current).offset / msPerMinute; current += offset * msPerMinute; DateComponents date; -- 2.0.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor