2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 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"
25 #include "DateConversion.h"
26 #include "DateInstance.h"
27 #include "DatePrototype.h"
28 #include "JSDateMath.h"
29 #include "JSFunction.h"
30 #include "JSGlobalObject.h"
32 #include "JSStringBuilder.h"
33 #include "ObjectPrototype.h"
36 #include <wtf/MathExtras.h>
38 #if OS(WINCE) && !PLATFORM(QT)
39 extern "C" time_t time(time_t* timer
); // Provided by libce.
47 #include <sys/timeb.h>
54 static EncodedJSValue JSC_HOST_CALL
dateParse(ExecState
*);
55 static EncodedJSValue JSC_HOST_CALL
dateNow(ExecState
*);
56 static EncodedJSValue JSC_HOST_CALL
dateUTC(ExecState
*);
60 #include "DateConstructor.lut.h"
64 const ClassInfo
DateConstructor::s_info
= { "Function", &InternalFunction::s_info
, 0, ExecState::dateConstructorTable
, CREATE_METHOD_TABLE(DateConstructor
) };
66 /* Source for DateConstructor.lut.h
67 @begin dateConstructorTable
68 parse dateParse DontEnum|Function 1
69 UTC dateUTC DontEnum|Function 7
70 now dateNow DontEnum|Function 0
74 ASSERT_CLASS_FITS_IN_CELL(DateConstructor
);
75 ASSERT_HAS_TRIVIAL_DESTRUCTOR(DateConstructor
);
77 DateConstructor::DateConstructor(JSGlobalObject
* globalObject
, Structure
* structure
)
78 : InternalFunction(globalObject
, structure
)
82 void DateConstructor::finishCreation(ExecState
* exec
, DatePrototype
* datePrototype
)
84 Base::finishCreation(exec
->globalData(), Identifier(exec
, datePrototype
->classInfo()->className
));
85 putDirectWithoutTransition(exec
->globalData(), exec
->propertyNames().prototype
, datePrototype
, DontEnum
| DontDelete
| ReadOnly
);
86 putDirectWithoutTransition(exec
->globalData(), exec
->propertyNames().length
, jsNumber(7), ReadOnly
| DontEnum
| DontDelete
);
89 bool DateConstructor::getOwnPropertySlot(JSCell
* cell
, ExecState
* exec
, const Identifier
& propertyName
, PropertySlot
&slot
)
91 return getStaticFunctionSlot
<InternalFunction
>(exec
, ExecState::dateConstructorTable(exec
), jsCast
<DateConstructor
*>(cell
), propertyName
, slot
);
94 bool DateConstructor::getOwnPropertyDescriptor(JSObject
* object
, ExecState
* exec
, const Identifier
& propertyName
, PropertyDescriptor
& descriptor
)
96 return getStaticFunctionDescriptor
<InternalFunction
>(exec
, ExecState::dateConstructorTable(exec
), jsCast
<DateConstructor
*>(object
), propertyName
, descriptor
);
100 JSObject
* constructDate(ExecState
* exec
, JSGlobalObject
* globalObject
, const ArgList
& args
)
102 int numArgs
= args
.size();
106 if (numArgs
== 0) // new Date() ECMA 15.9.3.3
107 value
= jsCurrentTime();
108 else if (numArgs
== 1) {
109 if (args
.at(0).inherits(&DateInstance::s_info
))
110 value
= asDateInstance(args
.at(0))->internalNumber();
112 JSValue primitive
= args
.at(0).toPrimitive(exec
);
113 if (primitive
.isString())
114 value
= parseDate(exec
, primitive
.getString(exec
));
116 value
= primitive
.toNumber(exec
);
119 double doubleArguments
[7] = {
120 args
.at(0).toNumber(exec
),
121 args
.at(1).toNumber(exec
),
122 args
.at(2).toNumber(exec
),
123 args
.at(3).toNumber(exec
),
124 args
.at(4).toNumber(exec
),
125 args
.at(5).toNumber(exec
),
126 args
.at(6).toNumber(exec
)
128 if (!isfinite(doubleArguments
[0])
129 || !isfinite(doubleArguments
[1])
130 || (numArgs
>= 3 && !isfinite(doubleArguments
[2]))
131 || (numArgs
>= 4 && !isfinite(doubleArguments
[3]))
132 || (numArgs
>= 5 && !isfinite(doubleArguments
[4]))
133 || (numArgs
>= 6 && !isfinite(doubleArguments
[5]))
134 || (numArgs
>= 7 && !isfinite(doubleArguments
[6])))
135 value
= std::numeric_limits
<double>::quiet_NaN();
138 int year
= JSC::toInt32(doubleArguments
[0]);
139 t
.year
= (year
>= 0 && year
<= 99) ? year
: year
- 1900;
140 t
.month
= JSC::toInt32(doubleArguments
[1]);
141 t
.monthDay
= (numArgs
>= 3) ? JSC::toInt32(doubleArguments
[2]) : 1;
142 t
.hour
= JSC::toInt32(doubleArguments
[3]);
143 t
.minute
= JSC::toInt32(doubleArguments
[4]);
144 t
.second
= JSC::toInt32(doubleArguments
[5]);
146 double ms
= (numArgs
>= 7) ? doubleArguments
[6] : 0;
147 value
= gregorianDateTimeToMS(exec
, t
, ms
, false);
151 return DateInstance::create(exec
, globalObject
->dateStructure(), value
);
154 static EncodedJSValue JSC_HOST_CALL
constructWithDateConstructor(ExecState
* exec
)
157 return JSValue::encode(constructDate(exec
, asInternalFunction(exec
->callee())->globalObject(), args
));
160 ConstructType
DateConstructor::getConstructData(JSCell
*, ConstructData
& constructData
)
162 constructData
.native
.function
= constructWithDateConstructor
;
163 return ConstructTypeHost
;
167 static EncodedJSValue JSC_HOST_CALL
callDate(ExecState
* exec
)
169 GregorianDateTime ts
;
170 msToGregorianDateTime(exec
, currentTimeMS(), false, ts
);
171 DateConversionBuffer date
;
172 DateConversionBuffer time
;
173 formatDate(ts
, date
);
174 formatTime(ts
, time
);
175 return JSValue::encode(jsMakeNontrivialString(exec
, date
, " ", time
));
178 CallType
DateConstructor::getCallData(JSCell
*, CallData
& callData
)
180 callData
.native
.function
= callDate
;
184 static EncodedJSValue JSC_HOST_CALL
dateParse(ExecState
* exec
)
186 return JSValue::encode(jsNumber(parseDate(exec
, exec
->argument(0).toString(exec
)->value(exec
))));
189 static EncodedJSValue JSC_HOST_CALL
dateNow(ExecState
*)
191 return JSValue::encode(jsNumber(jsCurrentTime()));
194 static EncodedJSValue JSC_HOST_CALL
dateUTC(ExecState
* exec
)
196 double doubleArguments
[7] = {
197 exec
->argument(0).toNumber(exec
),
198 exec
->argument(1).toNumber(exec
),
199 exec
->argument(2).toNumber(exec
),
200 exec
->argument(3).toNumber(exec
),
201 exec
->argument(4).toNumber(exec
),
202 exec
->argument(5).toNumber(exec
),
203 exec
->argument(6).toNumber(exec
)
205 int n
= exec
->argumentCount();
206 if (isnan(doubleArguments
[0])
207 || isnan(doubleArguments
[1])
208 || (n
>= 3 && isnan(doubleArguments
[2]))
209 || (n
>= 4 && isnan(doubleArguments
[3]))
210 || (n
>= 5 && isnan(doubleArguments
[4]))
211 || (n
>= 6 && isnan(doubleArguments
[5]))
212 || (n
>= 7 && isnan(doubleArguments
[6])))
213 return JSValue::encode(jsNaN());
216 int year
= JSC::toInt32(doubleArguments
[0]);
217 t
.year
= (year
>= 0 && year
<= 99) ? year
: year
- 1900;
218 t
.month
= JSC::toInt32(doubleArguments
[1]);
219 t
.monthDay
= (n
>= 3) ? JSC::toInt32(doubleArguments
[2]) : 1;
220 t
.hour
= JSC::toInt32(doubleArguments
[3]);
221 t
.minute
= JSC::toInt32(doubleArguments
[4]);
222 t
.second
= JSC::toInt32(doubleArguments
[5]);
223 double ms
= (n
>= 7) ? doubleArguments
[6] : 0;
224 return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec
, t
, ms
, true))));