static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec) { double doubleArguments[7] = { exec->argument(0).toNumber(exec), exec->argument(1).toNumber(exec), exec->argument(2).toNumber(exec), exec->argument(3).toNumber(exec), exec->argument(4).toNumber(exec), exec->argument(5).toNumber(exec), exec->argument(6).toNumber(exec) }; int n = exec->argumentCount(); if (isnan(doubleArguments[0]) || isnan(doubleArguments[1]) || (n >= 3 && isnan(doubleArguments[2])) || (n >= 4 && isnan(doubleArguments[3])) || (n >= 5 && isnan(doubleArguments[4])) || (n >= 6 && isnan(doubleArguments[5])) || (n >= 7 && isnan(doubleArguments[6]))) return JSValue::encode(jsNaN()); GregorianDateTime t; int year = JSC::toInt32(doubleArguments[0]); t.setYear((year >= 0 && year <= 99) ? (year + 1900) : year); t.setMonth(JSC::toInt32(doubleArguments[1])); t.setMonthDay((n >= 3) ? JSC::toInt32(doubleArguments[2]) : 1); t.setHour(JSC::toInt32(doubleArguments[3])); 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, t, ms, true)))); }
static double millisecondsFromComponents(ExecState* exec, const ArgList& args, WTF::TimeType timeType) { double doubleArguments[] = { args.at(0).toNumber(exec), args.at(1).toNumber(exec), args.at(2).toNumber(exec), args.at(3).toNumber(exec), args.at(4).toNumber(exec), args.at(5).toNumber(exec), args.at(6).toNumber(exec) }; int numArgs = args.size(); if ((!std::isfinite(doubleArguments[0]) || (doubleArguments[0] > INT_MAX) || (doubleArguments[0] < INT_MIN)) || (!std::isfinite(doubleArguments[1]) || (doubleArguments[1] > INT_MAX) || (doubleArguments[1] < INT_MIN)) || (numArgs >= 3 && (!std::isfinite(doubleArguments[2]) || (doubleArguments[2] > INT_MAX) || (doubleArguments[2] < INT_MIN))) || (numArgs >= 4 && (!std::isfinite(doubleArguments[3]) || (doubleArguments[3] > INT_MAX) || (doubleArguments[3] < INT_MIN))) || (numArgs >= 5 && (!std::isfinite(doubleArguments[4]) || (doubleArguments[4] > INT_MAX) || (doubleArguments[4] < INT_MIN))) || (numArgs >= 6 && (!std::isfinite(doubleArguments[5]) || (doubleArguments[5] > INT_MAX) || (doubleArguments[5] < INT_MIN))) || (numArgs >= 7 && (!std::isfinite(doubleArguments[6]) || (doubleArguments[6] > INT_MAX) || (doubleArguments[6] < INT_MIN)))) return PNaN; GregorianDateTime t; int year = JSC::toInt32(doubleArguments[0]); t.setYear((year >= 0 && year <= 99) ? (year + 1900) : year); t.setMonth(JSC::toInt32(doubleArguments[1])); t.setMonthDay((numArgs >= 3) ? JSC::toInt32(doubleArguments[2]) : 1); t.setHour(JSC::toInt32(doubleArguments[3])); t.setMinute(JSC::toInt32(doubleArguments[4])); t.setSecond(JSC::toInt32(doubleArguments[5])); t.setIsDST(-1); double ms = (numArgs >= 7) ? doubleArguments[6] : 0; return gregorianDateTimeToMS(exec->vm(), t, ms, timeType); }
// ECMA 15.9.3 JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args) { VM& vm = exec->vm(); int numArgs = args.size(); double value; if (numArgs == 0) // new Date() ECMA 15.9.3.3 value = jsCurrentTime(); else if (numArgs == 1) { if (args.at(0).inherits(DateInstance::info())) value = asDateInstance(args.at(0))->internalNumber(); else { JSValue primitive = args.at(0).toPrimitive(exec); if (primitive.isString()) value = parseDate(vm, primitive.getString(exec)); else value = primitive.toNumber(exec); } } else { double doubleArguments[7] = { args.at(0).toNumber(exec), args.at(1).toNumber(exec), args.at(2).toNumber(exec), args.at(3).toNumber(exec), args.at(4).toNumber(exec), args.at(5).toNumber(exec), args.at(6).toNumber(exec) }; if (!std::isfinite(doubleArguments[0]) || !std::isfinite(doubleArguments[1]) || (numArgs >= 3 && !std::isfinite(doubleArguments[2])) || (numArgs >= 4 && !std::isfinite(doubleArguments[3])) || (numArgs >= 5 && !std::isfinite(doubleArguments[4])) || (numArgs >= 6 && !std::isfinite(doubleArguments[5])) || (numArgs >= 7 && !std::isfinite(doubleArguments[6]))) value = QNaN; else { GregorianDateTime t; int year = JSC::toInt32(doubleArguments[0]); t.setYear((year >= 0 && year <= 99) ? (year + 1900) : year); t.setMonth(JSC::toInt32(doubleArguments[1])); t.setMonthDay((numArgs >= 3) ? JSC::toInt32(doubleArguments[2]) : 1); t.setHour(JSC::toInt32(doubleArguments[3])); t.setMinute(JSC::toInt32(doubleArguments[4])); t.setSecond(JSC::toInt32(doubleArguments[5])); t.setIsDST(-1); double ms = (numArgs >= 7) ? doubleArguments[6] : 0; value = gregorianDateTimeToMS(vm, t, ms, false); } } return DateInstance::create(vm, globalObject->dateStructure(), value); }
// input is UTC void msToGregorianDateTime(VM& vm, double ms, WTF::TimeType outputTimeType, GregorianDateTime& tm) { LocalTimeOffset localTime; if (outputTimeType == WTF::LocalTime) { localTime = localTimeOffset(vm, ms); ms += localTime.offset; } const int year = msToYear(ms); tm.setSecond(msToSeconds(ms)); tm.setMinute(msToMinutes(ms)); tm.setHour(msToHours(ms)); tm.setWeekDay(msToWeekDay(ms)); tm.setYearDay(dayInYear(ms, year)); tm.setMonthDay(dayInMonthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setMonth(monthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setYear(year); tm.setIsDST(localTime.isDST); tm.setUtcOffset(localTime.offset / WTF::msPerSecond); }
EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec) { JSValue thisValue = exec->thisValue(); if (!thisValue.inherits(DateInstance::info())) return throwVMTypeError(exec); VM& vm = exec->vm(); DateInstance* thisDateObj = asDateInstance(thisValue); if (!exec->argumentCount()) { JSValue result = jsNaN(); thisDateObj->setInternalValue(vm, result); return JSValue::encode(result); } double milli = thisDateObj->internalNumber(); double ms = 0; GregorianDateTime gregorianDateTime; 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); else { double secs = floor(milli / msPerSecond); ms = milli - secs * msPerSecond; if (const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec)) gregorianDateTime.copyFrom(*other); } double year = exec->argument(0).toIntegerPreserveNaN(exec); if (!std::isfinite(year)) { JSValue result = jsNaN(); thisDateObj->setInternalValue(vm, result); return JSValue::encode(result); } gregorianDateTime.setYear(toInt32((year >= 0 && year <= 99) ? (year + 1900) : year)); JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, false)); thisDateObj->setInternalValue(vm, result); return JSValue::encode(result); }
// input is UTC void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm) { double dstOff = 0.0; double utcOff = 0.0; if (!outputIsUTC) { utcOff = getUTCOffset(exec); dstOff = getDSTOffset(exec, ms, utcOff); ms += dstOff + utcOff; } const int year = msToYear(ms); tm.setSecond(msToSeconds(ms)); tm.setMinute(msToMinutes(ms)); tm.setHour(msToHours(ms)); tm.setWeekDay(msToWeekDay(ms)); tm.setYearDay(dayInYear(ms, year)); tm.setMonthDay(dayInMonthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setMonth(monthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setYear(year); tm.setIsDST(dstOff != 0.0); tm.setUtcOffset(static_cast<long>((dstOff + utcOff) / WTF::msPerSecond)); }