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"
25 #include "DateConversion.h"
26 #include "DateInstance.h"
27 #include "DatePrototype.h"
28 #include "JSFunction.h"
29 #include "JSGlobalObject.h"
31 #include "JSStringBuilder.h"
32 #include "ObjectPrototype.h"
33 #include "PrototypeFunction.h"
36 #include <wtf/DateMath.h>
37 #include <wtf/MathExtras.h>
39 #if OS(WINCE) && !PLATFORM(QT)
40 extern "C" time_t time(time_t* timer
); // Provided by libce.
48 #include <sys/timeb.h>
55 ASSERT_CLASS_FITS_IN_CELL(DateConstructor
);
57 static JSValue JSC_HOST_CALL
dateParse(ExecState
*, JSObject
*, JSValue
, const ArgList
&);
58 static JSValue JSC_HOST_CALL
dateNow(ExecState
*, JSObject
*, JSValue
, const ArgList
&);
59 static JSValue JSC_HOST_CALL
dateUTC(ExecState
*, JSObject
*, JSValue
, const ArgList
&);
61 DateConstructor::DateConstructor(ExecState
* exec
, NonNullPassRefPtr
<Structure
> structure
, Structure
* prototypeFunctionStructure
, DatePrototype
* datePrototype
)
62 : InternalFunction(&exec
->globalData(), structure
, Identifier(exec
, datePrototype
->classInfo()->className
))
64 putDirectWithoutTransition(exec
->propertyNames().prototype
, datePrototype
, DontEnum
|DontDelete
|ReadOnly
);
66 putDirectFunctionWithoutTransition(exec
, new (exec
) NativeFunctionWrapper(exec
, prototypeFunctionStructure
, 1, exec
->propertyNames().parse
, dateParse
), DontEnum
);
67 putDirectFunctionWithoutTransition(exec
, new (exec
) NativeFunctionWrapper(exec
, prototypeFunctionStructure
, 7, exec
->propertyNames().UTC
, dateUTC
), DontEnum
);
68 putDirectFunctionWithoutTransition(exec
, new (exec
) NativeFunctionWrapper(exec
, prototypeFunctionStructure
, 0, exec
->propertyNames().now
, dateNow
), DontEnum
);
70 putDirectWithoutTransition(exec
->propertyNames().length
, jsNumber(exec
, 7), ReadOnly
| DontEnum
| DontDelete
);
74 JSObject
* constructDate(ExecState
* exec
, const ArgList
& args
)
76 int numArgs
= args
.size();
80 if (numArgs
== 0) // new Date() ECMA 15.9.3.3
81 value
= jsCurrentTime();
82 else if (numArgs
== 1) {
83 if (args
.at(0).inherits(&DateInstance::info
))
84 value
= asDateInstance(args
.at(0))->internalNumber();
86 JSValue primitive
= args
.at(0).toPrimitive(exec
);
87 if (primitive
.isString())
88 value
= parseDate(exec
, primitive
.getString(exec
));
90 value
= primitive
.toNumber(exec
);
93 if (isnan(args
.at(0).toNumber(exec
))
94 || isnan(args
.at(1).toNumber(exec
))
95 || (numArgs
>= 3 && isnan(args
.at(2).toNumber(exec
)))
96 || (numArgs
>= 4 && isnan(args
.at(3).toNumber(exec
)))
97 || (numArgs
>= 5 && isnan(args
.at(4).toNumber(exec
)))
98 || (numArgs
>= 6 && isnan(args
.at(5).toNumber(exec
)))
99 || (numArgs
>= 7 && isnan(args
.at(6).toNumber(exec
))))
103 int year
= args
.at(0).toInt32(exec
);
104 t
.year
= (year
>= 0 && year
<= 99) ? year
: year
- 1900;
105 t
.month
= args
.at(1).toInt32(exec
);
106 t
.monthDay
= (numArgs
>= 3) ? args
.at(2).toInt32(exec
) : 1;
107 t
.hour
= args
.at(3).toInt32(exec
);
108 t
.minute
= args
.at(4).toInt32(exec
);
109 t
.second
= args
.at(5).toInt32(exec
);
111 double ms
= (numArgs
>= 7) ? args
.at(6).toNumber(exec
) : 0;
112 value
= gregorianDateTimeToMS(exec
, t
, ms
, false);
116 return new (exec
) DateInstance(exec
, value
);
119 static JSObject
* constructWithDateConstructor(ExecState
* exec
, JSObject
*, const ArgList
& args
)
121 return constructDate(exec
, args
);
124 ConstructType
DateConstructor::getConstructData(ConstructData
& constructData
)
126 constructData
.native
.function
= constructWithDateConstructor
;
127 return ConstructTypeHost
;
131 static JSValue JSC_HOST_CALL
callDate(ExecState
* exec
, JSObject
*, JSValue
, const ArgList
&)
133 time_t localTime
= time(0);
135 getLocalTime(&localTime
, &localTM
);
136 GregorianDateTime
ts(exec
, localTM
);
137 DateConversionBuffer date
;
138 DateConversionBuffer time
;
139 formatDate(ts
, date
);
140 formatTime(ts
, time
);
141 return jsMakeNontrivialString(exec
, date
, " ", time
);
144 CallType
DateConstructor::getCallData(CallData
& callData
)
146 callData
.native
.function
= callDate
;
150 static JSValue JSC_HOST_CALL
dateParse(ExecState
* exec
, JSObject
*, JSValue
, const ArgList
& args
)
152 return jsNumber(exec
, parseDate(exec
, args
.at(0).toString(exec
)));
155 static JSValue JSC_HOST_CALL
dateNow(ExecState
* exec
, JSObject
*, JSValue
, const ArgList
&)
157 return jsNumber(exec
, jsCurrentTime());
160 static JSValue JSC_HOST_CALL
dateUTC(ExecState
* exec
, JSObject
*, JSValue
, const ArgList
& args
)
163 if (isnan(args
.at(0).toNumber(exec
))
164 || isnan(args
.at(1).toNumber(exec
))
165 || (n
>= 3 && isnan(args
.at(2).toNumber(exec
)))
166 || (n
>= 4 && isnan(args
.at(3).toNumber(exec
)))
167 || (n
>= 5 && isnan(args
.at(4).toNumber(exec
)))
168 || (n
>= 6 && isnan(args
.at(5).toNumber(exec
)))
169 || (n
>= 7 && isnan(args
.at(6).toNumber(exec
))))
173 int year
= args
.at(0).toInt32(exec
);
174 t
.year
= (year
>= 0 && year
<= 99) ? year
: year
- 1900;
175 t
.month
= args
.at(1).toInt32(exec
);
176 t
.monthDay
= (n
>= 3) ? args
.at(2).toInt32(exec
) : 1;
177 t
.hour
= args
.at(3).toInt32(exec
);
178 t
.minute
= args
.at(4).toInt32(exec
);
179 t
.second
= args
.at(5).toInt32(exec
);
180 double ms
= (n
>= 7) ? args
.at(6).toNumber(exec
) : 0;
181 return jsNumber(exec
, timeClip(gregorianDateTimeToMS(exec
, t
, ms
, true)));