Exemplo n.º 1
0
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 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;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
// 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);
}
// ECMA 15.9.3
JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
    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::s_info))
            value = asDateInstance(args.at(0))->internalNumber();
        else {
            JSValue primitive = args.at(0).toPrimitive(exec);
            if (primitive.isString())
                value = parseDate(exec, 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 (isnan(doubleArguments[0])
                || isnan(doubleArguments[1])
                || (numArgs >= 3 && isnan(doubleArguments[2]))
                || (numArgs >= 4 && isnan(doubleArguments[3]))
                || (numArgs >= 5 && isnan(doubleArguments[4]))
                || (numArgs >= 6 && isnan(doubleArguments[5]))
                || (numArgs >= 7 && isnan(doubleArguments[6])))
            value = NaN;
        else {
            GregorianDateTime t;
            int year = JSC::toInt32(doubleArguments[0]);
            t.year = (year >= 0 && year <= 99) ? year : year - 1900;
            t.month = JSC::toInt32(doubleArguments[1]);
            t.monthDay = (numArgs >= 3) ? JSC::toInt32(doubleArguments[2]) : 1;
            t.hour = JSC::toInt32(doubleArguments[3]);
            t.minute = JSC::toInt32(doubleArguments[4]);
            t.second = JSC::toInt32(doubleArguments[5]);
            t.isDST = -1;
            double ms = (numArgs >= 7) ? doubleArguments[6] : 0;
            value = gregorianDateTimeToMS(exec, t, ms, false);
        }
    }

    return new (exec) DateInstance(exec, globalObject->dateStructure(), value);
}
Exemplo n.º 6
0
// ECMA 15.9.3
JSObject* constructDate(ExecState* exec, const ArgList& args)
{
    int numArgs = args.size();

    double value;

    if (numArgs == 0) // new Date() ECMA 15.9.3.3
        value = getCurrentUTCTime();
    else if (numArgs == 1) {
        if (args.at(exec, 0)->isObject(&DateInstance::info))
            value = asDateInstance(args.at(exec, 0))->internalNumber();
        else {
            JSValue* primitive = args.at(exec, 0)->toPrimitive(exec);
            if (primitive->isString())
                value = parseDate(primitive->getString());
            else
                value = primitive->toNumber(exec);
        }
    } else {
        if (isnan(args.at(exec, 0)->toNumber(exec))
                || isnan(args.at(exec, 1)->toNumber(exec))
                || (numArgs >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
                || (numArgs >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
                || (numArgs >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
                || (numArgs >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
                || (numArgs >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
            value = NaN;
        else {
          GregorianDateTime t;
          int year = args.at(exec, 0)->toInt32(exec);
          t.year = (year >= 0 && year <= 99) ? year : year - 1900;
          t.month = args.at(exec, 1)->toInt32(exec);
          t.monthDay = (numArgs >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
          t.hour = args.at(exec, 3)->toInt32(exec);
          t.minute = args.at(exec, 4)->toInt32(exec);
          t.second = args.at(exec, 5)->toInt32(exec);
          t.isDST = -1;
          double ms = (numArgs >= 7) ? args.at(exec, 6)->toNumber(exec) : 0;
          value = gregorianDateTimeToMS(t, ms, false);
        }
    }

    DateInstance* result = new (exec) DateInstance(exec->lexicalGlobalObject()->dateStructure());
    result->setInternalValue(jsNumber(exec, timeClip(value)));
    return result;
}
Exemplo n.º 7
0
// ECMA 15.9.3
AJObject* constructDate(ExecState* exec, const ArgList& args)
{
    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 {
            AJValue primitive = args.at(0).toPrimitive(exec);
            if (primitive.isString())
                value = parseDate(exec, primitive.getString(exec));
            else
                value = primitive.toNumber(exec);
        }
    } else {
        if (isnan(args.at(0).toNumber(exec))
                || isnan(args.at(1).toNumber(exec))
                || (numArgs >= 3 && isnan(args.at(2).toNumber(exec)))
                || (numArgs >= 4 && isnan(args.at(3).toNumber(exec)))
                || (numArgs >= 5 && isnan(args.at(4).toNumber(exec)))
                || (numArgs >= 6 && isnan(args.at(5).toNumber(exec)))
                || (numArgs >= 7 && isnan(args.at(6).toNumber(exec))))
            value = NaN;
        else {
            GregorianDateTime t;
            int year = args.at(0).toInt32(exec);
            t.year = (year >= 0 && year <= 99) ? year : year - 1900;
            t.month = args.at(1).toInt32(exec);
            t.monthDay = (numArgs >= 3) ? args.at(2).toInt32(exec) : 1;
            t.hour = args.at(3).toInt32(exec);
            t.minute = args.at(4).toInt32(exec);
            t.second = args.at(5).toInt32(exec);
            t.isDST = -1;
            double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
            value = gregorianDateTimeToMS(exec, t, ms, false);
        }
    }

    return new (exec) DateInstance(exec, value);
}
Exemplo n.º 8
0
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);
}
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;
}
Exemplo n.º 10
0
EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    if (!thisValue.inherits(&DateInstance::info))
        return throwVMTypeError(exec);

    DateInstance* thisDateObj = asDateInstance(thisValue);     
    if (!exec->argumentCount()) { 
        JSValue result = jsNaN(exec);
        thisDateObj->setInternalValue(result);
        return JSValue::encode(result);
    }
    
    double milli = thisDateObj->internalNumber();
    double ms = 0;

    GregorianDateTime gregorianDateTime;
    if (isnan(milli))
        // Based on ECMA 262 B.2.5 (setYear)
        // the time must be reset to +0 if it is NaN. 
        msToGregorianDateTime(exec, 0, true, gregorianDateTime);
    else {   
        double secs = floor(milli / msPerSecond);
        ms = milli - secs * msPerSecond;
        if (const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec))
            gregorianDateTime.copyFrom(*other);
    }
    
    bool ok = true;
    int32_t year = exec->argument(0).toInt32(exec, ok);
    if (!ok) {
        JSValue result = jsNaN(exec);
        thisDateObj->setInternalValue(result);
        return JSValue::encode(result);
    }
            
    gregorianDateTime.year = (year > 99 || year < 0) ? year - 1900 : year;
    JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, false));
    thisDateObj->setInternalValue(result);
    return JSValue::encode(result);
}
Exemplo n.º 11
0
static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC)
{
    JSValue thisValue = exec->thisValue();
    if (!thisValue.inherits(DateInstance::info()))
        return throwVMTypeError(exec);

    DateInstance* thisDateObj = asDateInstance(thisValue);
    if (!exec->argumentCount()) {
        JSValue result = jsNaN();
        thisDateObj->setInternalValue(exec->vm(), result);
        return JSValue::encode(result);
    }

    VM& vm = exec->vm();
    double milli = thisDateObj->internalNumber();
    double ms = 0; 

    GregorianDateTime gregorianDateTime; 
    if (numArgsToUse == 3 && std::isnan(milli)) 
        msToGregorianDateTime(vm, 0, true, gregorianDateTime);
    else { 
        ms = milli - floor(milli / msPerSecond) * msPerSecond; 
        const GregorianDateTime* other = inputIsUTC 
            ? thisDateObj->gregorianDateTimeUTC(exec)
            : thisDateObj->gregorianDateTime(exec);
        if (!other)
            return JSValue::encode(jsNaN());
        gregorianDateTime.copyFrom(*other);
    }
    
    if (!fillStructuresUsingDateArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
        JSValue result = jsNaN();
        thisDateObj->setInternalValue(vm, result);
        return JSValue::encode(result);
    } 
           
    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputIsUTC));
    thisDateObj->setInternalValue(vm, result);
    return JSValue::encode(result);
}
Exemplo n.º 12
0
static JSValue* dateUTC(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
{
    int n = args.size();
    if (isnan(args.at(exec, 0)->toNumber(exec))
            || isnan(args.at(exec, 1)->toNumber(exec))
            || (n >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
            || (n >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
            || (n >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
            || (n >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
            || (n >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
        return jsNaN(exec);

    GregorianDateTime t;
    int year = args.at(exec, 0)->toInt32(exec);
    t.year = (year >= 0 && year <= 99) ? year : year - 1900;
    t.month = args.at(exec, 1)->toInt32(exec);
    t.monthDay = (n >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
    t.hour = args.at(exec, 3)->toInt32(exec);
    t.minute = args.at(exec, 4)->toInt32(exec);
    t.second = args.at(exec, 5)->toInt32(exec);
    double ms = (n >= 7) ? args.at(exec, 6)->toNumber(exec) : 0;
    return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
}
Exemplo n.º 13
0
static AJValue JSC_HOST_CALL dateUTC(ExecState* exec, AJObject*, AJValue, const ArgList& args) 
{
    int n = args.size();
    if (isnan(args.at(0).toNumber(exec))
            || isnan(args.at(1).toNumber(exec))
            || (n >= 3 && isnan(args.at(2).toNumber(exec)))
            || (n >= 4 && isnan(args.at(3).toNumber(exec)))
            || (n >= 5 && isnan(args.at(4).toNumber(exec)))
            || (n >= 6 && isnan(args.at(5).toNumber(exec)))
            || (n >= 7 && isnan(args.at(6).toNumber(exec))))
        return jsNaN(exec);

    GregorianDateTime t;
    int year = args.at(0).toInt32(exec);
    t.year = (year >= 0 && year <= 99) ? year : year - 1900;
    t.month = args.at(1).toInt32(exec);
    t.monthDay = (n >= 3) ? args.at(2).toInt32(exec) : 1;
    t.hour = args.at(3).toInt32(exec);
    t.minute = args.at(4).toInt32(exec);
    t.second = args.at(5).toInt32(exec);
    double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0;
    return jsNumber(exec, timeClip(gregorianDateTimeToMS(exec, t, ms, true)));
}
static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC)
{
    JSValue thisValue = exec->hostThisValue();
    if (!thisValue.inherits(&DateInstance::s_info))
        return throwVMTypeError(exec);

    DateInstance* thisDateObj = asDateInstance(thisValue);
    double milli = thisDateObj->internalNumber();
    
    if (!exec->argumentCount() || isnan(milli)) {
        JSValue result = jsNaN();
        thisDateObj->setInternalValue(exec->globalData(), result);
        return JSValue::encode(result);
    }
     
    double secs = floor(milli / msPerSecond);
    double ms = milli - secs * msPerSecond;

    const GregorianDateTime* other = inputIsUTC 
        ? thisDateObj->gregorianDateTimeUTC(exec)
        : thisDateObj->gregorianDateTime(exec);
    if (!other)
        return JSValue::encode(jsNaN());

    GregorianDateTime gregorianDateTime;
    gregorianDateTime.copyFrom(*other);
    if (!fillStructuresUsingTimeArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
        JSValue result = jsNaN();
        thisDateObj->setInternalValue(exec->globalData(), result);
        return JSValue::encode(result);
    } 
    
    JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
    thisDateObj->setInternalValue(exec->globalData(), result);
    return JSValue::encode(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;
}
Exemplo n.º 16
0
double parseDateFromNullTerminatedCharacters(const char* dateString)
{
    // This parses a date in the form:
    //     Tuesday, 09-Nov-99 23:12:40 GMT
    // or
    //     Sat, 01-Jan-2000 08:00:00 GMT
    // or
    //     Sat, 01 Jan 2000 08:00:00 GMT
    // or
    //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822)
    // ### non RFC formats, added for Javascript:
    //     [Wednesday] January 09 1999 23:12:40 GMT
    //     [Wednesday] January 09 23:12:40 GMT 1999
    //
    // We ignore the weekday.
     
    // Skip leading space
    skipSpacesAndComments(dateString);

    long month = -1;
    const char *wordStart = dateString;
    // Check contents of first words if not number
    while (*dateString && !isASCIIDigit(*dateString)) {
        if (isASCIISpace(*dateString) || *dateString == '(') {
            if (dateString - wordStart >= 3)
                month = findMonth(wordStart);
            skipSpacesAndComments(dateString);
            wordStart = dateString;
        } else
           dateString++;
    }

    // Missing delimiter between month and day (like "January29")?
    if (month == -1 && wordStart != dateString)
        month = findMonth(wordStart);

    skipSpacesAndComments(dateString);

    if (!*dateString)
        return NaN;

    // ' 09-Nov-99 23:12:40 GMT'
    char* newPosStr;
    long day;
    if (!parseLong(dateString, &newPosStr, 10, &day))
        return NaN;
    dateString = newPosStr;

    if (!*dateString)
        return NaN;

    if (day < 0)
        return NaN;

    long year = 0;
    if (day > 31) {
        // ### where is the boundary and what happens below?
        if (*dateString != '/')
            return NaN;
        // looks like a YYYY/MM/DD date
        if (!*++dateString)
            return NaN;
        year = day;
        if (!parseLong(dateString, &newPosStr, 10, &month))
            return NaN;
        month -= 1;
        dateString = newPosStr;
        if (*dateString++ != '/' || !*dateString)
            return NaN;
        if (!parseLong(dateString, &newPosStr, 10, &day))
            return NaN;
        dateString = newPosStr;
    } else if (*dateString == '/' && month == -1) {
        dateString++;
        // This looks like a MM/DD/YYYY date, not an RFC date.
        month = day - 1; // 0-based
        if (!parseLong(dateString, &newPosStr, 10, &day))
            return NaN;
        if (day < 1 || day > 31)
            return NaN;
        dateString = newPosStr;
        if (*dateString == '/')
            dateString++;
        if (!*dateString)
            return NaN;
     } else {
        if (*dateString == '-')
            dateString++;

        skipSpacesAndComments(dateString);

        if (*dateString == ',')
            dateString++;

        if (month == -1) { // not found yet
            month = findMonth(dateString);
            if (month == -1)
                return NaN;

            while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString))
                dateString++;

            if (!*dateString)
                return NaN;

            // '-99 23:12:40 GMT'
            if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString))
                return NaN;
            dateString++;
        }
    }

    if (month < 0 || month > 11)
        return NaN;

    // '99 23:12:40 GMT'
    if (year <= 0 && *dateString) {
        if (!parseLong(dateString, &newPosStr, 10, &year))
            return NaN;
    }

    // Don't fail if the time is missing.
    long hour = 0;
    long minute = 0;
    long second = 0;
    if (!*newPosStr)
        dateString = newPosStr;
    else {
        // ' 23:12:40 GMT'
        if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {
            if (*newPosStr != ':')
                return NaN;
            // There was no year; the number was the hour.
            year = -1;
        } else {
            // in the normal case (we parsed the year), advance to the next number
            dateString = ++newPosStr;
            skipSpacesAndComments(dateString);
        }

        parseLong(dateString, &newPosStr, 10, &hour);
        // Do not check for errno here since we want to continue
        // even if errno was set becasue we are still looking
        // for the timezone!

        // Read a number? If not, this might be a timezone name.
        if (newPosStr != dateString) {
            dateString = newPosStr;

            if (hour < 0 || hour > 23)
                return NaN;

            if (!*dateString)
                return NaN;

            // ':12:40 GMT'
            if (*dateString++ != ':')
                return NaN;

            if (!parseLong(dateString, &newPosStr, 10, &minute))
                return NaN;
            dateString = newPosStr;

            if (minute < 0 || minute > 59)
                return NaN;

            // ':40 GMT'
            if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
                return NaN;

            // seconds are optional in rfc822 + rfc2822
            if (*dateString ==':') {
                dateString++;

                if (!parseLong(dateString, &newPosStr, 10, &second))
                    return NaN;
                dateString = newPosStr;

                if (second < 0 || second > 59)
                    return NaN;
            }

            skipSpacesAndComments(dateString);

            if (strncasecmp(dateString, "AM", 2) == 0) {
                if (hour > 12)
                    return NaN;
                if (hour == 12)
                    hour = 0;
                dateString += 2;
                skipSpacesAndComments(dateString);
            } else if (strncasecmp(dateString, "PM", 2) == 0) {
                if (hour > 12)
                    return NaN;
                if (hour != 12)
                    hour += 12;
                dateString += 2;
                skipSpacesAndComments(dateString);
            }
        }
    }

    bool haveTZ = false;
    int offset = 0;

    // Don't fail if the time zone is missing. 
    // Some websites omit the time zone (4275206).
    if (*dateString) {
        if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) {
            dateString += 3;
            haveTZ = true;
        }

        if (*dateString == '+' || *dateString == '-') {
            long o;
            if (!parseLong(dateString, &newPosStr, 10, &o))
                return NaN;
            dateString = newPosStr;

            if (o < -9959 || o > 9959)
                return NaN;

            int sgn = (o < 0) ? -1 : 1;
            o = labs(o);
            if (*dateString != ':') {
                offset = ((o / 100) * 60 + (o % 100)) * sgn;
            } else { // GMT+05:00
                long o2;
                if (!parseLong(dateString, &newPosStr, 10, &o2))
                    return NaN;
                dateString = newPosStr;
                offset = (o * 60 + o2) * sgn;
            }
            haveTZ = true;
        } else {
            for (int i = 0; i < int(sizeof(known_zones) / sizeof(KnownZone)); i++) {
                if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
                    offset = known_zones[i].tzOffset;
                    dateString += strlen(known_zones[i].tzName);
                    haveTZ = true;
                    break;
                }
            }
        }
    }

    skipSpacesAndComments(dateString);

    if (*dateString && year == -1) {
        if (!parseLong(dateString, &newPosStr, 10, &year))
            return NaN;
        dateString = newPosStr;
    }

    skipSpacesAndComments(dateString);

    // Trailing garbage
    if (*dateString)
        return NaN;

    // Y2K: Handle 2 digit years.
    if (year >= 0 && year < 100) {
        if (year < 50)
            year += 2000;
        else
            year += 1900;
    }

    // fall back to local timezone
    if (!haveTZ) {
        GregorianDateTime t;
        t.monthDay = day;
        t.month = month;
        t.year = year - 1900;
        t.isDST = -1;
        t.second = second;
        t.minute = minute;
        t.hour = hour;

        // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.
        return gregorianDateTimeToMS(t, 0, false);
    }

    return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
}