summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-09-19 15:34:59 +0400
committerAllan Sandfeld Jensen <allan.jensen@digia.com>2014-09-22 14:32:17 +0200
commit5b87292cbc4f3b94ed6426c526c4f3dcca3eaa55 (patch)
treeae74d2e9cd90d503ae179e83616e278d19374b39
parentdd8b0a0df9b12aae4c55e6bd548b5af5175dc818 (diff)
downloadqtscript-5b87292cbc4f3b94ed6426c526c4f3dcca3eaa55.tar.gz
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. Change-Id: I3b5369d1427757c0d638865324a36e43dcaa60bf Task-number: QTBUG-41422 Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h18
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp135
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h60
5 files changed, 108 insertions, 115 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 e38a2bc..6431978 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;
@@ -180,8 +183,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;