2 * Copyright 2008 Jacek Caban for CodeWeavers
3 * Copyright 2009 Piotr Caban
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.1 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 St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/port.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
32 /* 1601 to 1970 is 369 years plus 89 leap days */
33 #define TIME_EPOCH ((ULONGLONG)(369 * 365 + 89) * 86400 * 1000)
38 /* ECMA-262 3rd Edition 15.9.1.1 */
42 SYSTEMTIME standardDate;
44 SYSTEMTIME daylightDate;
48 static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
49 static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
50 static const WCHAR propertyIsEnumerableW[] =
51 {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
52 static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
53 static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
54 static const WCHAR toUTCStringW[] = {'t','o','U','T','C','S','t','r','i','n','g',0};
55 static const WCHAR toDateStringW[] = {'t','o','D','a','t','e','S','t','r','i','n','g',0};
56 static const WCHAR toTimeStringW[] = {'t','o','T','i','m','e','S','t','r','i','n','g',0};
57 static const WCHAR toLocaleDateStringW[] = {'t','o','L','o','c','a','l','e','D','a','t','e','S','t','r','i','n','g',0};
58 static const WCHAR toLocaleTimeStringW[] = {'t','o','L','o','c','a','l','e','T','i','m','e','S','t','r','i','n','g',0};
59 static const WCHAR getTimeW[] = {'g','e','t','T','i','m','e',0};
60 static const WCHAR getFullYearW[] = {'g','e','t','F','u','l','l','Y','e','a','r',0};
61 static const WCHAR getUTCFullYearW[] = {'g','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};
62 static const WCHAR getMonthW[] = {'g','e','t','M','o','n','t','h',0};
63 static const WCHAR getUTCMonthW[] = {'g','e','t','U','T','C','M','o','n','t','h',0};
64 static const WCHAR getDateW[] = {'g','e','t','D','a','t','e',0};
65 static const WCHAR getUTCDateW[] = {'g','e','t','U','T','C','D','a','t','e',0};
66 static const WCHAR getDayW[] = {'g','e','t','D','a','y',0};
67 static const WCHAR getUTCDayW[] = {'g','e','t','U','T','C','D','a','y',0};
68 static const WCHAR getHoursW[] = {'g','e','t','H','o','u','r','s',0};
69 static const WCHAR getUTCHoursW[] = {'g','e','t','U','T','C','H','o','u','r','s',0};
70 static const WCHAR getMinutesW[] = {'g','e','t','M','i','n','u','t','e','s',0};
71 static const WCHAR getUTCMinutesW[] = {'g','e','t','U','T','C','M','i','n','u','t','e','s',0};
72 static const WCHAR getSecondsW[] = {'g','e','t','S','e','c','o','n','d','s',0};
73 static const WCHAR getUTCSecondsW[] = {'g','e','t','U','T','C','S','e','c','o','n','d','s',0};
74 static const WCHAR getMillisecondsW[] = {'g','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0};
75 static const WCHAR getUTCMillisecondsW[] = {'g','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0};
76 static const WCHAR getTimezoneOffsetW[] = {'g','e','t','T','i','m','e','z','o','n','e','O','f','f','s','e','t',0};
77 static const WCHAR setTimeW[] = {'s','e','t','T','i','m','e',0};
78 static const WCHAR setMillisecondsW[] = {'s','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0};
79 static const WCHAR setUTCMillisecondsW[] = {'s','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0};
80 static const WCHAR setSecondsW[] = {'s','e','t','S','e','c','o','n','d','s',0};
81 static const WCHAR setUTCSecondsW[] = {'s','e','t','U','T','C','S','e','c','o','n','d','s',0};
82 static const WCHAR setMinutesW[] = {'s','e','t','M','i','n','u','t','e','s',0};
83 static const WCHAR setUTCMinutesW[] = {'s','e','t','U','T','C','M','i','n','u','t','e','s',0};
84 static const WCHAR setHoursW[] = {'s','e','t','H','o','u','r','s',0};
85 static const WCHAR setUTCHoursW[] = {'s','e','t','U','T','C','H','o','u','r','s',0};
86 static const WCHAR setDateW[] = {'s','e','t','D','a','t','e',0};
87 static const WCHAR setUTCDateW[] = {'s','e','t','U','T','C','D','a','t','e',0};
88 static const WCHAR setMonthW[] = {'s','e','t','M','o','n','t','h',0};
89 static const WCHAR setUTCMonthW[] = {'s','e','t','U','T','C','M','o','n','t','h',0};
90 static const WCHAR setFullYearW[] = {'s','e','t','F','u','l','l','Y','e','a','r',0};
91 static const WCHAR setUTCFullYearW[] = {'s','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};
92 static const WCHAR getYearW[] = {'g','e','t','Y','e','a','r',0};
94 static const WCHAR UTCW[] = {'U','T','C',0};
95 static const WCHAR parseW[] = {'p','a','r','s','e',0};
97 static inline DateInstance *date_this(vdisp_t *jsthis)
99 return is_vclass(jsthis, JSCLASS_DATE) ? (DateInstance*)jsthis->u.jsdisp : NULL;
102 /*ECMA-262 3rd Edition 15.9.1.2 */
103 #define MS_PER_DAY 86400000
104 #define MS_PER_HOUR 3600000
105 #define MS_PER_MINUTE 60000
107 /* ECMA-262 3rd Edition 15.9.1.2 */
108 static inline DOUBLE day(DOUBLE time)
110 return floor(time / MS_PER_DAY);
113 /* ECMA-262 3rd Edition 15.9.1.2 */
114 static inline DOUBLE time_within_day(DOUBLE time)
118 ret = fmod(time, MS_PER_DAY);
125 /* ECMA-262 3rd Edition 15.9.1.3 */
126 static inline DOUBLE days_in_year(DOUBLE year)
130 if(year != (int)year)
134 if(y%4 != 0) return 365;
135 if(y%100 != 0) return 366;
136 if(y%400 != 0) return 365;
140 /* ECMA-262 3rd Edition 15.9.1.3 */
141 static inline DOUBLE day_from_year(DOUBLE year)
143 if(year != (int)year)
146 return floor(365.0*(year-1970) + floor((year-1969)/4)
147 - floor((year-1901)/100) + floor((year-1601)/400));
150 static inline int day_from_month(int month, int in_leap_year)
159 return 59+in_leap_year;
161 return 90+in_leap_year;
163 return 120+in_leap_year;
165 return 151+in_leap_year;
167 return 181+in_leap_year;
169 return 212+in_leap_year;
171 return 243+in_leap_year;
173 return 273+in_leap_year;
175 return 304+in_leap_year;
177 return 334+in_leap_year;
181 /* ECMA-262 3rd Edition 15.9.1.3 */
182 static inline DOUBLE time_from_year(DOUBLE year)
184 return MS_PER_DAY*day_from_year(year);
187 /* ECMA-262 3rd Edition 15.9.1.3 */
188 static inline DOUBLE year_from_time(DOUBLE time)
195 y = 1970 + time/365.25/MS_PER_DAY;
197 if(time_from_year(y) > time)
198 while(time_from_year(y) > time) y--;
200 while(time_from_year(y+1)<=time) y++;
205 /* ECMA-262 3rd Edition 15.9.1.3 */
206 static inline int in_leap_year(DOUBLE time)
208 if(days_in_year(year_from_time(time))==366)
213 /* ECMA-262 3rd Edition 15.9.1.4 */
214 static inline int day_within_year(DOUBLE time)
216 return day(time) - day_from_year(year_from_time(time));
219 /* ECMA-262 3rd Edition 15.9.1.4 */
220 static inline DOUBLE month_from_time(DOUBLE time)
222 int ily = in_leap_year(time);
223 int dwy = day_within_year(time);
228 if(0<=dwy && dwy<31) return 0;
229 if(dwy < 59+ily) return 1;
230 if(dwy < 90+ily) return 2;
231 if(dwy < 120+ily) return 3;
232 if(dwy < 151+ily) return 4;
233 if(dwy < 181+ily) return 5;
234 if(dwy < 212+ily) return 6;
235 if(dwy < 243+ily) return 7;
236 if(dwy < 273+ily) return 8;
237 if(dwy < 304+ily) return 9;
238 if(dwy < 334+ily) return 10;
242 /* ECMA-262 3rd Edition 15.9.1.5 */
243 static inline DOUBLE date_from_time(DOUBLE time)
245 int dwy = day_within_year(time);
246 int ily = in_leap_year(time);
247 int mft = month_from_time(time);
252 if(mft==0) return dwy+1;
253 if(mft==1) return dwy-30;
254 if(mft==2) return dwy-58-ily;
255 if(mft==3) return dwy-89-ily;
256 if(mft==4) return dwy-119-ily;
257 if(mft==5) return dwy-150-ily;
258 if(mft==6) return dwy-180-ily;
259 if(mft==7) return dwy-211-ily;
260 if(mft==8) return dwy-242-ily;
261 if(mft==9) return dwy-272-ily;
262 if(mft==10) return dwy-303-ily;
266 /* ECMA-262 3rd Edition 15.9.1.6 */
267 static inline DOUBLE week_day(DOUBLE time)
274 ret = fmod(day(time)+4, 7);
280 static inline DOUBLE convert_time(int year, SYSTEMTIME st)
291 time = time_from_year(year);
292 time += (DOUBLE)day_from_month(st.wMonth-1, in_leap_year(time)) * MS_PER_DAY;
295 set_week_day = st.wDayOfWeek-week_day(time);
298 time += set_week_day * MS_PER_DAY;
300 time += (DOUBLE)(st.wDay-1) * 7 * MS_PER_DAY;
301 if(month_from_time(time) != st.wMonth-1)
302 time -= 7 * MS_PER_DAY;
305 time += st.wDay * MS_PER_DAY;
307 time += st.wHour * MS_PER_HOUR;
308 time += st.wMinute * MS_PER_MINUTE;
313 /* ECMA-262 3rd Edition 15.9.1.9 */
314 static inline DOUBLE daylight_saving_ta(DOUBLE time, DateInstance *date)
316 int year = year_from_time(time);
317 DOUBLE standardTime, daylightTime;
322 standardTime = convert_time(year, date->standardDate);
323 daylightTime = convert_time(year, date->daylightDate);
325 if(isnan(standardTime) || isnan(daylightTime))
327 else if(standardTime > daylightTime) {
328 if(daylightTime <= time && time < standardTime)
329 return date->daylightBias;
331 return date->standardBias;
334 if(standardTime <= time && time < daylightTime)
335 return date->standardBias;
337 return date->daylightBias;
341 /* ECMA-262 3rd Edition 15.9.1.9 */
342 static inline DOUBLE local_time(DOUBLE time, DateInstance *date)
344 return time - (daylight_saving_ta(time, date)+date->bias)*MS_PER_MINUTE;
347 /* ECMA-262 3rd Edition 15.9.1.9 */
348 static inline DOUBLE utc(DOUBLE time, DateInstance *date)
350 time += date->bias * MS_PER_MINUTE;
351 return time + daylight_saving_ta(time, date)*MS_PER_MINUTE;
354 /* ECMA-262 3rd Edition 15.9.1.10 */
355 static inline DOUBLE hour_from_time(DOUBLE time)
362 ret = fmod(floor(time/MS_PER_HOUR), 24);
368 /* ECMA-262 3rd Edition 15.9.1.10 */
369 static inline DOUBLE min_from_time(DOUBLE time)
376 ret = fmod(floor(time/MS_PER_MINUTE), 60);
382 /* ECMA-262 3rd Edition 15.9.1.10 */
383 static inline DOUBLE sec_from_time(DOUBLE time)
390 ret = fmod(floor(time/1000), 60);
396 /* ECMA-262 3rd Edition 15.9.1.10 */
397 static inline DOUBLE ms_from_time(DOUBLE time)
404 ret = fmod(time, 1000);
405 if(ret<0) ret += 1000;
410 /* ECMA-262 3rd Edition 15.9.1.11 */
411 static inline DOUBLE make_time(DOUBLE hour, DOUBLE min, DOUBLE sec, DOUBLE ms)
413 return hour*MS_PER_HOUR + min*MS_PER_MINUTE + sec*1000 + ms;
416 /* ECMA-262 3rd Edition 15.9.1.12 */
417 static inline DOUBLE make_day(DOUBLE year, DOUBLE month, DOUBLE day)
421 year += floor(month/12);
423 month = fmod(month, 12);
424 if(month<0) month += 12;
426 time = time_from_year(year);
428 day += floor(time / MS_PER_DAY);
429 day += day_from_month(month, in_leap_year(time));
434 /* ECMA-262 3rd Edition 15.9.1.13 */
435 static inline DOUBLE make_date(DOUBLE day, DOUBLE time)
437 return day*MS_PER_DAY + time;
440 /* ECMA-262 3rd Edition 15.9.1.14 */
441 static inline DOUBLE time_clip(DOUBLE time)
443 if(8.64e15 < time || time < -8.64e15) {
450 static SYSTEMTIME create_systemtime(DOUBLE time)
454 st.wYear = year_from_time(time);
455 st.wMonth = month_from_time(time) + 1;
456 st.wDayOfWeek = week_day(time);
457 st.wDay = date_from_time(time);
458 st.wHour = hour_from_time(time);
459 st.wMinute = min_from_time(time);
460 st.wSecond = sec_from_time(time);
461 st.wMilliseconds = ms_from_time(time);
466 static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset, VARIANT *retv)
468 static const WCHAR NaNW[] = { 'N','a','N',0 };
469 static const WCHAR formatW[] = { '%','s',' ','%','s',' ','%','d',' ',
470 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ',
471 'U','T','C','%','c','%','0','2','d','%','0','2','d',' ','%','d','%','s',0 };
472 static const WCHAR formatUTCW[] = { '%','s',' ','%','s',' ','%','d',' ',
473 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ',
474 'U','T','C',' ','%','d','%','s',0 };
475 static const WCHAR formatNoOffsetW[] = { '%','s',' ','%','s',' ',
476 '%','d',' ','%','0','2','d',':','%','0','2','d',':',
477 '%','0','2','d',' ','%','d','%','s',0 };
478 static const WCHAR ADW[] = { 0 };
479 static const WCHAR BCW[] = { ' ','B','.','C','.',0 };
481 static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1,
482 LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4,
483 LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 };
484 static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
485 LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
486 LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
487 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
488 LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
489 LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
491 BOOL formatAD = TRUE;
494 int len, size, year, day;
495 DWORD lcid_en, week_id, month_id;
500 V_VT(retv) = VT_BSTR;
501 V_BSTR(retv) = SysAllocString(NaNW);
503 return E_OUTOFMEMORY;
511 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
513 week_id = week_ids[(int)week_day(time)];
514 size = GetLocaleInfoW(lcid_en, week_id, NULL, 0);
515 week = SysAllocStringLen(NULL, size);
517 return E_OUTOFMEMORY;
518 GetLocaleInfoW(lcid_en, week_id, week, size);
521 month_id = month_ids[(int)month_from_time(time)];
522 size = GetLocaleInfoW(lcid_en, month_id, NULL, 0);
523 month = SysAllocStringLen(NULL, size);
526 return E_OUTOFMEMORY;
528 GetLocaleInfoW(lcid_en, month_id, month, size);
531 year = year_from_time(time);
539 year = year_from_time(time);
546 day = date_from_time(time);
551 day = date_from_time(time);
553 if(!show_offset) len -= 9;
554 else if(offset == 0) len -= 5;
555 else if(offset < 0) {
560 date_str = SysAllocStringLen(NULL, len);
563 SysFreeString(month);
564 return E_OUTOFMEMORY;
568 sprintfW(date_str, formatNoOffsetW, week, month, day,
569 (int)hour_from_time(time), (int)min_from_time(time),
570 (int)sec_from_time(time), year, formatAD?ADW:BCW);
572 sprintfW(date_str, formatW, week, month, day,
573 (int)hour_from_time(time), (int)min_from_time(time),
574 (int)sec_from_time(time), sign, offset/60, offset%60,
575 year, formatAD?ADW:BCW);
577 sprintfW(date_str, formatUTCW, week, month, day,
578 (int)hour_from_time(time), (int)min_from_time(time),
579 (int)sec_from_time(time), year, formatAD?ADW:BCW);
582 SysFreeString(month);
584 V_VT(retv) = VT_BSTR;
585 V_BSTR(retv) = date_str;
590 /* ECMA-262 3rd Edition 15.9.1.2 */
591 static HRESULT dateobj_to_string(DateInstance *date, VARIANT *retv)
596 time = local_time(date->time, date);
597 offset = date->bias +
598 daylight_saving_ta(time, date);
600 return date_to_string(time, TRUE, offset, retv);
603 static HRESULT Date_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
604 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
610 if(!(date = date_this(jsthis)))
611 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
613 return dateobj_to_string(date, retv);
616 /* ECMA-262 3rd Edition 15.9.1.5 */
617 static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
618 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
620 static const WCHAR NaNW[] = { 'N','a','N',0 };
624 int date_len, time_len;
628 if(!(date = date_this(jsthis)))
629 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
631 if(isnan(date->time)) {
633 V_VT(retv) = VT_BSTR;
634 V_BSTR(retv) = SysAllocString(NaNW);
636 return E_OUTOFMEMORY;
641 st = create_systemtime(local_time(date->time, date));
643 if(st.wYear<1601 || st.wYear>9999)
644 return dateobj_to_string(date, retv);
647 date_len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
648 time_len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
649 date_str = SysAllocStringLen(NULL, date_len+time_len-1);
651 return E_OUTOFMEMORY;
652 GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, date_len);
653 GetTimeFormatW(ctx->lcid, 0, &st, NULL, &date_str[date_len], time_len);
654 date_str[date_len-1] = ' ';
656 V_VT(retv) = VT_BSTR;
657 V_BSTR(retv) = date_str;
662 static HRESULT Date_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
663 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
669 if(!(date = date_this(jsthis)))
670 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
673 num_set_val(retv, date->time);
677 /* ECMA-262 3rd Edition 15.9.5.42 */
678 static HRESULT Date_toUTCString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
679 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
681 static const WCHAR NaNW[] = { 'N','a','N',0 };
682 static const WCHAR formatADW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ',
683 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 };
684 static const WCHAR formatBCW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ','B','.','C','.',' ',
685 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 };
687 static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1,
688 LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4,
689 LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 };
690 static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
691 LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
692 LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
693 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
694 LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
695 LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
697 BOOL formatAD = TRUE;
701 int len, size, year, day;
702 DWORD lcid_en, week_id, month_id;
706 if(!(date = date_this(jsthis)))
707 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
709 if(isnan(date->time)) {
711 V_VT(retv) = VT_BSTR;
712 V_BSTR(retv) = SysAllocString(NaNW);
714 return E_OUTOFMEMORY;
722 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
724 week_id = week_ids[(int)week_day(date->time)];
725 size = GetLocaleInfoW(lcid_en, week_id, NULL, 0);
726 week = SysAllocStringLen(NULL, size);
728 return E_OUTOFMEMORY;
729 GetLocaleInfoW(lcid_en, week_id, week, size);
732 month_id = month_ids[(int)month_from_time(date->time)];
733 size = GetLocaleInfoW(lcid_en, month_id, NULL, 0);
734 month = SysAllocStringLen(NULL, size);
737 return E_OUTOFMEMORY;
739 GetLocaleInfoW(lcid_en, month_id, month, size);
742 year = year_from_time(date->time);
750 year = year_from_time(date->time);
757 day = date_from_time(date->time);
762 day = date_from_time(date->time);
764 date_str = SysAllocStringLen(NULL, len);
767 SysFreeString(month);
768 return E_OUTOFMEMORY;
770 sprintfW(date_str, formatAD?formatADW:formatBCW, week, day, month, year,
771 (int)hour_from_time(date->time), (int)min_from_time(date->time),
772 (int)sec_from_time(date->time));
775 SysFreeString(month);
777 V_VT(retv) = VT_BSTR;
778 V_BSTR(retv) = date_str;
783 /* ECMA-262 3rd Edition 15.9.5.3 */
784 static HRESULT dateobj_to_date_string(DateInstance *date, VARIANT *retv)
786 static const WCHAR NaNW[] = { 'N','a','N',0 };
787 static const WCHAR formatADW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',0 };
788 static const WCHAR formatBCW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',' ','B','.','C','.',0 };
790 static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1,
791 LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4,
792 LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 };
793 static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
794 LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
795 LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
796 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
797 LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
798 LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
800 BOOL formatAD = TRUE;
804 int len, size, year, day;
805 DWORD lcid_en, week_id, month_id;
807 if(isnan(date->time)) {
809 V_VT(retv) = VT_BSTR;
810 V_BSTR(retv) = SysAllocString(NaNW);
812 return E_OUTOFMEMORY;
817 time = local_time(date->time, date);
822 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
824 week_id = week_ids[(int)week_day(time)];
825 size = GetLocaleInfoW(lcid_en, week_id, NULL, 0);
826 week = SysAllocStringLen(NULL, size);
828 return E_OUTOFMEMORY;
829 GetLocaleInfoW(lcid_en, week_id, week, size);
832 month_id = month_ids[(int)month_from_time(time)];
833 size = GetLocaleInfoW(lcid_en, month_id, NULL, 0);
834 month = SysAllocStringLen(NULL, size);
837 return E_OUTOFMEMORY;
839 GetLocaleInfoW(lcid_en, month_id, month, size);
842 year = year_from_time(time);
850 year = year_from_time(time);
857 day = date_from_time(time);
862 day = date_from_time(time);
864 date_str = SysAllocStringLen(NULL, len);
867 SysFreeString(month);
868 return E_OUTOFMEMORY;
870 sprintfW(date_str, formatAD?formatADW:formatBCW, week, month, day, year);
873 SysFreeString(month);
875 V_VT(retv) = VT_BSTR;
876 V_BSTR(retv) = date_str;
881 static HRESULT Date_toDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
882 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
886 if(!(date = date_this(jsthis)))
887 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
889 return dateobj_to_date_string(date, retv);
892 /* ECMA-262 3rd Edition 15.9.5.4 */
893 static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
894 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
896 static const WCHAR NaNW[] = { 'N','a','N',0 };
897 static const WCHAR formatW[] = { '%','0','2','d',':','%','0','2','d',':','%','0','2','d',
898 ' ','U','T','C','%','c','%','0','2','d','%','0','2','d',0 };
899 static const WCHAR formatUTCW[] = { '%','0','2','d',':','%','0','2','d',
900 ':','%','0','2','d',' ','U','T','C',0 };
909 if(!(date = date_this(jsthis)))
910 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
912 if(isnan(date->time)) {
914 V_VT(retv) = VT_BSTR;
915 V_BSTR(retv) = SysAllocString(NaNW);
917 return E_OUTOFMEMORY;
922 time = local_time(date->time, date);
925 date_str = SysAllocStringLen(NULL, 17);
927 return E_OUTOFMEMORY;
929 offset = date->bias +
930 daylight_saving_ta(time, date);
939 sprintfW(date_str, formatW, (int)hour_from_time(time),
940 (int)min_from_time(time), (int)sec_from_time(time),
941 sign, offset/60, offset%60);
943 sprintfW(date_str, formatUTCW, (int)hour_from_time(time),
944 (int)min_from_time(time), (int)sec_from_time(time));
946 V_VT(retv) = VT_BSTR;
947 V_BSTR(retv) = date_str;
952 /* ECMA-262 3rd Edition 15.9.5.6 */
953 static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
954 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
956 static const WCHAR NaNW[] = { 'N','a','N',0 };
964 if(!(date = date_this(jsthis)))
965 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
967 if(isnan(date->time)) {
969 V_VT(retv) = VT_BSTR;
970 V_BSTR(retv) = SysAllocString(NaNW);
972 return E_OUTOFMEMORY;
977 st = create_systemtime(local_time(date->time, date));
979 if(st.wYear<1601 || st.wYear>9999)
980 return dateobj_to_date_string(date, retv);
983 len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
984 date_str = SysAllocStringLen(NULL, len);
986 return E_OUTOFMEMORY;
987 GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, len);
989 V_VT(retv) = VT_BSTR;
990 V_BSTR(retv) = date_str;
995 /* ECMA-262 3rd Edition 15.9.5.7 */
996 static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
997 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
999 static const WCHAR NaNW[] = { 'N','a','N',0 };
1007 if(!(date = date_this(jsthis)))
1008 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1010 if(isnan(date->time)) {
1012 V_VT(retv) = VT_BSTR;
1013 V_BSTR(retv) = SysAllocString(NaNW);
1015 return E_OUTOFMEMORY;
1020 st = create_systemtime(local_time(date->time, date));
1022 if(st.wYear<1601 || st.wYear>9999)
1023 return Date_toTimeString(ctx, jsthis, flags, dp, retv, ei, caller);
1026 len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
1027 date_str = SysAllocStringLen(NULL, len);
1029 return E_OUTOFMEMORY;
1030 GetTimeFormatW(ctx->lcid, 0, &st, NULL, date_str, len);
1032 V_VT(retv) = VT_BSTR;
1033 V_BSTR(retv) = date_str;
1038 /* ECMA-262 3rd Edition 15.9.5.9 */
1039 static HRESULT Date_getTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1040 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1046 if(!(date = date_this(jsthis)))
1047 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1050 num_set_val(retv, date->time);
1054 /* ECMA-262 3rd Edition 15.9.5.10 */
1055 static HRESULT Date_getFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1056 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1062 if(!(date = date_this(jsthis)))
1063 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1066 DOUBLE time = local_time(date->time, date);
1068 num_set_val(retv, year_from_time(time));
1073 /* ECMA-262 3rd Edition 15.9.5.11 */
1074 static HRESULT Date_getUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1075 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1081 if(!(date = date_this(jsthis)))
1082 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1085 num_set_val(retv, year_from_time(date->time));
1089 /* ECMA-262 3rd Edition 15.9.5.12 */
1090 static HRESULT Date_getMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1091 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1097 if(!(date = date_this(jsthis)))
1098 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1101 DOUBLE time = local_time(date->time, date);
1103 num_set_val(retv, month_from_time(time));
1108 /* ECMA-262 3rd Edition 15.9.5.13 */
1109 static HRESULT Date_getUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1110 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1116 if(!(date = date_this(jsthis)))
1117 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1120 num_set_val(retv, month_from_time(date->time));
1124 /* ECMA-262 3rd Edition 15.9.5.14 */
1125 static HRESULT Date_getDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1126 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1132 if(!(date = date_this(jsthis)))
1133 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1136 DOUBLE time = local_time(date->time, date);
1138 num_set_val(retv, date_from_time(time));
1143 /* ECMA-262 3rd Edition 15.9.5.15 */
1144 static HRESULT Date_getUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1145 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1151 if(!(date = date_this(jsthis)))
1152 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1155 num_set_val(retv, date_from_time(date->time));
1159 /* ECMA-262 3rd Edition 15.9.5.16 */
1160 static HRESULT Date_getDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1161 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1167 if(!(date = date_this(jsthis)))
1168 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1171 DOUBLE time = local_time(date->time, date);
1173 num_set_val(retv, week_day(time));
1178 /* ECMA-262 3rd Edition 15.9.5.17 */
1179 static HRESULT Date_getUTCDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1180 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1186 if(!(date = date_this(jsthis)))
1187 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1190 num_set_val(retv, week_day(date->time));
1194 /* ECMA-262 3rd Edition 15.9.5.18 */
1195 static HRESULT Date_getHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1196 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1202 if(!(date = date_this(jsthis)))
1203 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1206 DOUBLE time = local_time(date->time, date);
1208 num_set_val(retv, hour_from_time(time));
1213 /* ECMA-262 3rd Edition 15.9.5.19 */
1214 static HRESULT Date_getUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1215 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1221 if(!(date = date_this(jsthis)))
1222 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1225 num_set_val(retv, hour_from_time(date->time));
1229 /* ECMA-262 3rd Edition 15.9.5.20 */
1230 static HRESULT Date_getMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1231 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1237 if(!(date = date_this(jsthis)))
1238 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1241 DOUBLE time = local_time(date->time, date);
1243 num_set_val(retv, min_from_time(time));
1248 /* ECMA-262 3rd Edition 15.9.5.21 */
1249 static HRESULT Date_getUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1250 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1256 if(!(date = date_this(jsthis)))
1257 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1260 num_set_val(retv, min_from_time(date->time));
1264 /* ECMA-262 3rd Edition 15.9.5.22 */
1265 static HRESULT Date_getSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1266 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1272 if(!(date = date_this(jsthis)))
1273 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1276 DOUBLE time = local_time(date->time, date);
1278 num_set_val(retv, sec_from_time(time));
1283 /* ECMA-262 3rd Edition 15.9.5.23 */
1284 static HRESULT Date_getUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1285 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1291 if(!(date = date_this(jsthis)))
1292 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1295 num_set_val(retv, sec_from_time(date->time));
1299 /* ECMA-262 3rd Edition 15.9.5.24 */
1300 static HRESULT Date_getMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1301 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1307 if(!(date = date_this(jsthis)))
1308 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1311 DOUBLE time = local_time(date->time, date);
1313 num_set_val(retv, ms_from_time(time));
1318 /* ECMA-262 3rd Edition 15.9.5.25 */
1319 static HRESULT Date_getUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1320 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1326 if(!(date = date_this(jsthis)))
1327 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1330 num_set_val(retv, ms_from_time(date->time));
1334 /* ECMA-262 3rd Edition 15.9.5.26 */
1335 static HRESULT Date_getTimezoneOffset(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1336 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1342 if(!(date = date_this(jsthis)))
1343 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1346 num_set_val(retv, floor(
1347 (date->time-local_time(date->time, date))/MS_PER_MINUTE));
1351 /* ECMA-262 3rd Edition 15.9.5.27 */
1352 static HRESULT Date_setTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1353 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1361 if(!(date = date_this(jsthis)))
1362 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1365 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1367 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1371 date->time = time_clip(num_val(&v));
1374 num_set_val(retv, date->time);
1379 /* ECMA-262 3rd Edition 15.9.5.28 */
1380 static HRESULT Date_setMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1381 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1390 if(!(date = date_this(jsthis)))
1391 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1394 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1396 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1400 t = local_time(date->time, date);
1401 t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t),
1402 sec_from_time(t), num_val(&v)));
1403 date->time = time_clip(utc(t, date));
1406 num_set_val(retv, date->time);
1411 /* ECMA-262 3rd Edition 15.9.5.29 */
1412 static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1413 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1422 if(!(date = date_this(jsthis)))
1423 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1426 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1428 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1433 t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t),
1434 sec_from_time(t), num_val(&v)));
1435 date->time = time_clip(t);
1438 num_set_val(retv, date->time);
1443 /* ECMA-262 3rd Edition 15.9.5.30 */
1444 static HRESULT Date_setSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1445 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1454 if(!(date = date_this(jsthis)))
1455 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1458 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1460 t = local_time(date->time, date);
1462 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1467 if(arg_cnt(dp) > 1) {
1468 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1473 else ms = ms_from_time(t);
1475 t = make_date(day(t), make_time(hour_from_time(t),
1476 min_from_time(t), sec, ms));
1477 date->time = time_clip(utc(t, date));
1480 num_set_val(retv, date->time);
1485 /* ECMA-262 3rd Edition 15.9.5.31 */
1486 static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1487 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1496 if(!(date = date_this(jsthis)))
1497 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1500 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1504 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1509 if(arg_cnt(dp) > 1) {
1510 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1515 else ms = ms_from_time(t);
1517 t = make_date(day(t), make_time(hour_from_time(t),
1518 min_from_time(t), sec, ms));
1519 date->time = time_clip(t);
1522 num_set_val(retv, date->time);
1527 /* ECMA-262 3rd Edition 15.9.5.33 */
1528 static HRESULT Date_setMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1529 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1534 DOUBLE t, min, sec, ms;
1538 if(!(date = date_this(jsthis)))
1539 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1542 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1544 t = local_time(date->time, date);
1546 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1551 if(arg_cnt(dp) > 1) {
1552 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1557 else sec = sec_from_time(t);
1559 if(arg_cnt(dp) > 2) {
1560 hres = to_number(ctx, get_arg(dp, 2), ei, &v);
1565 else ms = ms_from_time(t);
1567 t = make_date(day(t), make_time(hour_from_time(t),
1569 date->time = time_clip(utc(t, date));
1572 num_set_val(retv, date->time);
1577 /* ECMA-262 3rd Edition 15.9.5.34 */
1578 static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1579 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1584 DOUBLE t, min, sec, ms;
1588 if(!(date = date_this(jsthis)))
1589 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1592 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1596 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1601 if(arg_cnt(dp) > 1) {
1602 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1607 else sec = sec_from_time(t);
1609 if(arg_cnt(dp) > 2) {
1610 hres = to_number(ctx, get_arg(dp, 2), ei, &v);
1615 else ms = ms_from_time(t);
1617 t = make_date(day(t), make_time(hour_from_time(t),
1619 date->time = time_clip(t);
1622 num_set_val(retv, date->time);
1627 /* ECMA-262 3rd Edition 15.9.5.35 */
1628 static HRESULT Date_setHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1629 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1634 DOUBLE t, hour, min, sec, ms;
1638 if(!(date = date_this(jsthis)))
1639 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1642 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1644 t = local_time(date->time, date);
1646 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1651 if(arg_cnt(dp) > 1) {
1652 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1657 else min = min_from_time(t);
1659 if(arg_cnt(dp) > 2) {
1660 hres = to_number(ctx, get_arg(dp, 2), ei, &v);
1665 else sec = sec_from_time(t);
1667 if(arg_cnt(dp) > 3) {
1668 hres = to_number(ctx, get_arg(dp, 3), ei, &v);
1673 else ms = ms_from_time(t);
1675 t = make_date(day(t), make_time(hour, min, sec, ms));
1676 date->time = time_clip(utc(t, date));
1679 num_set_val(retv, date->time);
1684 /* ECMA-262 3rd Edition 15.9.5.36 */
1685 static HRESULT Date_setUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1686 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1691 DOUBLE t, hour, min, sec, ms;
1695 if(!(date = date_this(jsthis)))
1696 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1699 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1703 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1708 if(arg_cnt(dp) > 1) {
1709 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1714 else min = min_from_time(t);
1716 if(arg_cnt(dp) > 2) {
1717 hres = to_number(ctx, get_arg(dp, 2), ei, &v);
1722 else sec = sec_from_time(t);
1724 if(arg_cnt(dp) > 3) {
1725 hres = to_number(ctx, get_arg(dp, 3), ei, &v);
1730 else ms = ms_from_time(t);
1732 t = make_date(day(t), make_time(hour, min, sec, ms));
1733 date->time = time_clip(t);
1736 num_set_val(retv, date->time);
1741 /* ECMA-262 3rd Edition 15.9.5.36 */
1742 static HRESULT Date_setDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1743 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1752 if(!(date = date_this(jsthis)))
1753 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1756 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1758 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1762 t = local_time(date->time, date);
1763 t = make_date(make_day(year_from_time(t), month_from_time(t),
1764 num_val(&v)), time_within_day(t));
1765 date->time = time_clip(utc(t, date));
1768 num_set_val(retv, date->time);
1773 /* ECMA-262 3rd Edition 15.9.5.37 */
1774 static HRESULT Date_setUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1775 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1784 if(!(date = date_this(jsthis)))
1785 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1788 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1790 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1795 t = make_date(make_day(year_from_time(t), month_from_time(t),
1796 num_val(&v)), time_within_day(t));
1797 date->time = time_clip(t);
1800 num_set_val(retv, date->time);
1805 /* ECMA-262 3rd Edition 15.9.5.38 */
1806 static HRESULT Date_setMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1807 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1812 DOUBLE t, month, ddate;
1816 if(!(date = date_this(jsthis)))
1817 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1820 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1822 t = local_time(date->time, date);
1824 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1827 month = num_val(&v);
1829 if(arg_cnt(dp) > 1) {
1830 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1833 ddate = num_val(&v);
1835 else ddate = date_from_time(t);
1837 t = make_date(make_day(year_from_time(t), month, ddate),
1838 time_within_day(t));
1839 date->time = time_clip(utc(t, date));
1842 num_set_val(retv, date->time);
1847 /* ECMA-262 3rd Edition 15.9.5.39 */
1848 static HRESULT Date_setUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1849 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1854 DOUBLE t, month, ddate;
1858 if(!(date = date_this(jsthis)))
1859 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1862 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1866 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1869 month = num_val(&v);
1871 if(arg_cnt(dp) > 1) {
1872 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1875 ddate = num_val(&v);
1877 else ddate = date_from_time(t);
1879 t = make_date(make_day(year_from_time(t), month, ddate),
1880 time_within_day(t));
1881 date->time = time_clip(t);
1884 num_set_val(retv, date->time);
1889 /* ECMA-262 3rd Edition 15.9.5.40 */
1890 static HRESULT Date_setFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1891 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1896 DOUBLE t, year, month, ddate;
1900 if(!(date = date_this(jsthis)))
1901 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1904 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1906 t = local_time(date->time, date);
1908 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1913 if(arg_cnt(dp) > 1) {
1914 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1917 month = num_val(&v);
1919 else month = month_from_time(t);
1921 if(arg_cnt(dp) > 2) {
1922 hres = to_number(ctx, get_arg(dp, 2), ei, &v);
1925 ddate = num_val(&v);
1927 else ddate = date_from_time(t);
1929 t = make_date(make_day(year, month, ddate), time_within_day(t));
1930 date->time = time_clip(utc(t, date));
1933 num_set_val(retv, date->time);
1938 /* ECMA-262 3rd Edition 15.9.5.41 */
1939 static HRESULT Date_setUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1940 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1945 DOUBLE t, year, month, ddate;
1949 if(!(date = date_this(jsthis)))
1950 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1953 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
1957 hres = to_number(ctx, get_arg(dp, 0), ei, &v);
1962 if(arg_cnt(dp) > 1) {
1963 hres = to_number(ctx, get_arg(dp, 1), ei, &v);
1966 month = num_val(&v);
1968 else month = month_from_time(t);
1970 if(arg_cnt(dp) > 2) {
1971 hres = to_number(ctx, get_arg(dp, 2), ei, &v);
1974 ddate = num_val(&v);
1976 else ddate = date_from_time(t);
1978 t = make_date(make_day(year, month, ddate), time_within_day(t));
1979 date->time = time_clip(t);
1982 num_set_val(retv, date->time);
1987 /* ECMA-262 3rd Edition B2.4 */
1988 static HRESULT Date_getYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
1989 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
1996 if(!(date = date_this(jsthis)))
1997 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
1999 t = local_time(date->time, date);
2006 year = year_from_time(t);
2008 num_set_val(retv, (1900<=year && year<2000)?year-1900:year);
2013 static HRESULT Date_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
2014 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
2020 return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
2022 FIXME("unimplemented flags %x\n", flags);
2029 static const builtin_prop_t Date_props[] = {
2030 {getDateW, Date_getDate, PROPF_METHOD},
2031 {getDayW, Date_getDay, PROPF_METHOD},
2032 {getFullYearW, Date_getFullYear, PROPF_METHOD},
2033 {getHoursW, Date_getHours, PROPF_METHOD},
2034 {getMillisecondsW, Date_getMilliseconds, PROPF_METHOD},
2035 {getMinutesW, Date_getMinutes, PROPF_METHOD},
2036 {getMonthW, Date_getMonth, PROPF_METHOD},
2037 {getSecondsW, Date_getSeconds, PROPF_METHOD},
2038 {getTimeW, Date_getTime, PROPF_METHOD},
2039 {getTimezoneOffsetW, Date_getTimezoneOffset, PROPF_METHOD},
2040 {getUTCDateW, Date_getUTCDate, PROPF_METHOD},
2041 {getUTCDayW, Date_getUTCDay, PROPF_METHOD},
2042 {getUTCFullYearW, Date_getUTCFullYear, PROPF_METHOD},
2043 {getUTCHoursW, Date_getUTCHours, PROPF_METHOD},
2044 {getUTCMillisecondsW, Date_getUTCMilliseconds, PROPF_METHOD},
2045 {getUTCMinutesW, Date_getUTCMinutes, PROPF_METHOD},
2046 {getUTCMonthW, Date_getUTCMonth, PROPF_METHOD},
2047 {getUTCSecondsW, Date_getUTCSeconds, PROPF_METHOD},
2048 {getYearW, Date_getYear, PROPF_METHOD},
2049 {setDateW, Date_setDate, PROPF_METHOD|1},
2050 {setFullYearW, Date_setFullYear, PROPF_METHOD|3},
2051 {setHoursW, Date_setHours, PROPF_METHOD|4},
2052 {setMillisecondsW, Date_setMilliseconds, PROPF_METHOD|1},
2053 {setMinutesW, Date_setMinutes, PROPF_METHOD|3},
2054 {setMonthW, Date_setMonth, PROPF_METHOD|2},
2055 {setSecondsW, Date_setSeconds, PROPF_METHOD|2},
2056 {setTimeW, Date_setTime, PROPF_METHOD|1},
2057 {setUTCDateW, Date_setUTCDate, PROPF_METHOD|1},
2058 {setUTCFullYearW, Date_setUTCFullYear, PROPF_METHOD|3},
2059 {setUTCHoursW, Date_setUTCHours, PROPF_METHOD|4},
2060 {setUTCMillisecondsW, Date_setUTCMilliseconds, PROPF_METHOD|1},
2061 {setUTCMinutesW, Date_setUTCMinutes, PROPF_METHOD|3},
2062 {setUTCMonthW, Date_setUTCMonth, PROPF_METHOD|2},
2063 {setUTCSecondsW, Date_setUTCSeconds, PROPF_METHOD|2},
2064 {toDateStringW, Date_toDateString, PROPF_METHOD},
2065 {toLocaleDateStringW, Date_toLocaleDateString, PROPF_METHOD},
2066 {toLocaleStringW, Date_toLocaleString, PROPF_METHOD},
2067 {toLocaleTimeStringW, Date_toLocaleTimeString, PROPF_METHOD},
2068 {toStringW, Date_toString, PROPF_METHOD},
2069 {toTimeStringW, Date_toTimeString, PROPF_METHOD},
2070 {toUTCStringW, Date_toUTCString, PROPF_METHOD},
2071 {valueOfW, Date_valueOf, PROPF_METHOD},
2074 static const builtin_info_t Date_info = {
2076 {NULL, Date_value, 0},
2077 sizeof(Date_props)/sizeof(*Date_props),
2083 static HRESULT create_date(script_ctx_t *ctx, DispatchEx *object_prototype, DOUBLE time, DispatchEx **ret)
2087 TIME_ZONE_INFORMATION tzi;
2089 GetTimeZoneInformation(&tzi);
2091 date = heap_alloc_zero(sizeof(DateInstance));
2093 return E_OUTOFMEMORY;
2095 if(object_prototype)
2096 hres = init_dispex(&date->dispex, ctx, &Date_info, object_prototype);
2098 hres = init_dispex_from_constr(&date->dispex, ctx, &Date_info, ctx->date_constr);
2105 date->bias = tzi.Bias;
2106 date->standardDate = tzi.StandardDate;
2107 date->standardBias = tzi.StandardBias;
2108 date->daylightDate = tzi.DaylightDate;
2109 date->daylightBias = tzi.DaylightBias;
2111 *ret = &date->dispex;
2115 static inline HRESULT date_parse(BSTR input, VARIANT *retv) {
2116 static const DWORD string_ids[] = { LOCALE_SMONTHNAME12, LOCALE_SMONTHNAME11,
2117 LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME8,
2118 LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME5,
2119 LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME3, LOCALE_SMONTHNAME2,
2120 LOCALE_SMONTHNAME1, LOCALE_SDAYNAME7, LOCALE_SDAYNAME1,
2121 LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, LOCALE_SDAYNAME4,
2122 LOCALE_SDAYNAME5, LOCALE_SDAYNAME6 };
2123 BSTR strings[sizeof(string_ids)/sizeof(DWORD)];
2126 int input_len, parse_len = 0, nest_level = 0, i, size;
2127 int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0;
2128 int ms = 0, offset = 0, hour_adjust = 0;
2129 BOOL set_year = FALSE, set_month = FALSE, set_day = FALSE, set_hour = FALSE;
2130 BOOL set_offset = FALSE, set_era = FALSE, ad = TRUE, set_am = FALSE, am = TRUE;
2131 BOOL set_hour_adjust = TRUE;
2132 TIME_ZONE_INFORMATION tzi;
2136 if(retv) num_set_nan(retv);
2138 input_len = SysStringLen(input);
2139 for(i=0; i<input_len; i++) {
2140 if(input[i] == '(') nest_level++;
2141 else if(input[i] == ')') {
2146 else if(!nest_level) parse_len++;
2149 parse = SysAllocStringLen(NULL, parse_len);
2151 return E_OUTOFMEMORY;
2154 for(i=0; i<input_len; i++) {
2155 if(input[i] == '(') nest_level++;
2156 else if(input[i] == ')') nest_level--;
2157 else if(!nest_level) parse[parse_len++] = toupperW(input[i]);
2160 GetTimeZoneInformation(&tzi);
2162 di.standardDate = tzi.StandardDate;
2163 di.standardBias = tzi.StandardBias;
2164 di.daylightDate = tzi.DaylightDate;
2165 di.daylightBias = tzi.DaylightBias;
2167 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2168 for(i=0; i<sizeof(string_ids)/sizeof(DWORD); i++) {
2169 size = GetLocaleInfoW(lcid_en, string_ids[i], NULL, 0);
2170 strings[i] = SysAllocStringLen(NULL, size);
2174 SysFreeString(strings[i]);
2175 SysFreeString(parse);
2176 return E_OUTOFMEMORY;
2178 GetLocaleInfoW(lcid_en, string_ids[i], strings[i], size);
2181 for(i=0; i<parse_len;) {
2182 while(isspaceW(parse[i])) i++;
2183 if(parse[i] == ',') {
2184 while(parse[i] == ',') i++;
2188 if(parse[i]>='0' && parse[i]<='9') {
2189 int tmp = atoiW(&parse[i]);
2190 while(parse[i]>='0' && parse[i]<='9') i++;
2191 while(isspaceW(parse[i])) i++;
2193 if(parse[i] == ':') {
2200 while(parse[i] == ':') i++;
2201 while(isspaceW(parse[i])) i++;
2202 if(parse[i]>='0' && parse[i]<='9') {
2203 min = atoiW(&parse[i]);
2204 while(parse[i]>='0' && parse[i]<='9') i++;
2207 while(isspaceW(parse[i])) i++;
2208 while(parse[i] == ':') i++;
2209 while(isspaceW(parse[i])) i++;
2210 if(parse[i]>='0' && parse[i]<='9') {
2211 sec = atoiW(&parse[i]);
2212 while(parse[i]>='0' && parse[i]<='9') i++;
2215 else if(parse[i]=='-' || parse[i]=='/') {
2217 if(set_day || set_month || set_year) break;
2224 while(isspaceW(parse[i])) i++;
2225 while(parse[i]=='-' || parse[i]=='/') i++;
2226 while(isspaceW(parse[i])) i++;
2227 if(parse[i]<'0' || parse[i]>'9') break;
2228 day = atoiW(&parse[i]);
2229 while(parse[i]>='0' && parse[i]<='9') i++;
2231 while(parse[i]=='-' || parse[i]=='/') i++;
2232 while(isspaceW(parse[i])) i++;
2233 if(parse[i]<'0' || parse[i]>'9') break;
2234 year = atoiW(&parse[i]);
2235 while(parse[i]>='0' && parse[i]<='9') i++;
2237 else if(tmp<0) break;
2252 if(parse[i]<'A' || parse[i]>'Z') break;
2253 else if(parse[i]=='B' && (parse[i+1]=='C' ||
2254 (parse[i+1]=='.' && parse[i+2]=='C'))) {
2261 if(parse[i] == '.') i++;
2263 if(parse[i] == '.') i++;
2265 else if(parse[i]=='A' && (parse[i+1]=='D' ||
2266 (parse[i+1]=='.' && parse[i+2]=='D'))) {
2272 if(parse[i] == '.') i++;
2274 if(parse[i] == '.') i++;
2276 else if(parse[i+1]<'A' || parse[i+1]>'Z') {
2278 if(set_offset) break;
2281 if(parse[i] <= 'I') hour_adjust = parse[i]-'A'+2;
2282 else if(parse[i] == 'J') break;
2283 else if(parse[i] <= 'M') hour_adjust = parse[i]-'K'+11;
2284 else if(parse[i] <= 'Y') hour_adjust = parse[i]-'N';
2285 else hour_adjust = 1;
2288 if(parse[i] == '.') i++;
2290 else if(parse[i]=='A' && parse[i+1]=='M') {
2297 else if(parse[i]=='P' && parse[i+1]=='M') {
2304 else if((parse[i]=='U' && parse[i+1]=='T' && parse[i+2]=='C')
2305 || (parse[i]=='G' && parse[i+1]=='M' && parse[i+2]=='T')) {
2307 BOOL positive = TRUE;
2309 if(set_offset) break;
2311 set_hour_adjust = FALSE;
2314 while(isspaceW(parse[i])) i++;
2315 if(parse[i] == '-') positive = FALSE;
2316 else if(parse[i] != '+') continue;
2319 while(isspaceW(parse[i])) i++;
2320 if(parse[i]<'0' || parse[i]>'9') break;
2321 offset = atoiW(&parse[i]);
2322 while(parse[i]>='0' && parse[i]<='9') i++;
2324 if(offset<24) offset *= 60;
2325 else offset = (offset/100)*60 + offset%100;
2327 if(positive) offset = -offset;
2330 /* Month or garbage */
2333 for(size=i; parse[size]>='A' && parse[size]<='Z'; size++);
2336 for(j=0; j<sizeof(string_ids)/sizeof(DWORD); j++)
2337 if(!memicmpW(&parse[i], strings[j], size)) break;
2340 if(set_month) break;
2344 else if(j == sizeof(string_ids)/sizeof(DWORD)) break;
2351 if(retv && i==parse_len && set_year && set_month
2352 && set_day && (!set_am || hour<13)) {
2354 if(hour == 12) hour = 0;
2358 if(!ad) year = -year+1;
2359 else if(year<100) year += 1900;
2362 V_R8(retv) = time_clip(make_date(make_day(year, month, day),
2363 make_time(hour+hour_adjust, min, sec, ms)) + offset*MS_PER_MINUTE);
2365 if(set_hour_adjust) V_R8(retv) = utc(V_R8(retv), &di);
2368 for(i=0; i<sizeof(string_ids)/sizeof(DWORD); i++)
2369 SysFreeString(strings[i]);
2370 SysFreeString(parse);
2375 static HRESULT DateConstr_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
2376 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
2389 hres = to_string(ctx, get_arg(dp,0), ei, &parse_str);
2393 hres = date_parse(parse_str, retv);
2395 SysFreeString(parse_str);
2399 static HRESULT date_utc(script_ctx_t *ctx, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei)
2401 VARIANT year, month, vdate, hours, minutes, seconds, ms;
2403 int arg_no = arg_cnt(dp);
2409 hres = to_number(ctx, get_arg(dp, 0), ei, &year);
2419 hres = to_number(ctx, get_arg(dp, 1), ei, &month);
2424 V_VT(&month) = VT_R8;
2429 hres = to_number(ctx, get_arg(dp, 2), ei, &vdate);
2434 V_VT(&vdate) = VT_R8;
2439 hres = to_number(ctx, get_arg(dp, 3), ei, &hours);
2444 V_VT(&hours) = VT_R8;
2449 hres = to_number(ctx, get_arg(dp, 4), ei, &minutes);
2454 V_VT(&minutes) = VT_R8;
2459 hres = to_number(ctx, get_arg(dp, 5), ei, &seconds);
2464 V_VT(&seconds) = VT_R8;
2469 hres = to_number(ctx, get_arg(dp, 6), ei, &ms);
2480 V_R8(retv) = time_clip(make_date(
2481 make_day(y, num_val(&month), num_val(&vdate)),
2482 make_time(num_val(&hours), num_val(&minutes),
2483 num_val(&seconds), num_val(&ms))));
2489 static HRESULT DateConstr_UTC(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
2490 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
2494 return date_utc(ctx, dp, retv, ei);
2497 static HRESULT DateConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
2498 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
2506 case DISPATCH_CONSTRUCT:
2507 switch(arg_cnt(dp)) {
2508 /* ECMA-262 3rd Edition 15.9.3.3 */
2513 GetSystemTimeAsFileTime(&time);
2514 lltime = ((LONGLONG)time.dwHighDateTime<<32)
2515 + time.dwLowDateTime;
2517 hres = create_date(ctx, NULL, lltime/10000-TIME_EPOCH, &date);
2523 /* ECMA-262 3rd Edition 15.9.3.2 */
2527 hres = to_primitive(ctx, get_arg(dp,0), ei, &prim, NO_HINT);
2531 if(V_VT(&prim) == VT_BSTR)
2532 hres = date_parse(V_BSTR(&prim), &num);
2534 hres = to_number(ctx, &prim, ei, &num);
2536 VariantClear(&prim);
2540 hres = create_date(ctx, NULL, time_clip(num_val(&num)), &date);
2546 /* ECMA-262 3rd Edition 15.9.3.1 */
2551 hres = date_utc(ctx, dp, &ret_date, ei);
2555 hres = create_date(ctx, NULL, num_val(&ret_date), &date);
2559 di = (DateInstance*)date;
2560 di->time = utc(di->time, di);
2564 V_VT(retv) = VT_DISPATCH;
2565 V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(date);
2569 FILETIME system_time, local_time;
2572 GetSystemTimeAsFileTime(&system_time);
2573 FileTimeToLocalFileTime(&system_time, &local_time);
2574 lltime = ((LONGLONG)local_time.dwHighDateTime<<32)
2575 + local_time.dwLowDateTime;
2577 return date_to_string(lltime/10000-TIME_EPOCH, FALSE, 0, retv);
2581 FIXME("unimplemented flags %x\n", flags);
2588 static const builtin_prop_t DateConstr_props[] = {
2589 {UTCW, DateConstr_UTC, PROPF_METHOD},
2590 {parseW, DateConstr_parse, PROPF_METHOD}
2593 static const builtin_info_t DateConstr_info = {
2595 {NULL, Function_value, 0},
2596 sizeof(DateConstr_props)/sizeof(*DateConstr_props),
2602 HRESULT create_date_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret)
2607 static const WCHAR DateW[] = {'D','a','t','e',0};
2609 hres = create_date(ctx, object_prototype, 0.0, &date);
2613 hres = create_builtin_function(ctx, DateConstr_value, DateW, &DateConstr_info, PROPF_CONSTR, date, ret);
2615 jsdisp_release(date);