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()))
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)
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()))
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)
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)
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;
}
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);
}
// 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;
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
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
// 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;
}
{
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)