static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); double milli = thisDateObj->internalNumber(); if (args.isEmpty() || isnan(milli)) { JSValue result = jsNaN(exec); thisDateObj->setInternalValue(result); return result; } double secs = floor(milli / msPerSecond); double ms = milli - secs * msPerSecond; GregorianDateTime t; thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t); if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) { JSValue result = jsNaN(exec); thisDateObj->setInternalValue(result); return result; } JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC)); thisDateObj->setInternalValue(result); return result; }
JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; DateInstance* thisDateObj = asDateInstance(thisValue); if (args.isEmpty()) { JSValue result = jsNaN(exec); thisDateObj->setInternalValue(result); return result; } double milli = thisDateObj->internalNumber(); double ms = 0; GregorianDateTime t; if (isnan(milli)) // Based on ECMA 262 B.2.5 (setYear) // the time must be reset to +0 if it is NaN. thisDateObj->msToGregorianDateTime(0, true, t); else { double secs = floor(milli / msPerSecond); ms = milli - secs * msPerSecond; thisDateObj->msToGregorianDateTime(milli, utc, t); } bool ok = true; int32_t year = args.at(0).toInt32(exec, ok); if (!ok) { JSValue result = jsNaN(exec); thisDateObj->setInternalValue(result); return result; } t.year = (year > 99 || year < 0) ? year - 1900 : year; JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc)); thisDateObj->setInternalValue(result); return result; }
static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); DateInstance* thisDateObj = asDateInstance(thisValue); if (args.isEmpty()) { JSValue result = jsNaN(exec); thisDateObj->setInternalValue(result); return result; } double milli = thisDateObj->internalNumber(); double ms = 0; GregorianDateTime t; if (numArgsToUse == 3 && isnan(milli)) // Based on ECMA 262 15.9.5.40 - .41 (set[UTC]FullYear) // the time must be reset to +0 if it is NaN. thisDateObj->msToGregorianDateTime(0, true, t); else { double secs = floor(milli / msPerSecond); ms = milli - secs * msPerSecond; thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t); } if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) { JSValue result = jsNaN(exec); thisDateObj->setInternalValue(result); return result; } JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC)); thisDateObj->setInternalValue(result); return result; }
JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; DateInstance* thisDateObj = asDateInstance(thisValue); double milli = thisDateObj->internalNumber(); if (isnan(milli)) return jsNaN(exec); GregorianDateTime t; thisDateObj->msToGregorianDateTime(milli, utc, t); return jsNumber(exec, -gmtoffset(t) / minutesPerHour); }
JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; DateInstance* thisDateObj = asDateInstance(thisValue); double milli = thisDateObj->internalNumber(); if (isnan(milli)) return jsNaN(exec); GregorianDateTime t; thisDateObj->msToGregorianDateTime(milli, utc, t); return jsNumber(exec, t.second); }
JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; DateInstance* thisDateObj = asDateInstance(thisValue); double milli = thisDateObj->internalNumber(); if (isnan(milli)) return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; thisDateObj->msToGregorianDateTime(milli, utc, t); return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc)); }
JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = false; DateInstance* thisDateObj = asDateInstance(thisValue); double milli = thisDateObj->internalNumber(); if (isnan(milli)) return jsNaN(exec); GregorianDateTime t; thisDateObj->msToGregorianDateTime(milli, utc, t); // NOTE: IE returns the full year even in getYear. return jsNumber(exec, t.year); }
JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { if (!thisValue.isObject(&DateInstance::info)) return throwError(exec, TypeError); const bool utc = true; DateInstance* thisDateObj = asDateInstance(thisValue); double milli = thisDateObj->internalNumber(); if (!isfinite(milli)) return jsNontrivialString(exec, "Invalid Date"); GregorianDateTime t; thisDateObj->msToGregorianDateTime(milli, utc, t); // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) // 6 for formatting and one for null termination = 23. We add one extra character to allow us to force null termination. char buffer[24]; snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second); buffer[sizeof(buffer) - 1] = 0; return jsNontrivialString(exec, buffer); }