2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
23 #include "DateConstructor.h"
26 #include "DatePrototype.h"
27 #include "JSFunction.h"
28 #include "JSGlobalObject.h"
30 #include "ObjectPrototype.h"
31 #include "DateInstance.h"
34 #include <wtf/MathExtras.h>
41 #include <sys/timeb.h>
46 // TODO: MakeTime (15.9.11.1) etc. ?
48 static JSValue* dateParse(ExecState*, JSObject*, JSValue*, const ArgList&);
49 static JSValue* dateNow(ExecState*, JSObject*, JSValue*, const ArgList&);
50 static JSValue* dateUTC(ExecState*, JSObject*, JSValue*, const ArgList&);
52 DateConstructor::DateConstructor(ExecState* exec, FunctionPrototype* funcProto, DatePrototype* dateProto)
53 : InternalFunction(funcProto, Identifier(exec, dateProto->classInfo()->className))
55 putDirect(exec->propertyNames().prototype, dateProto, DontEnum|DontDelete|ReadOnly);
56 putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 1, exec->propertyNames().parse, dateParse), DontEnum);
57 putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
58 putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 0, exec->propertyNames().now, dateNow), DontEnum);
59 putDirect(exec, exec->propertyNames().length, 7, ReadOnly | DontEnum | DontDelete);
63 static JSObject* constructDate(ExecState* exec, JSObject*, const ArgList& args)
65 int numArgs = args.size();
69 if (numArgs == 0) { // new Date() ECMA 15.9.3.3
70 value = getCurrentUTCTime();
71 } else if (numArgs == 1) {
72 if (args[0]->isObject(&DateInstance::info))
73 value = static_cast<DateInstance*>(args[0])->internalNumber();
75 JSValue* primitive = args[0]->toPrimitive(exec);
76 if (primitive->isString())
77 value = parseDate(primitive->getString());
79 value = primitive->toNumber(exec);
82 if (isnan(args[0]->toNumber(exec))
83 || isnan(args[1]->toNumber(exec))
84 || (numArgs >= 3 && isnan(args[2]->toNumber(exec)))
85 || (numArgs >= 4 && isnan(args[3]->toNumber(exec)))
86 || (numArgs >= 5 && isnan(args[4]->toNumber(exec)))
87 || (numArgs >= 6 && isnan(args[5]->toNumber(exec)))
88 || (numArgs >= 7 && isnan(args[6]->toNumber(exec)))) {
92 int year = args[0]->toInt32(exec);
93 t.year = (year >= 0 && year <= 99) ? year : year - 1900;
94 t.month = args[1]->toInt32(exec);
95 t.monthDay = (numArgs >= 3) ? args[2]->toInt32(exec) : 1;
96 t.hour = args[3]->toInt32(exec);
97 t.minute = args[4]->toInt32(exec);
98 t.second = args[5]->toInt32(exec);
100 double ms = (numArgs >= 7) ? args[6]->toNumber(exec) : 0;
101 value = gregorianDateTimeToMS(t, ms, false);
105 DateInstance* ret = new (exec) DateInstance(exec->lexicalGlobalObject()->datePrototype());
106 ret->setInternalValue(jsNumber(exec, timeClip(value)));
110 ConstructType DateConstructor::getConstructData(ConstructData& constructData)
112 constructData.native.function = constructDate;
113 return ConstructTypeNative;
117 static JSValue* callDate(ExecState* exec, JSObject*, JSValue*, const ArgList&)
119 time_t localTime = time(0);
121 getLocalTime(&localTime, &localTM);
122 GregorianDateTime ts(localTM);
123 return jsString(exec, formatDate(ts) + " " + formatTime(ts, false));
126 CallType DateConstructor::getCallData(CallData& callData)
128 callData.native.function = callDate;
129 return CallTypeNative;
132 static JSValue* dateParse(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
134 return jsNumber(exec, parseDate(args[0]->toString(exec)));
137 static JSValue* dateNow(ExecState* exec, JSObject*, JSValue*, const ArgList&)
139 return jsNumber(exec, getCurrentUTCTime());
142 static JSValue* dateUTC(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
145 if (isnan(args[0]->toNumber(exec))
146 || isnan(args[1]->toNumber(exec))
147 || (n >= 3 && isnan(args[2]->toNumber(exec)))
148 || (n >= 4 && isnan(args[3]->toNumber(exec)))
149 || (n >= 5 && isnan(args[4]->toNumber(exec)))
150 || (n >= 6 && isnan(args[5]->toNumber(exec)))
151 || (n >= 7 && isnan(args[6]->toNumber(exec)))) {
156 int year = args[0]->toInt32(exec);
157 t.year = (year >= 0 && year <= 99) ? year : year - 1900;
158 t.month = args[1]->toInt32(exec);
159 t.monthDay = (n >= 3) ? args[2]->toInt32(exec) : 1;
160 t.hour = args[3]->toInt32(exec);
161 t.minute = args[4]->toInt32(exec);
162 t.second = args[5]->toInt32(exec);
163 double ms = (n >= 7) ? args[6]->toNumber(exec) : 0;
164 return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));