2 * Copyright 2008 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(jscript
);
28 /* 1601 to 1970 is 369 years plus 89 leap days */
29 #define TIME_EPOCH ((ULONGLONG)(369 * 365 + 89) * 86400 * 1000)
34 /* ECMA-262 3rd Edition 15.9.1.1 */
40 static const WCHAR toStringW
[] = {'t','o','S','t','r','i','n','g',0};
41 static const WCHAR toLocaleStringW
[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
42 static const WCHAR hasOwnPropertyW
[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
43 static const WCHAR propertyIsEnumerableW
[] =
44 {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
45 static const WCHAR isPrototypeOfW
[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
46 static const WCHAR valueOfW
[] = {'v','a','l','u','e','O','f',0};
47 static const WCHAR toUTCStringW
[] = {'t','o','U','T','C','S','t','r','i','n','g',0};
48 static const WCHAR toDateStringW
[] = {'t','o','D','a','t','e','S','t','r','i','n','g',0};
49 static const WCHAR toTimeStringW
[] = {'t','o','T','i','m','e','S','t','r','i','n','g',0};
50 static const WCHAR toLocaleDateStringW
[] = {'t','o','L','o','c','a','l','e','D','a','t','e','S','t','r','i','n','g',0};
51 static const WCHAR toLocaleTimeStringW
[] = {'t','o','L','o','c','a','l','e','T','i','m','e','S','t','r','i','n','g',0};
52 static const WCHAR getTimeW
[] = {'g','e','t','T','i','m','e',0};
53 static const WCHAR getFullYearW
[] = {'g','e','t','F','u','l','l','Y','e','a','r',0};
54 static const WCHAR getUTCFullYearW
[] = {'g','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};
55 static const WCHAR getMonthW
[] = {'g','e','t','M','o','n','t','h',0};
56 static const WCHAR getUTCMonthW
[] = {'g','e','t','U','T','C','M','o','n','t','h',0};
57 static const WCHAR getDateW
[] = {'g','e','t','D','a','t','e',0};
58 static const WCHAR getUTCDateW
[] = {'g','e','t','U','T','C','D','a','t','e',0};
59 static const WCHAR getDayW
[] = {'g','e','t','D','a','y',0};
60 static const WCHAR getUTCDayW
[] = {'g','e','t','U','T','C','D','a','y',0};
61 static const WCHAR getHoursW
[] = {'g','e','t','H','o','u','r','s',0};
62 static const WCHAR getUTCHoursW
[] = {'g','e','t','U','T','C','H','o','u','r','s',0};
63 static const WCHAR getMinutesW
[] = {'g','e','t','M','i','n','u','t','e','s',0};
64 static const WCHAR getUTCMinutesW
[] = {'g','e','t','U','T','C','M','i','n','u','t','e','s',0};
65 static const WCHAR getSecondsW
[] = {'g','e','t','S','e','c','o','n','d','s',0};
66 static const WCHAR getUTCSecondsW
[] = {'g','e','t','U','T','C','S','e','c','o','n','d','s',0};
67 static const WCHAR getMilisecondsW
[] = {'g','e','t','M','i','l','i','s','e','c','o','n','d','s',0};
68 static const WCHAR getUTCMilisecondsW
[] = {'g','e','t','U','T','C','M','i','l','i','s','e','c','o','n','d','s',0};
69 static const WCHAR getTimezoneOffsetW
[] = {'g','e','t','T','i','m','e','z','o','n','e','O','f','f','s','e','t',0};
70 static const WCHAR setTimeW
[] = {'s','e','t','T','i','m','e',0};
71 static const WCHAR setMilisecondsW
[] = {'s','e','t','M','i','l','i','s','e','c','o','n','d','s',0};
72 static const WCHAR setUTCMilisecondsW
[] = {'s','e','t','U','T','C','M','i','l','i','s','e','c','o','n','d','s',0};
73 static const WCHAR setSecondsW
[] = {'s','e','t','S','e','c','o','n','d','s',0};
74 static const WCHAR setUTCSecondsW
[] = {'s','e','t','U','T','C','S','e','c','o','n','d','s',0};
75 static const WCHAR setMinutesW
[] = {'s','e','t','M','i','n','u','t','e','s',0};
76 static const WCHAR setUTCMinutesW
[] = {'s','e','t','U','T','C','M','i','n','u','t','e','s',0};
77 static const WCHAR setHoursW
[] = {'s','e','t','H','o','u','r','s',0};
78 static const WCHAR setUTCHoursW
[] = {'s','e','t','H','o','u','r','s',0};
79 static const WCHAR setDateW
[] = {'s','e','t','D','a','t','e',0};
80 static const WCHAR setUTCDateW
[] = {'s','e','t','U','T','C','D','a','t','e',0};
81 static const WCHAR setMonthW
[] = {'s','e','t','M','o','n','t','h',0};
82 static const WCHAR setUTCMonthW
[] = {'s','e','t','U','T','C','M','o','n','t','h',0};
83 static const WCHAR setFullYearW
[] = {'s','e','t','F','u','l','l','Y','e','a','r',0};
84 static const WCHAR setUTCFullYearW
[] = {'s','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};
86 /*ECMA-262 3th Edition 15.9.1.2 */
87 #define MS_PER_DAY 86400000
88 #define MS_PER_HOUR 3600000
89 #define MS_PER_MINUTE 60000
91 /* ECMA-262 3th Edition 15.9.1.2 */
92 static inline DOUBLE
day(DOUBLE time
)
94 return floor(time
/ MS_PER_DAY
);
97 /* ECMA-262 3th Edition 15.9.1.3 */
98 static inline DOUBLE
days_in_year(DOUBLE year
)
102 if(year
!= (int)year
)
106 if(y
%4 != 0) return 365;
107 if(y
%100 != 0) return 366;
108 if(y
%400 != 0) return 365;
112 /* ECMA-262 3th Edition 15.9.1.3 */
113 static inline DOUBLE
day_from_year(DOUBLE year
)
117 if(year
!= (int)year
)
121 return 365*(y
-1970) + floor((y
-1969)/4)
122 - floor((y
-1901)/100) + floor((y
-1601)/400);
125 /* ECMA-262 3th Edition 15.9.1.3 */
126 static inline DOUBLE
time_from_year(DOUBLE year
)
128 return MS_PER_DAY
*day_from_year(year
);
131 /* ECMA-262 3th Edition 15.9.1.3 */
132 static inline DOUBLE
year_from_time(DOUBLE time
)
139 y
= 1970 + time
/365.25/MS_PER_DAY
;
141 if(time_from_year(y
) > time
)
142 while(time_from_year(y
) > time
) y
--;
144 while(time_from_year(y
+1)<=time
) y
++;
149 /* ECMA-262 3th Edition 15.9.1.3 */
150 static inline int in_leap_year(DOUBLE time
)
152 if(days_in_year(year_from_time(time
))==366)
157 /* ECMA-262 3th Edition 15.9.1.4 */
158 static inline int day_within_year(DOUBLE time
)
160 return day(time
) - day_from_year(year_from_time(time
));
163 /* ECMA-262 3th Edition 15.9.1.4 */
164 static inline DOUBLE
month_from_time(DOUBLE time
)
166 int ily
= in_leap_year(time
);
167 int dwy
= day_within_year(time
);
172 if(0<=dwy
&& dwy
<31) return 0;
173 if(dwy
< 59+ily
) return 1;
174 if(dwy
< 90+ily
) return 2;
175 if(dwy
< 120+ily
) return 3;
176 if(dwy
< 151+ily
) return 4;
177 if(dwy
< 181+ily
) return 5;
178 if(dwy
< 212+ily
) return 6;
179 if(dwy
< 243+ily
) return 7;
180 if(dwy
< 273+ily
) return 8;
181 if(dwy
< 304+ily
) return 9;
182 if(dwy
< 334+ily
) return 10;
186 /* ECMA-262 3th Edition 15.9.1.5 */
187 static inline DOUBLE
date_from_time(DOUBLE time
)
189 int dwy
= day_within_year(time
);
190 int ily
= in_leap_year(time
);
191 int mft
= month_from_time(time
);
196 if(mft
==0) return dwy
+1;
197 if(mft
==1) return dwy
-30;
198 if(mft
==2) return dwy
-58-ily
;
199 if(mft
==3) return dwy
-89-ily
;
200 if(mft
==4) return dwy
-119-ily
;
201 if(mft
==5) return dwy
-150-ily
;
202 if(mft
==6) return dwy
-180-ily
;
203 if(mft
==7) return dwy
-211-ily
;
204 if(mft
==8) return dwy
-242-ily
;
205 if(mft
==9) return dwy
-272-ily
;
206 if(mft
==10) return dwy
-303-ily
;
210 /* ECMA-262 3th Edition 15.9.1.6 */
211 static inline DOUBLE
week_day(DOUBLE time
)
216 return (int)(day(time
)+4) % 7;
219 /* ECMA-262 3th Edition 15.9.1.10 */
220 static inline DOUBLE
hour_from_time(DOUBLE time
)
225 return (int)floor(time
/MS_PER_HOUR
) % 24;
228 /* ECMA-262 3rd Edition 15.9.1.14 */
229 static inline DOUBLE
time_clip(DOUBLE time
)
231 if(8.64e15
< time
|| time
< -8.64e15
) {
238 static HRESULT
Date_toString(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
239 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
245 static HRESULT
Date_toLocaleString(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
246 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
252 static HRESULT
Date_hasOwnProperty(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
253 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
259 static HRESULT
Date_propertyIsEnumerable(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
260 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
266 static HRESULT
Date_isPrototypeOf(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
267 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
273 static HRESULT
Date_valueOf(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
274 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
280 static HRESULT
Date_toUTCString(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
281 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
287 static HRESULT
Date_toDateString(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
288 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
294 static HRESULT
Date_toTimeString(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
295 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
301 static HRESULT
Date_toLocaleDateString(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
302 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
308 static HRESULT
Date_toLocaleTimeString(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
309 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
315 /* ECMA-262 3rd Edition 15.9.5.9 */
316 static HRESULT
Date_getTime(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
317 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
321 if(!is_class(dispex
, JSCLASS_DATE
)) {
322 FIXME("throw TypeError\n");
327 DateInstance
*date
= (DateInstance
*)dispex
;
328 num_set_val(retv
, date
->time
);
333 /* ECMA-262 3th Edition 15.9.1.3 */
334 static HRESULT
Date_getFullYear(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
335 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
339 if(!is_class(dispex
, JSCLASS_DATE
)) {
340 FIXME("throw TypeError\n");
345 DateInstance
*date
= (DateInstance
*)dispex
;
346 DOUBLE time
= date
->time
- date
->bias
*MS_PER_MINUTE
;
348 num_set_val(retv
, year_from_time(time
));
353 /* ECMA-262 3th Edition 15.9.1.3 */
354 static HRESULT
Date_getUTCFullYear(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
355 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
359 if(!is_class(dispex
, JSCLASS_DATE
)) {
360 FIXME("throw TypeError\n");
365 DateInstance
*date
= (DateInstance
*)dispex
;
366 num_set_val(retv
, year_from_time(date
->time
));
371 /* ECMA-262 3th Edition 15.9.1.4 */
372 static HRESULT
Date_getMonth(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
373 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
377 if(!is_class(dispex
, JSCLASS_DATE
)) {
378 FIXME("throw TypeError\n");
383 DateInstance
*date
= (DateInstance
*)dispex
;
384 DOUBLE time
= date
->time
- date
->bias
*MS_PER_MINUTE
;
386 num_set_val(retv
, month_from_time(time
));
391 /* ECMA-262 3th Edition 15.9.1.4 */
392 static HRESULT
Date_getUTCMonth(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
393 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
397 if(!is_class(dispex
, JSCLASS_DATE
)) {
398 FIXME("throw TypeError\n");
403 DateInstance
*date
= (DateInstance
*)dispex
;
404 num_set_val(retv
, month_from_time(date
->time
));
409 /* ECMA-262 3th Edition 15.9.1.5 */
410 static HRESULT
Date_getDate(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
411 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
415 if(!is_class(dispex
, JSCLASS_DATE
)) {
416 FIXME("throw TypeError\n");
421 DateInstance
*date
= (DateInstance
*)dispex
;
422 DOUBLE time
= date
->time
- date
->bias
*MS_PER_MINUTE
;
424 num_set_val(retv
, date_from_time(time
));
429 /* ECMA-262 3th Edition 15.9.1.5 */
430 static HRESULT
Date_getUTCDate(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
431 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
435 if(!is_class(dispex
, JSCLASS_DATE
)) {
436 FIXME("throw TypeError\n");
441 DateInstance
*date
= (DateInstance
*)dispex
;
442 num_set_val(retv
, date_from_time(date
->time
));
447 /* ECMA-262 3th Edition 15.9.1.6 */
448 static HRESULT
Date_getDay(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
449 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
453 if(!is_class(dispex
, JSCLASS_DATE
)) {
454 FIXME("throw TypeError\n");
459 DateInstance
*date
= (DateInstance
*)dispex
;
460 DOUBLE time
= date
->time
- date
->bias
*MS_PER_MINUTE
;
462 num_set_val(retv
, week_day(time
));
467 /* ECMA-262 3th Edition 15.9.1.6 */
468 static HRESULT
Date_getUTCDay(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
469 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
473 if(!is_class(dispex
, JSCLASS_DATE
)) {
474 FIXME("throw TypeError\n");
479 DateInstance
*date
= (DateInstance
*)dispex
;
480 num_set_val(retv
, week_day(date
->time
));
485 /* ECMA-262 3th Edition 15.9.1.10 */
486 static HRESULT
Date_getHours(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
487 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
491 if(!is_class(dispex
, JSCLASS_DATE
)) {
492 FIXME("throw TypeError\n");
497 DateInstance
*date
= (DateInstance
*)dispex
;
498 DOUBLE time
= date
->time
- date
->bias
*MS_PER_MINUTE
;
500 num_set_val(retv
, hour_from_time(time
));
505 /* ECMA-262 3th Edition 15.9.1.10 */
506 static HRESULT
Date_getUTCHours(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
507 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
511 if(!is_class(dispex
, JSCLASS_DATE
)) {
512 FIXME("throw TypeError\n");
517 DateInstance
*date
= (DateInstance
*)dispex
;
518 num_set_val(retv
, hour_from_time(date
->time
));
523 static HRESULT
Date_getMinutes(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
524 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
530 static HRESULT
Date_getUTCMinutes(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
531 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
537 static HRESULT
Date_getSeconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
538 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
544 static HRESULT
Date_getUTCSeconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
545 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
551 static HRESULT
Date_getMiliseconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
552 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
558 static HRESULT
Date_getUTCMiliseconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
559 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
565 static HRESULT
Date_getTimezoneOffset(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
566 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
572 static HRESULT
Date_setTime(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
573 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
581 if(!is_class(dispex
, JSCLASS_DATE
)) {
582 FIXME("throw TypeError\n");
587 if(retv
) num_set_nan(retv
);
591 hres
= to_number(dispex
->ctx
, get_arg(dp
, 0), ei
, &v
);
595 date
= (DateInstance
*)dispex
;
596 date
->time
= time_clip(num_val(&v
));
599 num_set_val(retv
, date
->time
);
604 static HRESULT
Date_setMiliseconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
605 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
611 static HRESULT
Date_setUTCMiliseconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
612 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
618 static HRESULT
Date_setSeconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
619 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
625 static HRESULT
Date_setUTCSeconds(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
626 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
632 static HRESULT
Date_setMinutes(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
633 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
639 static HRESULT
Date_setUTCMinutes(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
640 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
646 static HRESULT
Date_setHours(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
647 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
653 static HRESULT
Date_setUTCHours(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
654 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
660 static HRESULT
Date_setDate(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
661 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
667 static HRESULT
Date_setUTCDate(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
668 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
674 static HRESULT
Date_setMonth(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
675 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
681 static HRESULT
Date_setUTCMonth(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
682 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
688 static HRESULT
Date_setFullYear(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
689 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
695 static HRESULT
Date_setUTCFullYear(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
696 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
702 static HRESULT
Date_value(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
703 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*caller
)
709 static const builtin_prop_t Date_props
[] = {
710 {getDateW
, Date_getDate
, PROPF_METHOD
},
711 {getDayW
, Date_getDay
, PROPF_METHOD
},
712 {getFullYearW
, Date_getFullYear
, PROPF_METHOD
},
713 {getHoursW
, Date_getHours
, PROPF_METHOD
},
714 {getMilisecondsW
, Date_getMiliseconds
, PROPF_METHOD
},
715 {getMinutesW
, Date_getMinutes
, PROPF_METHOD
},
716 {getMonthW
, Date_getMonth
, PROPF_METHOD
},
717 {getSecondsW
, Date_getSeconds
, PROPF_METHOD
},
718 {getTimeW
, Date_getTime
, PROPF_METHOD
},
719 {getTimezoneOffsetW
, Date_getTimezoneOffset
, PROPF_METHOD
},
720 {getUTCDateW
, Date_getUTCDate
, PROPF_METHOD
},
721 {getUTCDayW
, Date_getUTCDay
, PROPF_METHOD
},
722 {getUTCFullYearW
, Date_getUTCFullYear
, PROPF_METHOD
},
723 {getUTCHoursW
, Date_getUTCHours
, PROPF_METHOD
},
724 {getUTCMilisecondsW
, Date_getUTCMiliseconds
, PROPF_METHOD
},
725 {getUTCMinutesW
, Date_getUTCMinutes
, PROPF_METHOD
},
726 {getUTCMonthW
, Date_getUTCMonth
, PROPF_METHOD
},
727 {getUTCSecondsW
, Date_getUTCSeconds
, PROPF_METHOD
},
728 {hasOwnPropertyW
, Date_hasOwnProperty
, PROPF_METHOD
},
729 {isPrototypeOfW
, Date_isPrototypeOf
, PROPF_METHOD
},
730 {propertyIsEnumerableW
, Date_propertyIsEnumerable
, PROPF_METHOD
},
731 {setDateW
, Date_setDate
, PROPF_METHOD
},
732 {setFullYearW
, Date_setFullYear
, PROPF_METHOD
},
733 {setHoursW
, Date_setHours
, PROPF_METHOD
},
734 {setMilisecondsW
, Date_setMiliseconds
, PROPF_METHOD
},
735 {setMinutesW
, Date_setMinutes
, PROPF_METHOD
},
736 {setMonthW
, Date_setMonth
, PROPF_METHOD
},
737 {setSecondsW
, Date_setSeconds
, PROPF_METHOD
},
738 {setTimeW
, Date_setTime
, PROPF_METHOD
},
739 {setUTCDateW
, Date_setUTCDate
, PROPF_METHOD
},
740 {setUTCFullYearW
, Date_setUTCFullYear
, PROPF_METHOD
},
741 {setUTCHoursW
, Date_setUTCHours
, PROPF_METHOD
},
742 {setUTCMilisecondsW
, Date_setUTCMiliseconds
, PROPF_METHOD
},
743 {setUTCMinutesW
, Date_setUTCMinutes
, PROPF_METHOD
},
744 {setUTCMonthW
, Date_setUTCMonth
, PROPF_METHOD
},
745 {setUTCSecondsW
, Date_setUTCSeconds
, PROPF_METHOD
},
746 {toDateStringW
, Date_toDateString
, PROPF_METHOD
},
747 {toLocaleDateStringW
, Date_toLocaleDateString
, PROPF_METHOD
},
748 {toLocaleStringW
, Date_toLocaleString
, PROPF_METHOD
},
749 {toLocaleTimeStringW
, Date_toLocaleTimeString
, PROPF_METHOD
},
750 {toStringW
, Date_toString
, PROPF_METHOD
},
751 {toTimeStringW
, Date_toTimeString
, PROPF_METHOD
},
752 {toUTCStringW
, Date_toUTCString
, PROPF_METHOD
},
753 {valueOfW
, Date_valueOf
, PROPF_METHOD
},
756 static const builtin_info_t Date_info
= {
758 {NULL
, Date_value
, 0},
759 sizeof(Date_props
)/sizeof(*Date_props
),
765 static HRESULT
create_date(script_ctx_t
*ctx
, BOOL use_constr
, DOUBLE time
, DispatchEx
**ret
)
769 TIME_ZONE_INFORMATION tzi
;
771 GetTimeZoneInformation(&tzi
);
773 date
= heap_alloc_zero(sizeof(DateInstance
));
775 return E_OUTOFMEMORY
;
778 hres
= init_dispex_from_constr(&date
->dispex
, ctx
, &Date_info
, ctx
->date_constr
);
780 hres
= init_dispex(&date
->dispex
, ctx
, &Date_info
, NULL
);
787 date
->bias
= tzi
.Bias
;
789 *ret
= &date
->dispex
;
793 static HRESULT
DateConstr_value(DispatchEx
*dispex
, LCID lcid
, WORD flags
, DISPPARAMS
*dp
,
794 VARIANT
*retv
, jsexcept_t
*ei
, IServiceProvider
*sp
)
802 case DISPATCH_CONSTRUCT
:
803 switch(arg_cnt(dp
)) {
804 /* ECMA-262 3rd Edition 15.9.3.3 */
809 GetSystemTimeAsFileTime(&time
);
810 lltime
= ((LONGLONG
)time
.dwHighDateTime
<<32)
811 + time
.dwLowDateTime
;
813 hres
= create_date(dispex
->ctx
, TRUE
, lltime
/10000-TIME_EPOCH
, &date
);
819 /* ECMA-262 3rd Edition 15.9.3.2 */
823 hres
= to_primitive(dispex
->ctx
, get_arg(dp
,0), ei
, &prim
);
827 if(V_VT(&prim
) == VT_BSTR
) {
828 FIXME("VT_BSTR not supported\n");
832 hres
= to_number(dispex
->ctx
, &prim
, ei
, &num
);
837 hres
= create_date(dispex
->ctx
, TRUE
, time_clip(num_val(&num
)), &date
);
844 FIXME("unimplemented argcnt %d\n", arg_cnt(dp
));
848 V_VT(retv
) = VT_DISPATCH
;
849 V_DISPATCH(retv
) = (IDispatch
*)_IDispatchEx_(date
);
853 FIXME("unimplemented flags %x\n", flags
);
860 HRESULT
create_date_constr(script_ctx_t
*ctx
, DispatchEx
**ret
)
865 hres
= create_date(ctx
, FALSE
, 0.0, &date
);
869 hres
= create_builtin_function(ctx
, DateConstr_value
, PROPF_CONSTR
, date
, ret
);
871 jsdisp_release(date
);