Title: [175078] trunk
Revision
175078
Author
[email protected]
Date
2014-10-22 18:15:08 -0700 (Wed, 22 Oct 2014)

Log Message

String(new Date(Mar 30 2014 01:00:00)) is wrong in CET
https://bugs.webkit.org/show_bug.cgi?id=130967

Patch by Byungseon Shin <[email protected]> on 2014-10-22
Reviewed by Mark Lam.

Source/_javascript_Core:

By definition of calculateLocalTimeOffset, input time should be UTC time.
But there are many cases when input time is based on local time.
So, it gives erroneous results while calculating offset of DST boundary time.
By adding a argument to distinguish UTC and local time, we can get the correct offset.

* _javascript_Core.order:
* runtime/DateConstructor.cpp:
(JSC::constructDate):
(JSC::callDate):
(JSC::dateUTC):
* runtime/DateInstance.cpp:
(JSC::DateInstance::calculateGregorianDateTime):
(JSC::DateInstance::calculateGregorianDateTimeUTC):
* runtime/DatePrototype.cpp:
(JSC::setNewValueFromTimeArgs):
(JSC::setNewValueFromDateArgs):
(JSC::dateProtoFuncSetMilliSeconds):
(JSC::dateProtoFuncSetUTCMilliseconds):
(JSC::dateProtoFuncSetSeconds):
(JSC::dateProtoFuncSetUTCSeconds):
(JSC::dateProtoFuncSetMinutes):
(JSC::dateProtoFuncSetUTCMinutes):
(JSC::dateProtoFuncSetHours):
(JSC::dateProtoFuncSetUTCHours):
(JSC::dateProtoFuncSetDate):
(JSC::dateProtoFuncSetUTCDate):
(JSC::dateProtoFuncSetMonth):
(JSC::dateProtoFuncSetUTCMonth):
(JSC::dateProtoFuncSetFullYear):
(JSC::dateProtoFuncSetUTCFullYear):
(JSC::dateProtoFuncSetYear):
* runtime/JSDateMath.cpp:
(JSC::localTimeOffset):
(JSC::gregorianDateTimeToMS):
(JSC::msToGregorianDateTime):
(JSC::parseDateFromNullTerminatedCharacters):
* runtime/JSDateMath.h:
* runtime/VM.h:
(JSC::LocalTimeOffsetCache::LocalTimeOffsetCache):
(JSC::LocalTimeOffsetCache::reset):
Passing TimeType argument to distingush UTC time and local time.

Source/WTF:

By definition of calculateLocalTimeOffset, input time should be UTC time.
But there are many cases when input time is based on local time.
So, it gives erroneous results while calculating offset of DST boundary time.
By adding a argument to distinguish UTC and local time, we can get the correct offset.

* wtf/DateMath.cpp:
(WTF::calculateLocalTimeOffset):
(WTF::parseDateFromNullTerminatedCharacters):
Compensate time offset depends on UTC time or local time.
* wtf/DateMath.h:
Add argument to differenciate UTC or local time.

LayoutTests:

Set latest DST timezone boundary values on
<http://www.timeanddate.com/time/zone/usa/los-angeles>

* js/dom/script-tests/date-DST-time-cusps.js:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (175077 => 175078)


--- trunk/LayoutTests/ChangeLog	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/LayoutTests/ChangeLog	2014-10-23 01:15:08 UTC (rev 175078)
@@ -1,3 +1,15 @@
+2014-10-22  Byungseon Shin  <[email protected]>
+
+        String(new Date(Mar 30 2014 01:00:00)) is wrong in CET
+        https://bugs.webkit.org/show_bug.cgi?id=130967
+
+        Reviewed by Mark Lam.
+
+        Set latest DST timezone boundary values on
+        <http://www.timeanddate.com/time/zone/usa/los-angeles>
+
+        * js/dom/script-tests/date-DST-time-cusps.js:
+
 2014-10-22  Brent Fulgham  <[email protected]>
 
         [Win] Rebaseline various tests after switching to Windows rendering for native controls.

Modified: trunk/LayoutTests/js/dom/script-tests/date-DST-time-cusps.js (175077 => 175078)


--- trunk/LayoutTests/js/dom/script-tests/date-DST-time-cusps.js	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/LayoutTests/js/dom/script-tests/date-DST-time-cusps.js	2014-10-23 01:15:08 UTC (rev 175078)
@@ -7,11 +7,11 @@
 );
 
 var testCases = [];
-if ((new Date(2009, 9, 1)).toString().match("PDT")) {
-    testCases.push(["(new Date(1982, 2, 14, 2, 10)).getHours()", "3"]);
-    testCases.push(["(new Date(1982, 2, 14, 2)).getHours()", "3"]);
-    testCases.push(["(new Date(1982, 11, 7, 1, 10)).getTimezoneOffset()", "480"]);
-    testCases.push(["(new Date(1982, 11, 7, 1)).getTimezoneOffset()", "480"]);
+if ((new Date(2014, 8, 1)).toString().match("PDT")) {
+    testCases.push(["(new Date('Mar 09 2014 03:00:00')).getHours()", "3"]);
+    testCases.push(["(new Date('Mar 09 2014 03:00:00')).getTimezoneOffset()", "420"]);
+    testCases.push(["(new Date('Nov 02 2014 01:00:00')).getHours()", "1"]);
+    testCases.push(["(new Date('Nov 02 2014 01:00:00')).getTimezoneOffset()", "480"]);
 }
 
 var errors = [];

Modified: trunk/Source/_javascript_Core/ChangeLog (175077 => 175078)


--- trunk/Source/_javascript_Core/ChangeLog	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-10-23 01:15:08 UTC (rev 175078)
@@ -1,3 +1,52 @@
+2014-10-22  Byungseon Shin  <[email protected]>
+
+        String(new Date(Mar 30 2014 01:00:00)) is wrong in CET
+        https://bugs.webkit.org/show_bug.cgi?id=130967
+
+        Reviewed by Mark Lam.
+
+        By definition of calculateLocalTimeOffset, input time should be UTC time.
+        But there are many cases when input time is based on local time.
+        So, it gives erroneous results while calculating offset of DST boundary time.
+        By adding a argument to distinguish UTC and local time, we can get the correct offset.
+
+        * _javascript_Core.order:
+        * runtime/DateConstructor.cpp:
+        (JSC::constructDate):
+        (JSC::callDate):
+        (JSC::dateUTC):
+        * runtime/DateInstance.cpp:
+        (JSC::DateInstance::calculateGregorianDateTime):
+        (JSC::DateInstance::calculateGregorianDateTimeUTC):
+        * runtime/DatePrototype.cpp:
+        (JSC::setNewValueFromTimeArgs):
+        (JSC::setNewValueFromDateArgs):
+        (JSC::dateProtoFuncSetMilliSeconds):
+        (JSC::dateProtoFuncSetUTCMilliseconds):
+        (JSC::dateProtoFuncSetSeconds):
+        (JSC::dateProtoFuncSetUTCSeconds):
+        (JSC::dateProtoFuncSetMinutes):
+        (JSC::dateProtoFuncSetUTCMinutes):
+        (JSC::dateProtoFuncSetHours):
+        (JSC::dateProtoFuncSetUTCHours):
+        (JSC::dateProtoFuncSetDate):
+        (JSC::dateProtoFuncSetUTCDate):
+        (JSC::dateProtoFuncSetMonth):
+        (JSC::dateProtoFuncSetUTCMonth):
+        (JSC::dateProtoFuncSetFullYear):
+        (JSC::dateProtoFuncSetUTCFullYear):
+        (JSC::dateProtoFuncSetYear):
+        * runtime/JSDateMath.cpp:
+        (JSC::localTimeOffset):
+        (JSC::gregorianDateTimeToMS):
+        (JSC::msToGregorianDateTime):
+        (JSC::parseDateFromNullTerminatedCharacters):
+        * runtime/JSDateMath.h:
+        * runtime/VM.h:
+        (JSC::LocalTimeOffsetCache::LocalTimeOffsetCache):
+        (JSC::LocalTimeOffsetCache::reset):
+        Passing TimeType argument to distingush UTC time and local time.
+
 2014-10-22  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Fix generator importing of protocol type "any", treat as value

Modified: trunk/Source/_javascript_Core/_javascript_Core.order (175077 => 175078)


--- trunk/Source/_javascript_Core/_javascript_Core.order	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/_javascript_Core.order	2014-10-23 01:15:08 UTC (rev 175078)
@@ -3196,7 +3196,6 @@
 __ZN3JSCL19formateDateInstanceEPNS_9ExecStateENS_14DateTimeFormatEb
 __ZNK3JSC12DateInstance29calculateGregorianDateTimeUTCEPNS_9ExecStateE
 __ZN3JSC17DateInstanceCache3addEd
-__ZN3JSC21msToGregorianDateTimeEPNS_9ExecStateEdbRN3WTF17GregorianDateTimeE
 __ZN3WTF8msToYearEd
 __ZN3WTF11msToMinutesEd
 __ZN3WTF9msToHoursEd
@@ -3272,7 +3271,6 @@
 __ZN3JSC14MacroAssembler20convertInt32ToDoubleENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5Imm32ENS_12X86Registers13XMMRegisterIDE
 __ZN3JSC3JIT15emitSlow_op_modEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateE
-__ZN3JSC21gregorianDateTimeToMSEPNS_9ExecStateERKN3WTF17GregorianDateTimeEdb
 __ZN3WTF18dateToDaysFrom1970Eiii
 __ZN3JSC10PrefixNode11emitBracketERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC16globalFuncEscapeEPNS_9ExecStateE

Modified: trunk/Source/_javascript_Core/runtime/DateConstructor.cpp (175077 => 175078)


--- trunk/Source/_javascript_Core/runtime/DateConstructor.cpp	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/runtime/DateConstructor.cpp	2014-10-23 01:15:08 UTC (rev 175078)
@@ -162,7 +162,7 @@
             t.setSecond(JSC::toInt32(doubleArguments[5]));
             t.setIsDST(-1);
             double ms = (numArgs >= 7) ? doubleArguments[6] : 0;
-            value = gregorianDateTimeToMS(vm, t, ms, false);
+            value = gregorianDateTimeToMS(vm, t, ms, WTF::LocalTime);
         }
     }
 
@@ -186,7 +186,7 @@
 {
     VM& vm = exec->vm();
     GregorianDateTime ts;
-    msToGregorianDateTime(vm, currentTimeMS(), false, ts);
+    msToGregorianDateTime(vm, currentTimeMS(), WTF::LocalTime, ts);
     return JSValue::encode(jsNontrivialString(&vm, formatDateTime(ts, DateTimeFormatDateAndTime, false)));
 }
 
@@ -240,7 +240,7 @@
     t.setMinute(JSC::toInt32(doubleArguments[4]));
     t.setSecond(JSC::toInt32(doubleArguments[5]));
     double ms = (n >= 7) ? doubleArguments[6] : 0;
-    return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec->vm(), t, ms, true))));
+    return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec->vm(), t, ms, WTF::UTCTime))));
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/DateInstance.cpp (175077 => 175078)


--- trunk/Source/_javascript_Core/runtime/DateInstance.cpp	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/runtime/DateInstance.cpp	2014-10-23 01:15:08 UTC (rev 175078)
@@ -69,7 +69,7 @@
         m_data = vm.dateInstanceCache.add(milli);
 
     if (m_data->m_gregorianDateTimeCachedForMS != milli) {
-        msToGregorianDateTime(vm, milli, false, m_data->m_cachedGregorianDateTime);
+        msToGregorianDateTime(vm, milli, WTF::LocalTime, m_data->m_cachedGregorianDateTime);
         m_data->m_gregorianDateTimeCachedForMS = milli;
     }
     return &m_data->m_cachedGregorianDateTime;
@@ -86,7 +86,7 @@
         m_data = vm.dateInstanceCache.add(milli);
 
     if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) {
-        msToGregorianDateTime(vm, milli, true, m_data->m_cachedGregorianDateTimeUTC);
+        msToGregorianDateTime(vm, milli, WTF::UTCTime, m_data->m_cachedGregorianDateTimeUTC);
         m_data->m_gregorianDateTimeUTCCachedForMS = milli;
     }
     return &m_data->m_cachedGregorianDateTimeUTC;

Modified: trunk/Source/_javascript_Core/runtime/DatePrototype.cpp (175077 => 175078)


--- trunk/Source/_javascript_Core/runtime/DatePrototype.cpp	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/runtime/DatePrototype.cpp	2014-10-23 01:15:08 UTC (rev 175078)
@@ -859,7 +859,7 @@
     return JSValue::encode(result);
 }
 
-static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC)
+static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse, WTF::TimeType inputTimeType)
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.inherits(DateInstance::info()))
@@ -878,7 +878,7 @@
     double secs = floor(milli / msPerSecond);
     double ms = milli - secs * msPerSecond;
 
-    const GregorianDateTime* other = inputIsUTC 
+    const GregorianDateTime* other = inputTimeType == WTF::UTCTime
         ? thisDateObj->gregorianDateTimeUTC(exec)
         : thisDateObj->gregorianDateTime(exec);
     if (!other)
@@ -892,12 +892,12 @@
         return JSValue::encode(result);
     } 
     
-    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputIsUTC));
+    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputTimeType));
     thisDateObj->setInternalValue(vm, result);
     return JSValue::encode(result);
 }
 
-static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC)
+static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse, WTF::TimeType inputTimeType)
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.inherits(DateInstance::info()))
@@ -916,10 +916,10 @@
 
     GregorianDateTime gregorianDateTime; 
     if (numArgsToUse == 3 && std::isnan(milli)) 
-        msToGregorianDateTime(vm, 0, true, gregorianDateTime);
+        msToGregorianDateTime(vm, 0, WTF::UTCTime, gregorianDateTime);
     else { 
         ms = milli - floor(milli / msPerSecond) * msPerSecond; 
-        const GregorianDateTime* other = inputIsUTC 
+        const GregorianDateTime* other = inputTimeType == WTF::UTCTime
             ? thisDateObj->gregorianDateTimeUTC(exec)
             : thisDateObj->gregorianDateTime(exec);
         if (!other)
@@ -933,93 +933,93 @@
         return JSValue::encode(result);
     } 
            
-    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputIsUTC));
+    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputTimeType));
     thisDateObj->setInternalValue(vm, result);
     return JSValue::encode(result);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 1, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::LocalTime;
+    return setNewValueFromTimeArgs(exec, 1, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 1, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::UTCTime;
+    return setNewValueFromTimeArgs(exec, 1, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 2, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::LocalTime;
+    return setNewValueFromTimeArgs(exec, 2, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 2, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::UTCTime;
+    return setNewValueFromTimeArgs(exec, 2, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 3, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::LocalTime;
+    return setNewValueFromTimeArgs(exec, 3, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 3, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::UTCTime;
+    return setNewValueFromTimeArgs(exec, 3, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 4, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::LocalTime;
+    return setNewValueFromTimeArgs(exec, 4, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 4, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::UTCTime;
+    return setNewValueFromTimeArgs(exec, 4, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, 1, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::LocalTime;
+    return setNewValueFromDateArgs(exec, 1, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, 1, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::UTCTime;
+    return setNewValueFromDateArgs(exec, 1, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, 2, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::LocalTime;
+    return setNewValueFromDateArgs(exec, 2, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, 2, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::UTCTime;
+    return setNewValueFromDateArgs(exec, 2, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, 3, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::LocalTime;
+    return setNewValueFromDateArgs(exec, 3, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, 3, inputIsUTC);
+    const WTF::TimeType inputTimeType = WTF::UTCTime;
+    return setNewValueFromDateArgs(exec, 3, inputTimeType);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
@@ -1043,7 +1043,7 @@
     if (std::isnan(milli))
         // Based on ECMA 262 B.2.5 (setYear)
         // the time must be reset to +0 if it is NaN.
-        msToGregorianDateTime(vm, 0, true, gregorianDateTime);
+        msToGregorianDateTime(vm, 0, WTF::UTCTime, gregorianDateTime);
     else {
         double secs = floor(milli / msPerSecond);
         ms = milli - secs * msPerSecond;
@@ -1059,7 +1059,7 @@
     }
 
     gregorianDateTime.setYear(toInt32((year >= 0 && year <= 99) ? (year + 1900) : year));
-    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, false));
+    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, WTF::LocalTime));
     thisDateObj->setInternalValue(vm, result);
     return JSValue::encode(result);
 }

Modified: trunk/Source/_javascript_Core/runtime/JSDateMath.cpp (175077 => 175078)


--- trunk/Source/_javascript_Core/runtime/JSDateMath.cpp	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/runtime/JSDateMath.cpp	2014-10-23 01:15:08 UTC (rev 175078)
@@ -132,13 +132,14 @@
 // 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 LocalTimeOffset localTimeOffset(VM& vm, double ms)
+static LocalTimeOffset localTimeOffset(VM& vm, double ms, WTF::TimeType inputTimeType = WTF::UTCTime)
 {
     LocalTimeOffsetCache& cache = vm.localTimeOffsetCache;
     double start = cache.start;
     double end = cache.end;
+    WTF::TimeType cachedTimeType = cache.timeType;
 
-    if (start <= ms) {
+    if (cachedTimeType == inputTimeType && start <= ms) {
         // If the time fits in the cached interval, return the cached offset.
         if (ms <= end) return cache.offset;
 
@@ -146,7 +147,7 @@
         double newEnd = end + cache.increment;
 
         if (ms <= newEnd) {
-            LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd);
+            LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd, inputTimeType);
             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
@@ -155,7 +156,7 @@
                 cache.increment = msPerMonth;
                 return endOffset;
             }
-            LocalTimeOffset offset = calculateLocalTimeOffset(ms);
+            LocalTimeOffset offset = calculateLocalTimeOffset(ms, inputTimeType);
             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
@@ -180,31 +181,31 @@
     // 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.
-    LocalTimeOffset offset = calculateLocalTimeOffset(ms);
+    LocalTimeOffset offset = calculateLocalTimeOffset(ms, inputTimeType);
     cache.offset = offset;
     cache.start = ms;
     cache.end = ms;
     cache.increment = msPerMonth;
+    cache.timeType = inputTimeType;
     return offset;
 }
 
-double gregorianDateTimeToMS(VM& vm, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
+double gregorianDateTimeToMS(VM& vm, const GregorianDateTime& t, double milliSeconds, WTF::TimeType inputTimeType)
 {
     double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay());
     double ms = timeToMS(t.hour(), t.minute(), t.second(), milliSeconds);
-    double result = (day * WTF::msPerDay) + ms;
+    double localTimeResult = (day * WTF::msPerDay) + ms;
+    double localToUTCTimeOffset = inputTimeType == LocalTime
+        ? localTimeOffset(vm, localTimeResult, inputTimeType).offset : 0;
 
-    if (!inputIsUTC)
-        result -= localTimeOffset(vm, result).offset;
-
-    return result;
+    return localTimeResult - localToUTCTimeOffset;
 }
 
 // input is UTC
-void msToGregorianDateTime(VM& vm, double ms, bool outputIsUTC, GregorianDateTime& tm)
+void msToGregorianDateTime(VM& vm, double ms, WTF::TimeType outputTimeType, GregorianDateTime& tm)
 {
     LocalTimeOffset localTime;
-    if (!outputIsUTC) {
+    if (outputTimeType == WTF::LocalTime) {
         localTime = localTimeOffset(vm, ms);
         ms += localTime.offset;
     }
@@ -226,15 +227,15 @@
 {
     bool haveTZ;
     int offset;
-    double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
-    if (std::isnan(ms))
+    double localTimeMS = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
+    if (std::isnan(localTimeMS))
         return std::numeric_limits<double>::quiet_NaN();
 
-    // fall back to local timezone
+    // fall back to local timezone.
     if (!haveTZ)
-        offset = localTimeOffset(vm, ms).offset / WTF::msPerMinute;
+        offset = localTimeOffset(vm, localTimeMS, WTF::LocalTime).offset / WTF::msPerMinute;
 
-    return ms - (offset * WTF::msPerMinute);
+    return localTimeMS - (offset * WTF::msPerMinute);
 }
 
 double parseDate(VM& vm, const String& date)

Modified: trunk/Source/_javascript_Core/runtime/JSDateMath.h (175077 => 175078)


--- trunk/Source/_javascript_Core/runtime/JSDateMath.h	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/runtime/JSDateMath.h	2014-10-23 01:15:08 UTC (rev 175078)
@@ -50,8 +50,8 @@
 
 class VM;
 
-JS_EXPORT_PRIVATE void msToGregorianDateTime(VM&, double, bool outputIsUTC, GregorianDateTime&);
-JS_EXPORT_PRIVATE double gregorianDateTimeToMS(VM&, const GregorianDateTime&, double, bool inputIsUTC);
+JS_EXPORT_PRIVATE void msToGregorianDateTime(VM&, double, WTF::TimeType outputTimeType, GregorianDateTime&);
+JS_EXPORT_PRIVATE double gregorianDateTimeToMS(VM&, const GregorianDateTime&, double, WTF::TimeType inputTimeType);
 JS_EXPORT_PRIVATE double getUTCOffset(VM&);
 JS_EXPORT_PRIVATE double parseDateFromNullTerminatedCharacters(VM&, const char* dateString);
 JS_EXPORT_PRIVATE double parseDate(VM&, const WTF::String&);

Modified: trunk/Source/_javascript_Core/runtime/VM.h (175077 => 175078)


--- trunk/Source/_javascript_Core/runtime/VM.h	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2014-10-23 01:15:08 UTC (rev 175078)
@@ -132,6 +132,7 @@
         : start(0.0)
         , end(-1.0)
         , increment(0.0)
+        , timeType(WTF::UTCTime)
     {
     }
 
@@ -141,12 +142,14 @@
         start = 0.0;
         end = -1.0;
         increment = 0.0;
+        timeType = WTF::UTCTime;
     }
 
     LocalTimeOffset offset;
     double start;
     double end;
     double increment;
+    WTF::TimeType timeType;
 };
 
 class ConservativeRoots;

Modified: trunk/Source/WTF/ChangeLog (175077 => 175078)


--- trunk/Source/WTF/ChangeLog	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/WTF/ChangeLog	2014-10-23 01:15:08 UTC (rev 175078)
@@ -1,3 +1,22 @@
+2014-10-22  Byungseon Shin  <[email protected]>
+
+        String(new Date(Mar 30 2014 01:00:00)) is wrong in CET
+        https://bugs.webkit.org/show_bug.cgi?id=130967
+
+        Reviewed by Mark Lam.
+
+        By definition of calculateLocalTimeOffset, input time should be UTC time.
+        But there are many cases when input time is based on local time.
+        So, it gives erroneous results while calculating offset of DST boundary time.
+        By adding a argument to distinguish UTC and local time, we can get the correct offset.
+
+        * wtf/DateMath.cpp:
+        (WTF::calculateLocalTimeOffset):
+        (WTF::parseDateFromNullTerminatedCharacters):
+        Compensate time offset depends on UTC time or local time.
+        * wtf/DateMath.h:
+        Add argument to differenciate UTC or local time.
+
 2014-10-21  Dániel Bátyai  <[email protected]>
 
         Fix FTL Native Inlining for EFL

Modified: trunk/Source/WTF/wtf/DateMath.cpp (175077 => 175078)


--- trunk/Source/WTF/wtf/DateMath.cpp	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/WTF/wtf/DateMath.cpp	2014-10-23 01:15:08 UTC (rev 175078)
@@ -361,8 +361,6 @@
     return year;
 }
 
-#if !HAVE(TM_GMTOFF)
-
 static int32_t calculateUTCOffset()
 {
 #if OS(WINDOWS)
@@ -412,6 +410,8 @@
 #endif
 }
 
+#if !HAVE(TM_GMTOFF)
+
 #if OS(WINDOWS)
 // Code taken from http://support.microsoft.com/kb/167296
 static void UnixTimeToFileTime(time_t t, LPFILETIME pft)
@@ -471,8 +471,16 @@
 #endif
 
 // Returns combined offset in millisecond (UTC + DST).
-LocalTimeOffset calculateLocalTimeOffset(double ms)
+LocalTimeOffset calculateLocalTimeOffset(double ms, TimeType inputTimeType)
 {
+#if HAVE(TM_GMTOFF)
+    double localToUTCTimeOffset = inputTimeType == LocalTime ? calculateUTCOffset() : 0;
+#else
+    double localToUTCTimeOffset = calculateUTCOffset();
+#endif
+    if (inputTimeType == LocalTime)
+        ms -= localToUTCTimeOffset;
+
     // 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
@@ -502,9 +510,8 @@
     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);
+    double dstOffset = calculateDSTOffset(localTime, localToUTCTimeOffset);
+    return LocalTimeOffset(dstOffset, localToUTCTimeOffset + dstOffset);
 #endif
 }
 
@@ -1095,7 +1102,7 @@
 
     // fall back to local timezone
     if (!haveTZ)
-        offset = calculateLocalTimeOffset(ms).offset / msPerMinute;
+        offset = calculateLocalTimeOffset(ms, LocalTime).offset / msPerMinute; // ms value is in local time milliseconds.
 
     return ms - (offset * msPerMinute);
 }

Modified: trunk/Source/WTF/wtf/DateMath.h (175077 => 175078)


--- trunk/Source/WTF/wtf/DateMath.h	2014-10-23 01:13:35 UTC (rev 175077)
+++ trunk/Source/WTF/wtf/DateMath.h	2014-10-23 01:15:08 UTC (rev 175078)
@@ -53,6 +53,11 @@
 
 namespace WTF {
 
+enum TimeType {
+    UTCTime = 0,
+    LocalTime
+};
+
 struct LocalTimeOffset {
     LocalTimeOffset()
         : isDST(false)
@@ -126,7 +131,7 @@
 WTF_EXPORT_PRIVATE int dayInMonthFromDayInYear(int dayInYear, bool leapYear);
 
 // Returns combined offset in millisecond (UTC + DST).
-WTF_EXPORT_PRIVATE LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds);
+WTF_EXPORT_PRIVATE LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds, TimeType = UTCTime);
 
 } // namespace WTF
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to