Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendate.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Jacek Caban for CodeWeavers 00003 * Copyright 2009 Piotr Caban 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 #include "config.h" 00021 #include "wine/port.h" 00022 00023 #include <limits.h> 00024 #include <math.h> 00025 00026 #include "jscript.h" 00027 00028 #include "wine/debug.h" 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(jscript); 00031 00032 /* 1601 to 1970 is 369 years plus 89 leap days */ 00033 #define TIME_EPOCH ((ULONGLONG)(369 * 365 + 89) * 86400 * 1000) 00034 00035 typedef struct { 00036 DispatchEx dispex; 00037 00038 /* ECMA-262 3rd Edition 15.9.1.1 */ 00039 DOUBLE time; 00040 00041 LONG bias; 00042 SYSTEMTIME standardDate; 00043 LONG standardBias; 00044 SYSTEMTIME daylightDate; 00045 LONG daylightBias; 00046 } DateInstance; 00047 00048 static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; 00049 static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; 00050 static const WCHAR propertyIsEnumerableW[] = 00051 {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; 00052 static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; 00053 static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; 00054 static const WCHAR toUTCStringW[] = {'t','o','U','T','C','S','t','r','i','n','g',0}; 00055 static const WCHAR toGMTStringW[] = {'t','o','G','M','T','S','t','r','i','n','g',0}; 00056 static const WCHAR toDateStringW[] = {'t','o','D','a','t','e','S','t','r','i','n','g',0}; 00057 static const WCHAR toTimeStringW[] = {'t','o','T','i','m','e','S','t','r','i','n','g',0}; 00058 static const WCHAR toLocaleDateStringW[] = {'t','o','L','o','c','a','l','e','D','a','t','e','S','t','r','i','n','g',0}; 00059 static const WCHAR toLocaleTimeStringW[] = {'t','o','L','o','c','a','l','e','T','i','m','e','S','t','r','i','n','g',0}; 00060 static const WCHAR getTimeW[] = {'g','e','t','T','i','m','e',0}; 00061 static const WCHAR getFullYearW[] = {'g','e','t','F','u','l','l','Y','e','a','r',0}; 00062 static const WCHAR getUTCFullYearW[] = {'g','e','t','U','T','C','F','u','l','l','Y','e','a','r',0}; 00063 static const WCHAR getMonthW[] = {'g','e','t','M','o','n','t','h',0}; 00064 static const WCHAR getUTCMonthW[] = {'g','e','t','U','T','C','M','o','n','t','h',0}; 00065 static const WCHAR getDateW[] = {'g','e','t','D','a','t','e',0}; 00066 static const WCHAR getUTCDateW[] = {'g','e','t','U','T','C','D','a','t','e',0}; 00067 static const WCHAR getDayW[] = {'g','e','t','D','a','y',0}; 00068 static const WCHAR getUTCDayW[] = {'g','e','t','U','T','C','D','a','y',0}; 00069 static const WCHAR getHoursW[] = {'g','e','t','H','o','u','r','s',0}; 00070 static const WCHAR getUTCHoursW[] = {'g','e','t','U','T','C','H','o','u','r','s',0}; 00071 static const WCHAR getMinutesW[] = {'g','e','t','M','i','n','u','t','e','s',0}; 00072 static const WCHAR getUTCMinutesW[] = {'g','e','t','U','T','C','M','i','n','u','t','e','s',0}; 00073 static const WCHAR getSecondsW[] = {'g','e','t','S','e','c','o','n','d','s',0}; 00074 static const WCHAR getUTCSecondsW[] = {'g','e','t','U','T','C','S','e','c','o','n','d','s',0}; 00075 static const WCHAR getMillisecondsW[] = {'g','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0}; 00076 static const WCHAR getUTCMillisecondsW[] = {'g','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0}; 00077 static const WCHAR getTimezoneOffsetW[] = {'g','e','t','T','i','m','e','z','o','n','e','O','f','f','s','e','t',0}; 00078 static const WCHAR setTimeW[] = {'s','e','t','T','i','m','e',0}; 00079 static const WCHAR setMillisecondsW[] = {'s','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0}; 00080 static const WCHAR setUTCMillisecondsW[] = {'s','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0}; 00081 static const WCHAR setSecondsW[] = {'s','e','t','S','e','c','o','n','d','s',0}; 00082 static const WCHAR setUTCSecondsW[] = {'s','e','t','U','T','C','S','e','c','o','n','d','s',0}; 00083 static const WCHAR setMinutesW[] = {'s','e','t','M','i','n','u','t','e','s',0}; 00084 static const WCHAR setUTCMinutesW[] = {'s','e','t','U','T','C','M','i','n','u','t','e','s',0}; 00085 static const WCHAR setHoursW[] = {'s','e','t','H','o','u','r','s',0}; 00086 static const WCHAR setUTCHoursW[] = {'s','e','t','U','T','C','H','o','u','r','s',0}; 00087 static const WCHAR setDateW[] = {'s','e','t','D','a','t','e',0}; 00088 static const WCHAR setUTCDateW[] = {'s','e','t','U','T','C','D','a','t','e',0}; 00089 static const WCHAR setMonthW[] = {'s','e','t','M','o','n','t','h',0}; 00090 static const WCHAR setUTCMonthW[] = {'s','e','t','U','T','C','M','o','n','t','h',0}; 00091 static const WCHAR setFullYearW[] = {'s','e','t','F','u','l','l','Y','e','a','r',0}; 00092 static const WCHAR setUTCFullYearW[] = {'s','e','t','U','T','C','F','u','l','l','Y','e','a','r',0}; 00093 static const WCHAR getYearW[] = {'g','e','t','Y','e','a','r',0}; 00094 00095 static const WCHAR UTCW[] = {'U','T','C',0}; 00096 static const WCHAR parseW[] = {'p','a','r','s','e',0}; 00097 00098 static inline DateInstance *date_this(vdisp_t *jsthis) 00099 { 00100 return is_vclass(jsthis, JSCLASS_DATE) ? (DateInstance*)jsthis->u.jsdisp : NULL; 00101 } 00102 00103 /*ECMA-262 3rd Edition 15.9.1.2 */ 00104 #define MS_PER_DAY 86400000 00105 #define MS_PER_HOUR 3600000 00106 #define MS_PER_MINUTE 60000 00107 00108 /* ECMA-262 3rd Edition 15.9.1.2 */ 00109 static inline DOUBLE day(DOUBLE time) 00110 { 00111 return floor(time / MS_PER_DAY); 00112 } 00113 00114 /* ECMA-262 3rd Edition 15.9.1.2 */ 00115 static inline DOUBLE time_within_day(DOUBLE time) 00116 { 00117 DOUBLE ret; 00118 00119 ret = fmod(time, MS_PER_DAY); 00120 if(ret < 0) 00121 ret += MS_PER_DAY; 00122 00123 return ret; 00124 } 00125 00126 /* ECMA-262 3rd Edition 15.9.1.3 */ 00127 static inline DOUBLE days_in_year(DOUBLE year) 00128 { 00129 int y; 00130 00131 if(year != (int)year) 00132 return ret_nan(); 00133 00134 y = year; 00135 if(y%4 != 0) return 365; 00136 if(y%100 != 0) return 366; 00137 if(y%400 != 0) return 365; 00138 return 366; 00139 } 00140 00141 /* ECMA-262 3rd Edition 15.9.1.3 */ 00142 static inline DOUBLE day_from_year(DOUBLE year) 00143 { 00144 if(year != (int)year) 00145 return ret_nan(); 00146 00147 return floor(365.0*(year-1970) + floor((year-1969)/4) 00148 - floor((year-1901)/100) + floor((year-1601)/400)); 00149 } 00150 00151 static inline int day_from_month(int month, int in_leap_year) 00152 { 00153 switch(month) 00154 { 00155 case 0: 00156 return 0; 00157 case 1: 00158 return 31; 00159 case 2: 00160 return 59+in_leap_year; 00161 case 3: 00162 return 90+in_leap_year; 00163 case 4: 00164 return 120+in_leap_year; 00165 case 5: 00166 return 151+in_leap_year; 00167 case 6: 00168 return 181+in_leap_year; 00169 case 7: 00170 return 212+in_leap_year; 00171 case 8: 00172 return 243+in_leap_year; 00173 case 9: 00174 return 273+in_leap_year; 00175 case 10: 00176 return 304+in_leap_year; 00177 default: 00178 return 334+in_leap_year; 00179 } 00180 } 00181 00182 /* ECMA-262 3rd Edition 15.9.1.3 */ 00183 static inline DOUBLE time_from_year(DOUBLE year) 00184 { 00185 return MS_PER_DAY*day_from_year(year); 00186 } 00187 00188 /* ECMA-262 3rd Edition 15.9.1.3 */ 00189 static inline DOUBLE year_from_time(DOUBLE time) 00190 { 00191 int y; 00192 00193 if(isnan(time)) 00194 return ret_nan(); 00195 00196 y = 1970 + time/365.25/MS_PER_DAY; 00197 00198 if(time_from_year(y) > time) 00199 while(time_from_year(y) > time) y--; 00200 else 00201 while(time_from_year(y+1)<=time) y++; 00202 00203 return y; 00204 } 00205 00206 /* ECMA-262 3rd Edition 15.9.1.3 */ 00207 static inline int in_leap_year(DOUBLE time) 00208 { 00209 if(days_in_year(year_from_time(time))==366) 00210 return 1; 00211 return 0; 00212 } 00213 00214 /* ECMA-262 3rd Edition 15.9.1.4 */ 00215 static inline int day_within_year(DOUBLE time) 00216 { 00217 return day(time) - day_from_year(year_from_time(time)); 00218 } 00219 00220 /* ECMA-262 3rd Edition 15.9.1.4 */ 00221 static inline DOUBLE month_from_time(DOUBLE time) 00222 { 00223 int ily = in_leap_year(time); 00224 int dwy = day_within_year(time); 00225 00226 if(isnan(time)) 00227 return ret_nan(); 00228 00229 if(0<=dwy && dwy<31) return 0; 00230 if(dwy < 59+ily) return 1; 00231 if(dwy < 90+ily) return 2; 00232 if(dwy < 120+ily) return 3; 00233 if(dwy < 151+ily) return 4; 00234 if(dwy < 181+ily) return 5; 00235 if(dwy < 212+ily) return 6; 00236 if(dwy < 243+ily) return 7; 00237 if(dwy < 273+ily) return 8; 00238 if(dwy < 304+ily) return 9; 00239 if(dwy < 334+ily) return 10; 00240 return 11; 00241 } 00242 00243 /* ECMA-262 3rd Edition 15.9.1.5 */ 00244 static inline DOUBLE date_from_time(DOUBLE time) 00245 { 00246 int dwy = day_within_year(time); 00247 int ily = in_leap_year(time); 00248 int mft = month_from_time(time); 00249 00250 if(isnan(time)) 00251 return ret_nan(); 00252 00253 if(mft==0) return dwy+1; 00254 if(mft==1) return dwy-30; 00255 if(mft==2) return dwy-58-ily; 00256 if(mft==3) return dwy-89-ily; 00257 if(mft==4) return dwy-119-ily; 00258 if(mft==5) return dwy-150-ily; 00259 if(mft==6) return dwy-180-ily; 00260 if(mft==7) return dwy-211-ily; 00261 if(mft==8) return dwy-242-ily; 00262 if(mft==9) return dwy-272-ily; 00263 if(mft==10) return dwy-303-ily; 00264 return dwy-333-ily; 00265 } 00266 00267 /* ECMA-262 3rd Edition 15.9.1.6 */ 00268 static inline DOUBLE week_day(DOUBLE time) 00269 { 00270 DOUBLE ret; 00271 00272 if(isnan(time)) 00273 return ret_nan(); 00274 00275 ret = fmod(day(time)+4, 7); 00276 if(ret<0) ret += 7; 00277 00278 return ret; 00279 } 00280 00281 static inline DOUBLE convert_time(int year, SYSTEMTIME st) 00282 { 00283 DOUBLE time; 00284 int set_week_day; 00285 00286 if(st.wMonth == 0) 00287 return ret_nan(); 00288 00289 if(st.wYear != 0) 00290 year = st.wYear; 00291 00292 time = time_from_year(year); 00293 time += (DOUBLE)day_from_month(st.wMonth-1, in_leap_year(time)) * MS_PER_DAY; 00294 00295 if(st.wYear == 0) { 00296 set_week_day = st.wDayOfWeek-week_day(time); 00297 if(set_week_day < 0) 00298 set_week_day += 7; 00299 time += set_week_day * MS_PER_DAY; 00300 00301 time += (DOUBLE)(st.wDay-1) * 7 * MS_PER_DAY; 00302 if(month_from_time(time) != st.wMonth-1) 00303 time -= 7 * MS_PER_DAY; 00304 } 00305 else 00306 time += st.wDay * MS_PER_DAY; 00307 00308 time += st.wHour * MS_PER_HOUR; 00309 time += st.wMinute * MS_PER_MINUTE; 00310 00311 return time; 00312 } 00313 00314 /* ECMA-262 3rd Edition 15.9.1.9 */ 00315 static inline DOUBLE daylight_saving_ta(DOUBLE time, DateInstance *date) 00316 { 00317 int year = year_from_time(time); 00318 DOUBLE standardTime, daylightTime; 00319 00320 if(isnan(time)) 00321 return 0; 00322 00323 standardTime = convert_time(year, date->standardDate); 00324 daylightTime = convert_time(year, date->daylightDate); 00325 00326 if(isnan(standardTime) || isnan(daylightTime)) 00327 return 0; 00328 else if(standardTime > daylightTime) { 00329 if(daylightTime <= time && time < standardTime) 00330 return date->daylightBias; 00331 00332 return date->standardBias; 00333 } 00334 else { 00335 if(standardTime <= time && time < daylightTime) 00336 return date->standardBias; 00337 00338 return date->daylightBias; 00339 } 00340 } 00341 00342 /* ECMA-262 3rd Edition 15.9.1.9 */ 00343 static inline DOUBLE local_time(DOUBLE time, DateInstance *date) 00344 { 00345 return time - (daylight_saving_ta(time, date)+date->bias)*MS_PER_MINUTE; 00346 } 00347 00348 /* ECMA-262 3rd Edition 15.9.1.9 */ 00349 static inline DOUBLE utc(DOUBLE time, DateInstance *date) 00350 { 00351 time += date->bias * MS_PER_MINUTE; 00352 return time + daylight_saving_ta(time, date)*MS_PER_MINUTE; 00353 } 00354 00355 /* ECMA-262 3rd Edition 15.9.1.10 */ 00356 static inline DOUBLE hour_from_time(DOUBLE time) 00357 { 00358 DOUBLE ret; 00359 00360 if(isnan(time)) 00361 return ret_nan(); 00362 00363 ret = fmod(floor(time/MS_PER_HOUR), 24); 00364 if(ret<0) ret += 24; 00365 00366 return ret; 00367 } 00368 00369 /* ECMA-262 3rd Edition 15.9.1.10 */ 00370 static inline DOUBLE min_from_time(DOUBLE time) 00371 { 00372 DOUBLE ret; 00373 00374 if(isnan(time)) 00375 return ret_nan(); 00376 00377 ret = fmod(floor(time/MS_PER_MINUTE), 60); 00378 if(ret<0) ret += 60; 00379 00380 return ret; 00381 } 00382 00383 /* ECMA-262 3rd Edition 15.9.1.10 */ 00384 static inline DOUBLE sec_from_time(DOUBLE time) 00385 { 00386 DOUBLE ret; 00387 00388 if(isnan(time)) 00389 return ret_nan(); 00390 00391 ret = fmod(floor(time/1000), 60); 00392 if(ret<0) ret += 60; 00393 00394 return ret; 00395 } 00396 00397 /* ECMA-262 3rd Edition 15.9.1.10 */ 00398 static inline DOUBLE ms_from_time(DOUBLE time) 00399 { 00400 DOUBLE ret; 00401 00402 if(isnan(time)) 00403 return ret_nan(); 00404 00405 ret = fmod(time, 1000); 00406 if(ret<0) ret += 1000; 00407 00408 return ret; 00409 } 00410 00411 /* ECMA-262 3rd Edition 15.9.1.11 */ 00412 static inline DOUBLE make_time(DOUBLE hour, DOUBLE min, DOUBLE sec, DOUBLE ms) 00413 { 00414 return hour*MS_PER_HOUR + min*MS_PER_MINUTE + sec*1000 + ms; 00415 } 00416 00417 /* ECMA-262 3rd Edition 15.9.1.12 */ 00418 static inline DOUBLE make_day(DOUBLE year, DOUBLE month, DOUBLE day) 00419 { 00420 DOUBLE time; 00421 00422 year += floor(month/12); 00423 00424 month = fmod(month, 12); 00425 if(month<0) month += 12; 00426 00427 time = time_from_year(year); 00428 00429 day += floor(time / MS_PER_DAY); 00430 day += day_from_month(month, in_leap_year(time)); 00431 00432 return day-1; 00433 } 00434 00435 /* ECMA-262 3rd Edition 15.9.1.13 */ 00436 static inline DOUBLE make_date(DOUBLE day, DOUBLE time) 00437 { 00438 return day*MS_PER_DAY + time; 00439 } 00440 00441 /* ECMA-262 3rd Edition 15.9.1.14 */ 00442 static inline DOUBLE time_clip(DOUBLE time) 00443 { 00444 if(8.64e15 < time || time < -8.64e15) { 00445 return ret_nan(); 00446 } 00447 00448 return floor(time); 00449 } 00450 00451 static SYSTEMTIME create_systemtime(DOUBLE time) 00452 { 00453 SYSTEMTIME st; 00454 00455 st.wYear = year_from_time(time); 00456 st.wMonth = month_from_time(time) + 1; 00457 st.wDayOfWeek = week_day(time); 00458 st.wDay = date_from_time(time); 00459 st.wHour = hour_from_time(time); 00460 st.wMinute = min_from_time(time); 00461 st.wSecond = sec_from_time(time); 00462 st.wMilliseconds = ms_from_time(time); 00463 00464 return st; 00465 } 00466 00467 static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset, VARIANT *retv) 00468 { 00469 static const WCHAR NaNW[] = { 'N','a','N',0 }; 00470 static const WCHAR formatW[] = { '%','s',' ','%','s',' ','%','d',' ', 00471 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ', 00472 'U','T','C','%','c','%','0','2','d','%','0','2','d',' ','%','d','%','s',0 }; 00473 static const WCHAR formatUTCW[] = { '%','s',' ','%','s',' ','%','d',' ', 00474 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ', 00475 'U','T','C',' ','%','d','%','s',0 }; 00476 static const WCHAR formatNoOffsetW[] = { '%','s',' ','%','s',' ', 00477 '%','d',' ','%','0','2','d',':','%','0','2','d',':', 00478 '%','0','2','d',' ','%','d','%','s',0 }; 00479 static const WCHAR ADW[] = { 0 }; 00480 static const WCHAR BCW[] = { ' ','B','.','C','.',0 }; 00481 00482 static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, 00483 LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, 00484 LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 }; 00485 static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, 00486 LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4, 00487 LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, 00488 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, 00489 LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10, 00490 LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 }; 00491 00492 BOOL formatAD = TRUE; 00493 BSTR week, month; 00494 BSTR date_str; 00495 int len, size, year, day; 00496 DWORD lcid_en, week_id, month_id; 00497 WCHAR sign = '-'; 00498 00499 if(isnan(time)) { 00500 if(retv) { 00501 V_VT(retv) = VT_BSTR; 00502 V_BSTR(retv) = SysAllocString(NaNW); 00503 if(!V_BSTR(retv)) 00504 return E_OUTOFMEMORY; 00505 } 00506 return S_OK; 00507 } 00508 00509 if(retv) { 00510 len = 21; 00511 00512 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT); 00513 00514 week_id = week_ids[(int)week_day(time)]; 00515 size = GetLocaleInfoW(lcid_en, week_id, NULL, 0); 00516 week = SysAllocStringLen(NULL, size); 00517 if(!week) 00518 return E_OUTOFMEMORY; 00519 GetLocaleInfoW(lcid_en, week_id, week, size); 00520 len += size-1; 00521 00522 month_id = month_ids[(int)month_from_time(time)]; 00523 size = GetLocaleInfoW(lcid_en, month_id, NULL, 0); 00524 month = SysAllocStringLen(NULL, size); 00525 if(!month) { 00526 SysFreeString(week); 00527 return E_OUTOFMEMORY; 00528 } 00529 GetLocaleInfoW(lcid_en, month_id, month, size); 00530 len += size-1; 00531 00532 year = year_from_time(time); 00533 if(year<0) 00534 year = -year+1; 00535 do { 00536 year /= 10; 00537 len++; 00538 } while(year); 00539 00540 year = year_from_time(time); 00541 if(year<0) { 00542 formatAD = FALSE; 00543 year = -year+1; 00544 len += 5; 00545 } 00546 00547 day = date_from_time(time); 00548 do { 00549 day /= 10; 00550 len++; 00551 } while(day); 00552 day = date_from_time(time); 00553 00554 if(!show_offset) len -= 9; 00555 else if(offset == 0) len -= 5; 00556 else if(offset < 0) { 00557 sign = '+'; 00558 offset = -offset; 00559 } 00560 00561 date_str = SysAllocStringLen(NULL, len); 00562 if(!date_str) { 00563 SysFreeString(week); 00564 SysFreeString(month); 00565 return E_OUTOFMEMORY; 00566 } 00567 00568 if(!show_offset) 00569 sprintfW(date_str, formatNoOffsetW, week, month, day, 00570 (int)hour_from_time(time), (int)min_from_time(time), 00571 (int)sec_from_time(time), year, formatAD?ADW:BCW); 00572 else if(offset) 00573 sprintfW(date_str, formatW, week, month, day, 00574 (int)hour_from_time(time), (int)min_from_time(time), 00575 (int)sec_from_time(time), sign, offset/60, offset%60, 00576 year, formatAD?ADW:BCW); 00577 else 00578 sprintfW(date_str, formatUTCW, week, month, day, 00579 (int)hour_from_time(time), (int)min_from_time(time), 00580 (int)sec_from_time(time), year, formatAD?ADW:BCW); 00581 00582 SysFreeString(week); 00583 SysFreeString(month); 00584 00585 V_VT(retv) = VT_BSTR; 00586 V_BSTR(retv) = date_str; 00587 } 00588 return S_OK; 00589 } 00590 00591 /* ECMA-262 3rd Edition 15.9.1.2 */ 00592 static HRESULT dateobj_to_string(DateInstance *date, VARIANT *retv) 00593 { 00594 DOUBLE time; 00595 int offset; 00596 00597 time = local_time(date->time, date); 00598 offset = date->bias + 00599 daylight_saving_ta(time, date); 00600 00601 return date_to_string(time, TRUE, offset, retv); 00602 } 00603 00604 static HRESULT Date_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00605 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00606 { 00607 DateInstance *date; 00608 00609 TRACE("\n"); 00610 00611 if(!(date = date_this(jsthis))) 00612 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 00613 00614 return dateobj_to_string(date, retv); 00615 } 00616 00617 /* ECMA-262 3rd Edition 15.9.1.5 */ 00618 static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00619 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00620 { 00621 static const WCHAR NaNW[] = { 'N','a','N',0 }; 00622 SYSTEMTIME st; 00623 DateInstance *date; 00624 BSTR date_str; 00625 int date_len, time_len; 00626 00627 TRACE("\n"); 00628 00629 if(!(date = date_this(jsthis))) 00630 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 00631 00632 if(isnan(date->time)) { 00633 if(retv) { 00634 V_VT(retv) = VT_BSTR; 00635 V_BSTR(retv) = SysAllocString(NaNW); 00636 if(!V_BSTR(retv)) 00637 return E_OUTOFMEMORY; 00638 } 00639 return S_OK; 00640 } 00641 00642 st = create_systemtime(local_time(date->time, date)); 00643 00644 if(st.wYear<1601 || st.wYear>9999) 00645 return dateobj_to_string(date, retv); 00646 00647 if(retv) { 00648 date_len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0); 00649 time_len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0); 00650 date_str = SysAllocStringLen(NULL, date_len+time_len-1); 00651 if(!date_str) 00652 return E_OUTOFMEMORY; 00653 GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, date_len); 00654 GetTimeFormatW(ctx->lcid, 0, &st, NULL, &date_str[date_len], time_len); 00655 date_str[date_len-1] = ' '; 00656 00657 V_VT(retv) = VT_BSTR; 00658 V_BSTR(retv) = date_str; 00659 } 00660 return S_OK; 00661 } 00662 00663 static HRESULT Date_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00664 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00665 { 00666 DateInstance *date; 00667 00668 TRACE("\n"); 00669 00670 if(!(date = date_this(jsthis))) 00671 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 00672 00673 if(retv) 00674 num_set_val(retv, date->time); 00675 return S_OK; 00676 } 00677 00678 static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, 00679 VARIANT *retv, jsexcept_t *ei) 00680 { 00681 static const WCHAR NaNW[] = { 'N','a','N',0 }; 00682 static const WCHAR formatADW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ', 00683 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 }; 00684 static const WCHAR formatBCW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ','B','.','C','.',' ', 00685 '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 }; 00686 00687 static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, 00688 LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, 00689 LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 }; 00690 static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, 00691 LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4, 00692 LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, 00693 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, 00694 LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10, 00695 LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 }; 00696 00697 BOOL formatAD = TRUE; 00698 BSTR week, month; 00699 DateInstance *date; 00700 BSTR date_str; 00701 int len, size, year, day; 00702 DWORD lcid_en, week_id, month_id; 00703 00704 if(!(date = date_this(jsthis))) 00705 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 00706 00707 if(isnan(date->time)) { 00708 if(retv) { 00709 V_VT(retv) = VT_BSTR; 00710 V_BSTR(retv) = SysAllocString(NaNW); 00711 if(!V_BSTR(retv)) 00712 return E_OUTOFMEMORY; 00713 } 00714 return S_OK; 00715 } 00716 00717 if(retv) { 00718 len = 17; 00719 00720 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT); 00721 00722 week_id = week_ids[(int)week_day(date->time)]; 00723 size = GetLocaleInfoW(lcid_en, week_id, NULL, 0); 00724 week = SysAllocStringLen(NULL, size); 00725 if(!week) 00726 return E_OUTOFMEMORY; 00727 GetLocaleInfoW(lcid_en, week_id, week, size); 00728 len += size-1; 00729 00730 month_id = month_ids[(int)month_from_time(date->time)]; 00731 size = GetLocaleInfoW(lcid_en, month_id, NULL, 0); 00732 month = SysAllocStringLen(NULL, size); 00733 if(!month) { 00734 SysFreeString(week); 00735 return E_OUTOFMEMORY; 00736 } 00737 GetLocaleInfoW(lcid_en, month_id, month, size); 00738 len += size-1; 00739 00740 year = year_from_time(date->time); 00741 if(year<0) 00742 year = -year+1; 00743 do { 00744 year /= 10; 00745 len++; 00746 } while(year); 00747 00748 year = year_from_time(date->time); 00749 if(year<0) { 00750 formatAD = FALSE; 00751 year = -year+1; 00752 len += 5; 00753 } 00754 00755 day = date_from_time(date->time); 00756 do { 00757 day /= 10; 00758 len++; 00759 } while(day); 00760 day = date_from_time(date->time); 00761 00762 date_str = SysAllocStringLen(NULL, len); 00763 if(!date_str) { 00764 SysFreeString(week); 00765 SysFreeString(month); 00766 return E_OUTOFMEMORY; 00767 } 00768 sprintfW(date_str, formatAD?formatADW:formatBCW, week, day, month, year, 00769 (int)hour_from_time(date->time), (int)min_from_time(date->time), 00770 (int)sec_from_time(date->time)); 00771 00772 SysFreeString(week); 00773 SysFreeString(month); 00774 00775 V_VT(retv) = VT_BSTR; 00776 V_BSTR(retv) = date_str; 00777 } 00778 return S_OK; 00779 } 00780 00781 /* ECMA-262 3rd Edition 15.9.5.42 */ 00782 static HRESULT Date_toUTCString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00783 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00784 { 00785 TRACE("\n"); 00786 return create_utc_string(ctx, jsthis, retv, ei); 00787 } 00788 00789 static HRESULT Date_toGMTString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00790 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00791 { 00792 TRACE("\n"); 00793 return create_utc_string(ctx, jsthis, retv, ei); 00794 } 00795 00796 /* ECMA-262 3rd Edition 15.9.5.3 */ 00797 static HRESULT dateobj_to_date_string(DateInstance *date, VARIANT *retv) 00798 { 00799 static const WCHAR NaNW[] = { 'N','a','N',0 }; 00800 static const WCHAR formatADW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',0 }; 00801 static const WCHAR formatBCW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',' ','B','.','C','.',0 }; 00802 00803 static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, 00804 LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, 00805 LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 }; 00806 static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, 00807 LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4, 00808 LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, 00809 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, 00810 LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10, 00811 LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 }; 00812 00813 BOOL formatAD = TRUE; 00814 BSTR week, month; 00815 BSTR date_str; 00816 DOUBLE time; 00817 int len, size, year, day; 00818 DWORD lcid_en, week_id, month_id; 00819 00820 if(isnan(date->time)) { 00821 if(retv) { 00822 V_VT(retv) = VT_BSTR; 00823 V_BSTR(retv) = SysAllocString(NaNW); 00824 if(!V_BSTR(retv)) 00825 return E_OUTOFMEMORY; 00826 } 00827 return S_OK; 00828 } 00829 00830 time = local_time(date->time, date); 00831 00832 if(retv) { 00833 len = 5; 00834 00835 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT); 00836 00837 week_id = week_ids[(int)week_day(time)]; 00838 size = GetLocaleInfoW(lcid_en, week_id, NULL, 0); 00839 week = SysAllocStringLen(NULL, size); 00840 if(!week) 00841 return E_OUTOFMEMORY; 00842 GetLocaleInfoW(lcid_en, week_id, week, size); 00843 len += size-1; 00844 00845 month_id = month_ids[(int)month_from_time(time)]; 00846 size = GetLocaleInfoW(lcid_en, month_id, NULL, 0); 00847 month = SysAllocStringLen(NULL, size); 00848 if(!month) { 00849 SysFreeString(week); 00850 return E_OUTOFMEMORY; 00851 } 00852 GetLocaleInfoW(lcid_en, month_id, month, size); 00853 len += size-1; 00854 00855 year = year_from_time(time); 00856 if(year<0) 00857 year = -year+1; 00858 do { 00859 year /= 10; 00860 len++; 00861 } while(year); 00862 00863 year = year_from_time(time); 00864 if(year<0) { 00865 formatAD = FALSE; 00866 year = -year+1; 00867 len += 5; 00868 } 00869 00870 day = date_from_time(time); 00871 do { 00872 day /= 10; 00873 len++; 00874 } while(day); 00875 day = date_from_time(time); 00876 00877 date_str = SysAllocStringLen(NULL, len); 00878 if(!date_str) { 00879 SysFreeString(week); 00880 SysFreeString(month); 00881 return E_OUTOFMEMORY; 00882 } 00883 sprintfW(date_str, formatAD?formatADW:formatBCW, week, month, day, year); 00884 00885 SysFreeString(week); 00886 SysFreeString(month); 00887 00888 V_VT(retv) = VT_BSTR; 00889 V_BSTR(retv) = date_str; 00890 } 00891 return S_OK; 00892 } 00893 00894 static HRESULT Date_toDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00895 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00896 { 00897 DateInstance *date; 00898 00899 if(!(date = date_this(jsthis))) 00900 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 00901 00902 return dateobj_to_date_string(date, retv); 00903 } 00904 00905 /* ECMA-262 3rd Edition 15.9.5.4 */ 00906 static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00907 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00908 { 00909 static const WCHAR NaNW[] = { 'N','a','N',0 }; 00910 static const WCHAR formatW[] = { '%','0','2','d',':','%','0','2','d',':','%','0','2','d', 00911 ' ','U','T','C','%','c','%','0','2','d','%','0','2','d',0 }; 00912 static const WCHAR formatUTCW[] = { '%','0','2','d',':','%','0','2','d', 00913 ':','%','0','2','d',' ','U','T','C',0 }; 00914 DateInstance *date; 00915 BSTR date_str; 00916 DOUBLE time; 00917 WCHAR sign; 00918 int offset; 00919 00920 TRACE("\n"); 00921 00922 if(!(date = date_this(jsthis))) 00923 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 00924 00925 if(isnan(date->time)) { 00926 if(retv) { 00927 V_VT(retv) = VT_BSTR; 00928 V_BSTR(retv) = SysAllocString(NaNW); 00929 if(!V_BSTR(retv)) 00930 return E_OUTOFMEMORY; 00931 } 00932 return S_OK; 00933 } 00934 00935 time = local_time(date->time, date); 00936 00937 if(retv) { 00938 date_str = SysAllocStringLen(NULL, 17); 00939 if(!date_str) 00940 return E_OUTOFMEMORY; 00941 00942 offset = date->bias + 00943 daylight_saving_ta(time, date); 00944 00945 if(offset < 0) { 00946 sign = '+'; 00947 offset = -offset; 00948 } 00949 else sign = '-'; 00950 00951 if(offset) 00952 sprintfW(date_str, formatW, (int)hour_from_time(time), 00953 (int)min_from_time(time), (int)sec_from_time(time), 00954 sign, offset/60, offset%60); 00955 else 00956 sprintfW(date_str, formatUTCW, (int)hour_from_time(time), 00957 (int)min_from_time(time), (int)sec_from_time(time)); 00958 00959 V_VT(retv) = VT_BSTR; 00960 V_BSTR(retv) = date_str; 00961 } 00962 return S_OK; 00963 } 00964 00965 /* ECMA-262 3rd Edition 15.9.5.6 */ 00966 static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 00967 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 00968 { 00969 static const WCHAR NaNW[] = { 'N','a','N',0 }; 00970 SYSTEMTIME st; 00971 DateInstance *date; 00972 BSTR date_str; 00973 int len; 00974 00975 TRACE("\n"); 00976 00977 if(!(date = date_this(jsthis))) 00978 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 00979 00980 if(isnan(date->time)) { 00981 if(retv) { 00982 V_VT(retv) = VT_BSTR; 00983 V_BSTR(retv) = SysAllocString(NaNW); 00984 if(!V_BSTR(retv)) 00985 return E_OUTOFMEMORY; 00986 } 00987 return S_OK; 00988 } 00989 00990 st = create_systemtime(local_time(date->time, date)); 00991 00992 if(st.wYear<1601 || st.wYear>9999) 00993 return dateobj_to_date_string(date, retv); 00994 00995 if(retv) { 00996 len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0); 00997 date_str = SysAllocStringLen(NULL, len); 00998 if(!date_str) 00999 return E_OUTOFMEMORY; 01000 GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, len); 01001 01002 V_VT(retv) = VT_BSTR; 01003 V_BSTR(retv) = date_str; 01004 } 01005 return S_OK; 01006 } 01007 01008 /* ECMA-262 3rd Edition 15.9.5.7 */ 01009 static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01010 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01011 { 01012 static const WCHAR NaNW[] = { 'N','a','N',0 }; 01013 SYSTEMTIME st; 01014 DateInstance *date; 01015 BSTR date_str; 01016 int len; 01017 01018 TRACE("\n"); 01019 01020 if(!(date = date_this(jsthis))) 01021 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01022 01023 if(isnan(date->time)) { 01024 if(retv) { 01025 V_VT(retv) = VT_BSTR; 01026 V_BSTR(retv) = SysAllocString(NaNW); 01027 if(!V_BSTR(retv)) 01028 return E_OUTOFMEMORY; 01029 } 01030 return S_OK; 01031 } 01032 01033 st = create_systemtime(local_time(date->time, date)); 01034 01035 if(st.wYear<1601 || st.wYear>9999) 01036 return Date_toTimeString(ctx, jsthis, flags, dp, retv, ei, caller); 01037 01038 if(retv) { 01039 len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0); 01040 date_str = SysAllocStringLen(NULL, len); 01041 if(!date_str) 01042 return E_OUTOFMEMORY; 01043 GetTimeFormatW(ctx->lcid, 0, &st, NULL, date_str, len); 01044 01045 V_VT(retv) = VT_BSTR; 01046 V_BSTR(retv) = date_str; 01047 } 01048 return S_OK; 01049 } 01050 01051 /* ECMA-262 3rd Edition 15.9.5.9 */ 01052 static HRESULT Date_getTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01053 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01054 { 01055 DateInstance *date; 01056 01057 TRACE("\n"); 01058 01059 if(!(date = date_this(jsthis))) 01060 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01061 01062 if(retv) 01063 num_set_val(retv, date->time); 01064 return S_OK; 01065 } 01066 01067 /* ECMA-262 3rd Edition 15.9.5.10 */ 01068 static HRESULT Date_getFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01069 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01070 { 01071 DateInstance *date; 01072 01073 TRACE("\n"); 01074 01075 if(!(date = date_this(jsthis))) 01076 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01077 01078 if(retv) { 01079 DOUBLE time = local_time(date->time, date); 01080 01081 num_set_val(retv, year_from_time(time)); 01082 } 01083 return S_OK; 01084 } 01085 01086 /* ECMA-262 3rd Edition 15.9.5.11 */ 01087 static HRESULT Date_getUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01088 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01089 { 01090 DateInstance *date; 01091 01092 TRACE("\n"); 01093 01094 if(!(date = date_this(jsthis))) 01095 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01096 01097 if(retv) 01098 num_set_val(retv, year_from_time(date->time)); 01099 return S_OK; 01100 } 01101 01102 /* ECMA-262 3rd Edition 15.9.5.12 */ 01103 static HRESULT Date_getMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01104 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01105 { 01106 DateInstance *date; 01107 01108 TRACE("\n"); 01109 01110 if(!(date = date_this(jsthis))) 01111 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01112 01113 if(retv) { 01114 DOUBLE time = local_time(date->time, date); 01115 01116 num_set_val(retv, month_from_time(time)); 01117 } 01118 return S_OK; 01119 } 01120 01121 /* ECMA-262 3rd Edition 15.9.5.13 */ 01122 static HRESULT Date_getUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01123 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01124 { 01125 DateInstance *date; 01126 01127 TRACE("\n"); 01128 01129 if(!(date = date_this(jsthis))) 01130 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01131 01132 if(retv) 01133 num_set_val(retv, month_from_time(date->time)); 01134 return S_OK; 01135 } 01136 01137 /* ECMA-262 3rd Edition 15.9.5.14 */ 01138 static HRESULT Date_getDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01139 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01140 { 01141 DateInstance *date; 01142 01143 TRACE("\n"); 01144 01145 if(!(date = date_this(jsthis))) 01146 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01147 01148 if(retv) { 01149 DOUBLE time = local_time(date->time, date); 01150 01151 num_set_val(retv, date_from_time(time)); 01152 } 01153 return S_OK; 01154 } 01155 01156 /* ECMA-262 3rd Edition 15.9.5.15 */ 01157 static HRESULT Date_getUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01158 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01159 { 01160 DateInstance *date; 01161 01162 TRACE("\n"); 01163 01164 if(!(date = date_this(jsthis))) 01165 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01166 01167 if(retv) 01168 num_set_val(retv, date_from_time(date->time)); 01169 return S_OK; 01170 } 01171 01172 /* ECMA-262 3rd Edition 15.9.5.16 */ 01173 static HRESULT Date_getDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01174 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01175 { 01176 DateInstance *date; 01177 01178 TRACE("\n"); 01179 01180 if(!(date = date_this(jsthis))) 01181 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01182 01183 if(retv) { 01184 DOUBLE time = local_time(date->time, date); 01185 01186 num_set_val(retv, week_day(time)); 01187 } 01188 return S_OK; 01189 } 01190 01191 /* ECMA-262 3rd Edition 15.9.5.17 */ 01192 static HRESULT Date_getUTCDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01193 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01194 { 01195 DateInstance *date; 01196 01197 TRACE("\n"); 01198 01199 if(!(date = date_this(jsthis))) 01200 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01201 01202 if(retv) 01203 num_set_val(retv, week_day(date->time)); 01204 return S_OK; 01205 } 01206 01207 /* ECMA-262 3rd Edition 15.9.5.18 */ 01208 static HRESULT Date_getHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01209 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01210 { 01211 DateInstance *date; 01212 01213 TRACE("\n"); 01214 01215 if(!(date = date_this(jsthis))) 01216 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01217 01218 if(retv) { 01219 DOUBLE time = local_time(date->time, date); 01220 01221 num_set_val(retv, hour_from_time(time)); 01222 } 01223 return S_OK; 01224 } 01225 01226 /* ECMA-262 3rd Edition 15.9.5.19 */ 01227 static HRESULT Date_getUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01228 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01229 { 01230 DateInstance *date; 01231 01232 TRACE("\n"); 01233 01234 if(!(date = date_this(jsthis))) 01235 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01236 01237 if(retv) 01238 num_set_val(retv, hour_from_time(date->time)); 01239 return S_OK; 01240 } 01241 01242 /* ECMA-262 3rd Edition 15.9.5.20 */ 01243 static HRESULT Date_getMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01244 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01245 { 01246 DateInstance *date; 01247 01248 TRACE("\n"); 01249 01250 if(!(date = date_this(jsthis))) 01251 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01252 01253 if(retv) { 01254 DOUBLE time = local_time(date->time, date); 01255 01256 num_set_val(retv, min_from_time(time)); 01257 } 01258 return S_OK; 01259 } 01260 01261 /* ECMA-262 3rd Edition 15.9.5.21 */ 01262 static HRESULT Date_getUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01263 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01264 { 01265 DateInstance *date; 01266 01267 TRACE("\n"); 01268 01269 if(!(date = date_this(jsthis))) 01270 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01271 01272 if(retv) 01273 num_set_val(retv, min_from_time(date->time)); 01274 return S_OK; 01275 } 01276 01277 /* ECMA-262 3rd Edition 15.9.5.22 */ 01278 static HRESULT Date_getSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01279 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01280 { 01281 DateInstance *date; 01282 01283 TRACE("\n"); 01284 01285 if(!(date = date_this(jsthis))) 01286 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01287 01288 if(retv) { 01289 DOUBLE time = local_time(date->time, date); 01290 01291 num_set_val(retv, sec_from_time(time)); 01292 } 01293 return S_OK; 01294 } 01295 01296 /* ECMA-262 3rd Edition 15.9.5.23 */ 01297 static HRESULT Date_getUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01298 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01299 { 01300 DateInstance *date; 01301 01302 TRACE("\n"); 01303 01304 if(!(date = date_this(jsthis))) 01305 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01306 01307 if(retv) 01308 num_set_val(retv, sec_from_time(date->time)); 01309 return S_OK; 01310 } 01311 01312 /* ECMA-262 3rd Edition 15.9.5.24 */ 01313 static HRESULT Date_getMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01314 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01315 { 01316 DateInstance *date; 01317 01318 TRACE("\n"); 01319 01320 if(!(date = date_this(jsthis))) 01321 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01322 01323 if(retv) { 01324 DOUBLE time = local_time(date->time, date); 01325 01326 num_set_val(retv, ms_from_time(time)); 01327 } 01328 return S_OK; 01329 } 01330 01331 /* ECMA-262 3rd Edition 15.9.5.25 */ 01332 static HRESULT Date_getUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01333 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01334 { 01335 DateInstance *date; 01336 01337 TRACE("\n"); 01338 01339 if(!(date = date_this(jsthis))) 01340 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01341 01342 if(retv) 01343 num_set_val(retv, ms_from_time(date->time)); 01344 return S_OK; 01345 } 01346 01347 /* ECMA-262 3rd Edition 15.9.5.26 */ 01348 static HRESULT Date_getTimezoneOffset(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01349 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01350 { 01351 DateInstance *date; 01352 01353 TRACE("\n"); 01354 01355 if(!(date = date_this(jsthis))) 01356 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01357 01358 if(retv) 01359 num_set_val(retv, floor( 01360 (date->time-local_time(date->time, date))/MS_PER_MINUTE)); 01361 return S_OK; 01362 } 01363 01364 /* ECMA-262 3rd Edition 15.9.5.27 */ 01365 static HRESULT Date_setTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01366 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01367 { 01368 VARIANT v; 01369 HRESULT hres; 01370 DateInstance *date; 01371 01372 TRACE("\n"); 01373 01374 if(!(date = date_this(jsthis))) 01375 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01376 01377 if(!arg_cnt(dp)) 01378 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01379 01380 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01381 if(FAILED(hres)) 01382 return hres; 01383 01384 date->time = time_clip(num_val(&v)); 01385 01386 if(retv) 01387 num_set_val(retv, date->time); 01388 01389 return S_OK; 01390 } 01391 01392 /* ECMA-262 3rd Edition 15.9.5.28 */ 01393 static HRESULT Date_setMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01394 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01395 { 01396 VARIANT v; 01397 HRESULT hres; 01398 DateInstance *date; 01399 DOUBLE t; 01400 01401 TRACE("\n"); 01402 01403 if(!(date = date_this(jsthis))) 01404 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01405 01406 if(!arg_cnt(dp)) 01407 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01408 01409 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01410 if(FAILED(hres)) 01411 return hres; 01412 01413 t = local_time(date->time, date); 01414 t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t), 01415 sec_from_time(t), num_val(&v))); 01416 date->time = time_clip(utc(t, date)); 01417 01418 if(retv) 01419 num_set_val(retv, date->time); 01420 01421 return S_OK; 01422 } 01423 01424 /* ECMA-262 3rd Edition 15.9.5.29 */ 01425 static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01426 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01427 { 01428 VARIANT v; 01429 HRESULT hres; 01430 DateInstance *date; 01431 DOUBLE t; 01432 01433 TRACE("\n"); 01434 01435 if(!(date = date_this(jsthis))) 01436 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01437 01438 if(!arg_cnt(dp)) 01439 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01440 01441 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01442 if(FAILED(hres)) 01443 return hres; 01444 01445 t = date->time; 01446 t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t), 01447 sec_from_time(t), num_val(&v))); 01448 date->time = time_clip(t); 01449 01450 if(retv) 01451 num_set_val(retv, date->time); 01452 01453 return S_OK; 01454 } 01455 01456 /* ECMA-262 3rd Edition 15.9.5.30 */ 01457 static HRESULT Date_setSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01458 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01459 { 01460 VARIANT v; 01461 HRESULT hres; 01462 DateInstance *date; 01463 DOUBLE t, sec, ms; 01464 01465 TRACE("\n"); 01466 01467 if(!(date = date_this(jsthis))) 01468 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01469 01470 if(!arg_cnt(dp)) 01471 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01472 01473 t = local_time(date->time, date); 01474 01475 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01476 if(FAILED(hres)) 01477 return hres; 01478 sec = num_val(&v); 01479 01480 if(arg_cnt(dp) > 1) { 01481 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01482 if(FAILED(hres)) 01483 return hres; 01484 ms = num_val(&v); 01485 } 01486 else ms = ms_from_time(t); 01487 01488 t = make_date(day(t), make_time(hour_from_time(t), 01489 min_from_time(t), sec, ms)); 01490 date->time = time_clip(utc(t, date)); 01491 01492 if(retv) 01493 num_set_val(retv, date->time); 01494 01495 return S_OK; 01496 } 01497 01498 /* ECMA-262 3rd Edition 15.9.5.31 */ 01499 static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01500 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01501 { 01502 VARIANT v; 01503 HRESULT hres; 01504 DateInstance *date; 01505 DOUBLE t, sec, ms; 01506 01507 TRACE("\n"); 01508 01509 if(!(date = date_this(jsthis))) 01510 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01511 01512 if(!arg_cnt(dp)) 01513 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01514 01515 t = date->time; 01516 01517 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01518 if(FAILED(hres)) 01519 return hres; 01520 sec = num_val(&v); 01521 01522 if(arg_cnt(dp) > 1) { 01523 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01524 if(FAILED(hres)) 01525 return hres; 01526 ms = num_val(&v); 01527 } 01528 else ms = ms_from_time(t); 01529 01530 t = make_date(day(t), make_time(hour_from_time(t), 01531 min_from_time(t), sec, ms)); 01532 date->time = time_clip(t); 01533 01534 if(retv) 01535 num_set_val(retv, date->time); 01536 01537 return S_OK; 01538 } 01539 01540 /* ECMA-262 3rd Edition 15.9.5.33 */ 01541 static HRESULT Date_setMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01542 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01543 { 01544 VARIANT v; 01545 HRESULT hres; 01546 DateInstance *date; 01547 DOUBLE t, min, sec, ms; 01548 01549 TRACE("\n"); 01550 01551 if(!(date = date_this(jsthis))) 01552 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01553 01554 if(!arg_cnt(dp)) 01555 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01556 01557 t = local_time(date->time, date); 01558 01559 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01560 if(FAILED(hres)) 01561 return hres; 01562 min = num_val(&v); 01563 01564 if(arg_cnt(dp) > 1) { 01565 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01566 if(FAILED(hres)) 01567 return hres; 01568 sec = num_val(&v); 01569 } 01570 else sec = sec_from_time(t); 01571 01572 if(arg_cnt(dp) > 2) { 01573 hres = to_number(ctx, get_arg(dp, 2), ei, &v); 01574 if(FAILED(hres)) 01575 return hres; 01576 ms = num_val(&v); 01577 } 01578 else ms = ms_from_time(t); 01579 01580 t = make_date(day(t), make_time(hour_from_time(t), 01581 min, sec, ms)); 01582 date->time = time_clip(utc(t, date)); 01583 01584 if(retv) 01585 num_set_val(retv, date->time); 01586 01587 return S_OK; 01588 } 01589 01590 /* ECMA-262 3rd Edition 15.9.5.34 */ 01591 static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01592 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01593 { 01594 VARIANT v; 01595 HRESULT hres; 01596 DateInstance *date; 01597 DOUBLE t, min, sec, ms; 01598 01599 TRACE("\n"); 01600 01601 if(!(date = date_this(jsthis))) 01602 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01603 01604 if(!arg_cnt(dp)) 01605 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01606 01607 t = date->time; 01608 01609 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01610 if(FAILED(hres)) 01611 return hres; 01612 min = num_val(&v); 01613 01614 if(arg_cnt(dp) > 1) { 01615 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01616 if(FAILED(hres)) 01617 return hres; 01618 sec = num_val(&v); 01619 } 01620 else sec = sec_from_time(t); 01621 01622 if(arg_cnt(dp) > 2) { 01623 hres = to_number(ctx, get_arg(dp, 2), ei, &v); 01624 if(FAILED(hres)) 01625 return hres; 01626 ms = num_val(&v); 01627 } 01628 else ms = ms_from_time(t); 01629 01630 t = make_date(day(t), make_time(hour_from_time(t), 01631 min, sec, ms)); 01632 date->time = time_clip(t); 01633 01634 if(retv) 01635 num_set_val(retv, date->time); 01636 01637 return S_OK; 01638 } 01639 01640 /* ECMA-262 3rd Edition 15.9.5.35 */ 01641 static HRESULT Date_setHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01642 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01643 { 01644 VARIANT v; 01645 HRESULT hres; 01646 DateInstance *date; 01647 DOUBLE t, hour, min, sec, ms; 01648 01649 TRACE("\n"); 01650 01651 if(!(date = date_this(jsthis))) 01652 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01653 01654 if(!arg_cnt(dp)) 01655 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01656 01657 t = local_time(date->time, date); 01658 01659 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01660 if(FAILED(hres)) 01661 return hres; 01662 hour = num_val(&v); 01663 01664 if(arg_cnt(dp) > 1) { 01665 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01666 if(FAILED(hres)) 01667 return hres; 01668 min = num_val(&v); 01669 } 01670 else min = min_from_time(t); 01671 01672 if(arg_cnt(dp) > 2) { 01673 hres = to_number(ctx, get_arg(dp, 2), ei, &v); 01674 if(FAILED(hres)) 01675 return hres; 01676 sec = num_val(&v); 01677 } 01678 else sec = sec_from_time(t); 01679 01680 if(arg_cnt(dp) > 3) { 01681 hres = to_number(ctx, get_arg(dp, 3), ei, &v); 01682 if(FAILED(hres)) 01683 return hres; 01684 ms = num_val(&v); 01685 } 01686 else ms = ms_from_time(t); 01687 01688 t = make_date(day(t), make_time(hour, min, sec, ms)); 01689 date->time = time_clip(utc(t, date)); 01690 01691 if(retv) 01692 num_set_val(retv, date->time); 01693 01694 return S_OK; 01695 } 01696 01697 /* ECMA-262 3rd Edition 15.9.5.36 */ 01698 static HRESULT Date_setUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01699 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01700 { 01701 DateInstance *date; 01702 VARIANT v; 01703 HRESULT hres; 01704 DOUBLE t, hour, min, sec, ms; 01705 01706 TRACE("\n"); 01707 01708 if(!(date = date_this(jsthis))) 01709 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01710 01711 if(!arg_cnt(dp)) 01712 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01713 01714 t = date->time; 01715 01716 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01717 if(FAILED(hres)) 01718 return hres; 01719 hour = num_val(&v); 01720 01721 if(arg_cnt(dp) > 1) { 01722 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01723 if(FAILED(hres)) 01724 return hres; 01725 min = num_val(&v); 01726 } 01727 else min = min_from_time(t); 01728 01729 if(arg_cnt(dp) > 2) { 01730 hres = to_number(ctx, get_arg(dp, 2), ei, &v); 01731 if(FAILED(hres)) 01732 return hres; 01733 sec = num_val(&v); 01734 } 01735 else sec = sec_from_time(t); 01736 01737 if(arg_cnt(dp) > 3) { 01738 hres = to_number(ctx, get_arg(dp, 3), ei, &v); 01739 if(FAILED(hres)) 01740 return hres; 01741 ms = num_val(&v); 01742 } 01743 else ms = ms_from_time(t); 01744 01745 t = make_date(day(t), make_time(hour, min, sec, ms)); 01746 date->time = time_clip(t); 01747 01748 if(retv) 01749 num_set_val(retv, date->time); 01750 01751 return S_OK; 01752 } 01753 01754 /* ECMA-262 3rd Edition 15.9.5.36 */ 01755 static HRESULT Date_setDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01756 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01757 { 01758 VARIANT v; 01759 HRESULT hres; 01760 DateInstance *date; 01761 DOUBLE t; 01762 01763 TRACE("\n"); 01764 01765 if(!(date = date_this(jsthis))) 01766 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01767 01768 if(!arg_cnt(dp)) 01769 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01770 01771 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01772 if(FAILED(hres)) 01773 return hres; 01774 01775 t = local_time(date->time, date); 01776 t = make_date(make_day(year_from_time(t), month_from_time(t), 01777 num_val(&v)), time_within_day(t)); 01778 date->time = time_clip(utc(t, date)); 01779 01780 if(retv) 01781 num_set_val(retv, date->time); 01782 01783 return S_OK; 01784 } 01785 01786 /* ECMA-262 3rd Edition 15.9.5.37 */ 01787 static HRESULT Date_setUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01788 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01789 { 01790 VARIANT v; 01791 HRESULT hres; 01792 DateInstance *date; 01793 DOUBLE t; 01794 01795 TRACE("\n"); 01796 01797 if(!(date = date_this(jsthis))) 01798 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01799 01800 if(!arg_cnt(dp)) 01801 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01802 01803 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01804 if(FAILED(hres)) 01805 return hres; 01806 01807 t = date->time; 01808 t = make_date(make_day(year_from_time(t), month_from_time(t), 01809 num_val(&v)), time_within_day(t)); 01810 date->time = time_clip(t); 01811 01812 if(retv) 01813 num_set_val(retv, date->time); 01814 01815 return S_OK; 01816 } 01817 01818 /* ECMA-262 3rd Edition 15.9.5.38 */ 01819 static HRESULT Date_setMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01820 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01821 { 01822 VARIANT v; 01823 HRESULT hres; 01824 DateInstance *date; 01825 DOUBLE t, month, ddate; 01826 01827 TRACE("\n"); 01828 01829 if(!(date = date_this(jsthis))) 01830 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01831 01832 if(!arg_cnt(dp)) 01833 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01834 01835 t = local_time(date->time, date); 01836 01837 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01838 if(FAILED(hres)) 01839 return hres; 01840 month = num_val(&v); 01841 01842 if(arg_cnt(dp) > 1) { 01843 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01844 if(FAILED(hres)) 01845 return hres; 01846 ddate = num_val(&v); 01847 } 01848 else ddate = date_from_time(t); 01849 01850 t = make_date(make_day(year_from_time(t), month, ddate), 01851 time_within_day(t)); 01852 date->time = time_clip(utc(t, date)); 01853 01854 if(retv) 01855 num_set_val(retv, date->time); 01856 01857 return S_OK; 01858 } 01859 01860 /* ECMA-262 3rd Edition 15.9.5.39 */ 01861 static HRESULT Date_setUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01862 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01863 { 01864 VARIANT v; 01865 HRESULT hres; 01866 DateInstance *date; 01867 DOUBLE t, month, ddate; 01868 01869 TRACE("\n"); 01870 01871 if(!(date = date_this(jsthis))) 01872 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01873 01874 if(!arg_cnt(dp)) 01875 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01876 01877 t = date->time; 01878 01879 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01880 if(FAILED(hres)) 01881 return hres; 01882 month = num_val(&v); 01883 01884 if(arg_cnt(dp) > 1) { 01885 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01886 if(FAILED(hres)) 01887 return hres; 01888 ddate = num_val(&v); 01889 } 01890 else ddate = date_from_time(t); 01891 01892 t = make_date(make_day(year_from_time(t), month, ddate), 01893 time_within_day(t)); 01894 date->time = time_clip(t); 01895 01896 if(retv) 01897 num_set_val(retv, date->time); 01898 01899 return S_OK; 01900 } 01901 01902 /* ECMA-262 3rd Edition 15.9.5.40 */ 01903 static HRESULT Date_setFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01904 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01905 { 01906 VARIANT v; 01907 HRESULT hres; 01908 DateInstance *date; 01909 DOUBLE t, year, month, ddate; 01910 01911 TRACE("\n"); 01912 01913 if(!(date = date_this(jsthis))) 01914 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01915 01916 if(!arg_cnt(dp)) 01917 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01918 01919 t = local_time(date->time, date); 01920 01921 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01922 if(FAILED(hres)) 01923 return hres; 01924 year = num_val(&v); 01925 01926 if(arg_cnt(dp) > 1) { 01927 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01928 if(FAILED(hres)) 01929 return hres; 01930 month = num_val(&v); 01931 } 01932 else month = month_from_time(t); 01933 01934 if(arg_cnt(dp) > 2) { 01935 hres = to_number(ctx, get_arg(dp, 2), ei, &v); 01936 if(FAILED(hres)) 01937 return hres; 01938 ddate = num_val(&v); 01939 } 01940 else ddate = date_from_time(t); 01941 01942 t = make_date(make_day(year, month, ddate), time_within_day(t)); 01943 date->time = time_clip(utc(t, date)); 01944 01945 if(retv) 01946 num_set_val(retv, date->time); 01947 01948 return S_OK; 01949 } 01950 01951 /* ECMA-262 3rd Edition 15.9.5.41 */ 01952 static HRESULT Date_setUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 01953 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 01954 { 01955 VARIANT v; 01956 HRESULT hres; 01957 DateInstance *date; 01958 DOUBLE t, year, month, ddate; 01959 01960 TRACE("\n"); 01961 01962 if(!(date = date_this(jsthis))) 01963 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 01964 01965 if(!arg_cnt(dp)) 01966 return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL); 01967 01968 t = date->time; 01969 01970 hres = to_number(ctx, get_arg(dp, 0), ei, &v); 01971 if(FAILED(hres)) 01972 return hres; 01973 year = num_val(&v); 01974 01975 if(arg_cnt(dp) > 1) { 01976 hres = to_number(ctx, get_arg(dp, 1), ei, &v); 01977 if(FAILED(hres)) 01978 return hres; 01979 month = num_val(&v); 01980 } 01981 else month = month_from_time(t); 01982 01983 if(arg_cnt(dp) > 2) { 01984 hres = to_number(ctx, get_arg(dp, 2), ei, &v); 01985 if(FAILED(hres)) 01986 return hres; 01987 ddate = num_val(&v); 01988 } 01989 else ddate = date_from_time(t); 01990 01991 t = make_date(make_day(year, month, ddate), time_within_day(t)); 01992 date->time = time_clip(t); 01993 01994 if(retv) 01995 num_set_val(retv, date->time); 01996 01997 return S_OK; 01998 } 01999 02000 /* ECMA-262 3rd Edition B2.4 */ 02001 static HRESULT Date_getYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 02002 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 02003 { 02004 DateInstance *date; 02005 DOUBLE t, year; 02006 02007 TRACE("\n"); 02008 02009 if(!(date = date_this(jsthis))) 02010 return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL); 02011 02012 t = local_time(date->time, date); 02013 if(isnan(t)) { 02014 if(retv) 02015 num_set_nan(retv); 02016 return S_OK; 02017 } 02018 02019 year = year_from_time(t); 02020 if(retv) 02021 num_set_val(retv, (1900<=year && year<2000)?year-1900:year); 02022 02023 return S_OK; 02024 } 02025 02026 static HRESULT Date_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 02027 VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) 02028 { 02029 TRACE("\n"); 02030 02031 switch(flags) { 02032 case INVOKE_FUNC: 02033 return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL); 02034 default: 02035 FIXME("unimplemented flags %x\n", flags); 02036 return E_NOTIMPL; 02037 } 02038 02039 return S_OK; 02040 } 02041 02042 static const builtin_prop_t Date_props[] = { 02043 {getDateW, Date_getDate, PROPF_METHOD}, 02044 {getDayW, Date_getDay, PROPF_METHOD}, 02045 {getFullYearW, Date_getFullYear, PROPF_METHOD}, 02046 {getHoursW, Date_getHours, PROPF_METHOD}, 02047 {getMillisecondsW, Date_getMilliseconds, PROPF_METHOD}, 02048 {getMinutesW, Date_getMinutes, PROPF_METHOD}, 02049 {getMonthW, Date_getMonth, PROPF_METHOD}, 02050 {getSecondsW, Date_getSeconds, PROPF_METHOD}, 02051 {getTimeW, Date_getTime, PROPF_METHOD}, 02052 {getTimezoneOffsetW, Date_getTimezoneOffset, PROPF_METHOD}, 02053 {getUTCDateW, Date_getUTCDate, PROPF_METHOD}, 02054 {getUTCDayW, Date_getUTCDay, PROPF_METHOD}, 02055 {getUTCFullYearW, Date_getUTCFullYear, PROPF_METHOD}, 02056 {getUTCHoursW, Date_getUTCHours, PROPF_METHOD}, 02057 {getUTCMillisecondsW, Date_getUTCMilliseconds, PROPF_METHOD}, 02058 {getUTCMinutesW, Date_getUTCMinutes, PROPF_METHOD}, 02059 {getUTCMonthW, Date_getUTCMonth, PROPF_METHOD}, 02060 {getUTCSecondsW, Date_getUTCSeconds, PROPF_METHOD}, 02061 {getYearW, Date_getYear, PROPF_METHOD}, 02062 {setDateW, Date_setDate, PROPF_METHOD|1}, 02063 {setFullYearW, Date_setFullYear, PROPF_METHOD|3}, 02064 {setHoursW, Date_setHours, PROPF_METHOD|4}, 02065 {setMillisecondsW, Date_setMilliseconds, PROPF_METHOD|1}, 02066 {setMinutesW, Date_setMinutes, PROPF_METHOD|3}, 02067 {setMonthW, Date_setMonth, PROPF_METHOD|2}, 02068 {setSecondsW, Date_setSeconds, PROPF_METHOD|2}, 02069 {setTimeW, Date_setTime, PROPF_METHOD|1}, 02070 {setUTCDateW, Date_setUTCDate, PROPF_METHOD|1}, 02071 {setUTCFullYearW, Date_setUTCFullYear, PROPF_METHOD|3}, 02072 {setUTCHoursW, Date_setUTCHours, PROPF_METHOD|4}, 02073 {setUTCMillisecondsW, Date_setUTCMilliseconds, PROPF_METHOD|1}, 02074 {setUTCMinutesW, Date_setUTCMinutes, PROPF_METHOD|3}, 02075 {setUTCMonthW, Date_setUTCMonth, PROPF_METHOD|2}, 02076 {setUTCSecondsW, Date_setUTCSeconds, PROPF_METHOD|2}, 02077 {toDateStringW, Date_toDateString, PROPF_METHOD}, 02078 {toGMTStringW, Date_toGMTString, PROPF_METHOD}, 02079 {toLocaleDateStringW, Date_toLocaleDateString, PROPF_METHOD}, 02080 {toLocaleStringW, Date_toLocaleString, PROPF_METHOD}, 02081 {toLocaleTimeStringW, Date_toLocaleTimeString, PROPF_METHOD}, 02082 {toStringW, Date_toString, PROPF_METHOD}, 02083 {toTimeStringW, Date_toTimeString, PROPF_METHOD}, 02084 {toUTCStringW, Date_toUTCString, PROPF_METHOD}, 02085 {valueOfW, Date_valueOf, PROPF_METHOD}, 02086 }; 02087 02088 static const builtin_info_t Date_info = { 02089 JSCLASS_DATE, 02090 {NULL, Date_value, 0}, 02091 sizeof(Date_props)/sizeof(*Date_props), 02092 Date_props, 02093 NULL, 02094 NULL 02095 }; 02096 02097 static HRESULT create_date(script_ctx_t *ctx, DispatchEx *object_prototype, DOUBLE time, DispatchEx **ret) 02098 { 02099 DateInstance *date; 02100 HRESULT hres; 02101 TIME_ZONE_INFORMATION tzi; 02102 02103 GetTimeZoneInformation(&tzi); 02104 02105 date = heap_alloc_zero(sizeof(DateInstance)); 02106 if(!date) 02107 return E_OUTOFMEMORY; 02108 02109 if(object_prototype) 02110 hres = init_dispex(&date->dispex, ctx, &Date_info, object_prototype); 02111 else 02112 hres = init_dispex_from_constr(&date->dispex, ctx, &Date_info, ctx->date_constr); 02113 if(FAILED(hres)) { 02114 heap_free(date); 02115 return hres; 02116 } 02117 02118 date->time = time; 02119 date->bias = tzi.Bias; 02120 date->standardDate = tzi.StandardDate; 02121 date->standardBias = tzi.StandardBias; 02122 date->daylightDate = tzi.DaylightDate; 02123 date->daylightBias = tzi.DaylightBias; 02124 02125 *ret = &date->dispex; 02126 return S_OK; 02127 } 02128 02129 static inline HRESULT date_parse(BSTR input, VARIANT *retv) { 02130 static const DWORD string_ids[] = { LOCALE_SMONTHNAME12, LOCALE_SMONTHNAME11, 02131 LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME8, 02132 LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME5, 02133 LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME3, LOCALE_SMONTHNAME2, 02134 LOCALE_SMONTHNAME1, LOCALE_SDAYNAME7, LOCALE_SDAYNAME1, 02135 LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, 02136 LOCALE_SDAYNAME5, LOCALE_SDAYNAME6 }; 02137 BSTR strings[sizeof(string_ids)/sizeof(DWORD)]; 02138 02139 BSTR parse; 02140 int input_len, parse_len = 0, nest_level = 0, i, size; 02141 int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0; 02142 int ms = 0, offset = 0, hour_adjust = 0; 02143 BOOL set_year = FALSE, set_month = FALSE, set_day = FALSE, set_hour = FALSE; 02144 BOOL set_offset = FALSE, set_era = FALSE, ad = TRUE, set_am = FALSE, am = TRUE; 02145 BOOL set_hour_adjust = TRUE; 02146 TIME_ZONE_INFORMATION tzi; 02147 DateInstance di; 02148 DWORD lcid_en; 02149 02150 if(retv) num_set_nan(retv); 02151 02152 input_len = SysStringLen(input); 02153 for(i=0; i<input_len; i++) { 02154 if(input[i] == '(') nest_level++; 02155 else if(input[i] == ')') { 02156 nest_level--; 02157 if(nest_level<0) 02158 return S_OK; 02159 } 02160 else if(!nest_level) parse_len++; 02161 } 02162 02163 parse = SysAllocStringLen(NULL, parse_len); 02164 if(!parse) 02165 return E_OUTOFMEMORY; 02166 nest_level = 0; 02167 parse_len = 0; 02168 for(i=0; i<input_len; i++) { 02169 if(input[i] == '(') nest_level++; 02170 else if(input[i] == ')') nest_level--; 02171 else if(!nest_level) parse[parse_len++] = toupperW(input[i]); 02172 } 02173 02174 GetTimeZoneInformation(&tzi); 02175 di.bias = tzi.Bias; 02176 di.standardDate = tzi.StandardDate; 02177 di.standardBias = tzi.StandardBias; 02178 di.daylightDate = tzi.DaylightDate; 02179 di.daylightBias = tzi.DaylightBias; 02180 02181 lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT); 02182 for(i=0; i<sizeof(string_ids)/sizeof(DWORD); i++) { 02183 size = GetLocaleInfoW(lcid_en, string_ids[i], NULL, 0); 02184 strings[i] = SysAllocStringLen(NULL, size); 02185 if(!strings[i]) { 02186 i--; 02187 while(i-- >= 0) 02188 SysFreeString(strings[i]); 02189 SysFreeString(parse); 02190 return E_OUTOFMEMORY; 02191 } 02192 GetLocaleInfoW(lcid_en, string_ids[i], strings[i], size); 02193 } 02194 02195 for(i=0; i<parse_len;) { 02196 while(isspaceW(parse[i])) i++; 02197 if(parse[i] == ',') { 02198 while(parse[i] == ',') i++; 02199 continue; 02200 } 02201 02202 if(parse[i]>='0' && parse[i]<='9') { 02203 int tmp = atoiW(&parse[i]); 02204 while(parse[i]>='0' && parse[i]<='9') i++; 02205 while(isspaceW(parse[i])) i++; 02206 02207 if(parse[i] == ':') { 02208 /* Time */ 02209 if(set_hour) break; 02210 set_hour = TRUE; 02211 02212 hour = tmp; 02213 02214 while(parse[i] == ':') i++; 02215 while(isspaceW(parse[i])) i++; 02216 if(parse[i]>='0' && parse[i]<='9') { 02217 min = atoiW(&parse[i]); 02218 while(parse[i]>='0' && parse[i]<='9') i++; 02219 } 02220 02221 while(isspaceW(parse[i])) i++; 02222 while(parse[i] == ':') i++; 02223 while(isspaceW(parse[i])) i++; 02224 if(parse[i]>='0' && parse[i]<='9') { 02225 sec = atoiW(&parse[i]); 02226 while(parse[i]>='0' && parse[i]<='9') i++; 02227 } 02228 } 02229 else if(parse[i]=='-' || parse[i]=='/') { 02230 /* Short date */ 02231 if(set_day || set_month || set_year) break; 02232 set_day = TRUE; 02233 set_month = TRUE; 02234 set_year = TRUE; 02235 02236 month = tmp-1; 02237 02238 while(isspaceW(parse[i])) i++; 02239 while(parse[i]=='-' || parse[i]=='/') i++; 02240 while(isspaceW(parse[i])) i++; 02241 if(parse[i]<'0' || parse[i]>'9') break; 02242 day = atoiW(&parse[i]); 02243 while(parse[i]>='0' && parse[i]<='9') i++; 02244 02245 while(parse[i]=='-' || parse[i]=='/') i++; 02246 while(isspaceW(parse[i])) i++; 02247 if(parse[i]<'0' || parse[i]>'9') break; 02248 year = atoiW(&parse[i]); 02249 while(parse[i]>='0' && parse[i]<='9') i++; 02250 } 02251 else if(tmp<0) break; 02252 else if(tmp<70) { 02253 /* Day */ 02254 if(set_day) break; 02255 set_day = TRUE; 02256 day = tmp; 02257 } 02258 else { 02259 /* Year */ 02260 if(set_year) break; 02261 set_year = TRUE; 02262 year = tmp; 02263 } 02264 } 02265 else { 02266 if(parse[i]<'A' || parse[i]>'Z') break; 02267 else if(parse[i]=='B' && (parse[i+1]=='C' || 02268 (parse[i+1]=='.' && parse[i+2]=='C'))) { 02269 /* AD/BC */ 02270 if(set_era) break; 02271 set_era = TRUE; 02272 ad = FALSE; 02273 02274 i++; 02275 if(parse[i] == '.') i++; 02276 i++; 02277 if(parse[i] == '.') i++; 02278 } 02279 else if(parse[i]=='A' && (parse[i+1]=='D' || 02280 (parse[i+1]=='.' && parse[i+2]=='D'))) { 02281 /* AD/BC */ 02282 if(set_era) break; 02283 set_era = TRUE; 02284 02285 i++; 02286 if(parse[i] == '.') i++; 02287 i++; 02288 if(parse[i] == '.') i++; 02289 } 02290 else if(parse[i+1]<'A' || parse[i+1]>'Z') { 02291 /* Timezone */ 02292 if(set_offset) break; 02293 set_offset = TRUE; 02294 02295 if(parse[i] <= 'I') hour_adjust = parse[i]-'A'+2; 02296 else if(parse[i] == 'J') break; 02297 else if(parse[i] <= 'M') hour_adjust = parse[i]-'K'+11; 02298 else if(parse[i] <= 'Y') hour_adjust = parse[i]-'N'; 02299 else hour_adjust = 1; 02300 02301 i++; 02302 if(parse[i] == '.') i++; 02303 } 02304 else if(parse[i]=='A' && parse[i+1]=='M') { 02305 /* AM/PM */ 02306 if(set_am) break; 02307 set_am = TRUE; 02308 am = TRUE; 02309 i += 2; 02310 } 02311 else if(parse[i]=='P' && parse[i+1]=='M') { 02312 /* AM/PM */ 02313 if(set_am) break; 02314 set_am = TRUE; 02315 am = FALSE; 02316 i += 2; 02317 } 02318 else if((parse[i]=='U' && parse[i+1]=='T' && parse[i+2]=='C') 02319 || (parse[i]=='G' && parse[i+1]=='M' && parse[i+2]=='T')) { 02320 /* Timezone */ 02321 BOOL positive = TRUE; 02322 02323 if(set_offset) break; 02324 set_offset = TRUE; 02325 set_hour_adjust = FALSE; 02326 02327 i += 3; 02328 while(isspaceW(parse[i])) i++; 02329 if(parse[i] == '-') positive = FALSE; 02330 else if(parse[i] != '+') continue; 02331 02332 i++; 02333 while(isspaceW(parse[i])) i++; 02334 if(parse[i]<'0' || parse[i]>'9') break; 02335 offset = atoiW(&parse[i]); 02336 while(parse[i]>='0' && parse[i]<='9') i++; 02337 02338 if(offset<24) offset *= 60; 02339 else offset = (offset/100)*60 + offset%100; 02340 02341 if(positive) offset = -offset; 02342 } 02343 else { 02344 /* Month or garbage */ 02345 int j; 02346 02347 for(size=i; parse[size]>='A' && parse[size]<='Z'; size++); 02348 size -= i; 02349 02350 for(j=0; j<sizeof(string_ids)/sizeof(DWORD); j++) 02351 if(!memicmpW(&parse[i], strings[j], size)) break; 02352 02353 if(j < 12) { 02354 if(set_month) break; 02355 set_month = TRUE; 02356 month = 11-j; 02357 } 02358 else if(j == sizeof(string_ids)/sizeof(DWORD)) break; 02359 02360 i += size; 02361 } 02362 } 02363 } 02364 02365 if(retv && i==parse_len && set_year && set_month 02366 && set_day && (!set_am || hour<13)) { 02367 if(set_am) { 02368 if(hour == 12) hour = 0; 02369 if(!am) hour += 12; 02370 } 02371 02372 if(!ad) year = -year+1; 02373 else if(year<100) year += 1900; 02374 02375 V_VT(retv) = VT_R8; 02376 V_R8(retv) = time_clip(make_date(make_day(year, month, day), 02377 make_time(hour+hour_adjust, min, sec, ms)) + offset*MS_PER_MINUTE); 02378 02379 if(set_hour_adjust) V_R8(retv) = utc(V_R8(retv), &di); 02380 } 02381 02382 for(i=0; i<sizeof(string_ids)/sizeof(DWORD); i++) 02383 SysFreeString(strings[i]); 02384 SysFreeString(parse); 02385 02386 return S_OK; 02387 } 02388 02389 static HRESULT DateConstr_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 02390 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 02391 { 02392 BSTR parse_str; 02393 HRESULT hres; 02394 02395 TRACE("\n"); 02396 02397 if(!arg_cnt(dp)) { 02398 if(retv) 02399 num_set_nan(retv); 02400 return S_OK; 02401 } 02402 02403 hres = to_string(ctx, get_arg(dp,0), ei, &parse_str); 02404 if(FAILED(hres)) 02405 return hres; 02406 02407 hres = date_parse(parse_str, retv); 02408 02409 SysFreeString(parse_str); 02410 return hres; 02411 } 02412 02413 static HRESULT date_utc(script_ctx_t *ctx, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) 02414 { 02415 VARIANT year, month, vdate, hours, minutes, seconds, ms; 02416 DOUBLE y; 02417 int arg_no = arg_cnt(dp); 02418 HRESULT hres; 02419 02420 TRACE("\n"); 02421 02422 if(arg_no>0) { 02423 hres = to_number(ctx, get_arg(dp, 0), ei, &year); 02424 if(FAILED(hres)) 02425 return hres; 02426 y = num_val(&year); 02427 if(0<=y && y<=99) 02428 y += 1900; 02429 } 02430 else y = 1900; 02431 02432 if(arg_no>1) { 02433 hres = to_number(ctx, get_arg(dp, 1), ei, &month); 02434 if(FAILED(hres)) 02435 return hres; 02436 } 02437 else { 02438 V_VT(&month) = VT_R8; 02439 V_R8(&month) = 0; 02440 } 02441 02442 if(arg_no>2) { 02443 hres = to_number(ctx, get_arg(dp, 2), ei, &vdate); 02444 if(FAILED(hres)) 02445 return hres; 02446 } 02447 else { 02448 V_VT(&vdate) = VT_R8; 02449 V_R8(&vdate) = 1; 02450 } 02451 02452 if(arg_no>3) { 02453 hres = to_number(ctx, get_arg(dp, 3), ei, &hours); 02454 if(FAILED(hres)) 02455 return hres; 02456 } 02457 else { 02458 V_VT(&hours) = VT_R8; 02459 V_R8(&hours) = 0; 02460 } 02461 02462 if(arg_no>4) { 02463 hres = to_number(ctx, get_arg(dp, 4), ei, &minutes); 02464 if(FAILED(hres)) 02465 return hres; 02466 } 02467 else { 02468 V_VT(&minutes) = VT_R8; 02469 V_R8(&minutes) = 0; 02470 } 02471 02472 if(arg_no>5) { 02473 hres = to_number(ctx, get_arg(dp, 5), ei, &seconds); 02474 if(FAILED(hres)) 02475 return hres; 02476 } 02477 else { 02478 V_VT(&seconds) = VT_R8; 02479 V_R8(&seconds) = 0; 02480 } 02481 02482 if(arg_no>6) { 02483 hres = to_number(ctx, get_arg(dp, 6), ei, &ms); 02484 if(FAILED(hres)) 02485 return hres; 02486 } 02487 else { 02488 V_VT(&ms) = VT_R8; 02489 V_R8(&ms) = 0; 02490 } 02491 02492 if(retv) { 02493 V_VT(retv) = VT_R8; 02494 V_R8(retv) = time_clip(make_date( 02495 make_day(y, num_val(&month), num_val(&vdate)), 02496 make_time(num_val(&hours), num_val(&minutes), 02497 num_val(&seconds), num_val(&ms)))); 02498 } 02499 02500 return S_OK; 02501 } 02502 02503 static HRESULT DateConstr_UTC(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 02504 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 02505 { 02506 TRACE("\n"); 02507 02508 return date_utc(ctx, dp, retv, ei); 02509 } 02510 02511 static HRESULT DateConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, 02512 VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) 02513 { 02514 DispatchEx *date; 02515 HRESULT hres; 02516 02517 TRACE("\n"); 02518 02519 switch(flags) { 02520 case DISPATCH_CONSTRUCT: 02521 switch(arg_cnt(dp)) { 02522 /* ECMA-262 3rd Edition 15.9.3.3 */ 02523 case 0: { 02524 FILETIME time; 02525 LONGLONG lltime; 02526 02527 GetSystemTimeAsFileTime(&time); 02528 lltime = ((LONGLONG)time.dwHighDateTime<<32) 02529 + time.dwLowDateTime; 02530 02531 hres = create_date(ctx, NULL, lltime/10000-TIME_EPOCH, &date); 02532 if(FAILED(hres)) 02533 return hres; 02534 break; 02535 } 02536 02537 /* ECMA-262 3rd Edition 15.9.3.2 */ 02538 case 1: { 02539 VARIANT prim, num; 02540 02541 hres = to_primitive(ctx, get_arg(dp,0), ei, &prim, NO_HINT); 02542 if(FAILED(hres)) 02543 return hres; 02544 02545 if(V_VT(&prim) == VT_BSTR) 02546 hres = date_parse(V_BSTR(&prim), &num); 02547 else 02548 hres = to_number(ctx, &prim, ei, &num); 02549 02550 VariantClear(&prim); 02551 if(FAILED(hres)) 02552 return hres; 02553 02554 hres = create_date(ctx, NULL, time_clip(num_val(&num)), &date); 02555 if(FAILED(hres)) 02556 return hres; 02557 break; 02558 } 02559 02560 /* ECMA-262 3rd Edition 15.9.3.1 */ 02561 default: { 02562 VARIANT ret_date; 02563 DateInstance *di; 02564 02565 hres = date_utc(ctx, dp, &ret_date, ei); 02566 if(FAILED(hres)) 02567 return hres; 02568 02569 hres = create_date(ctx, NULL, num_val(&ret_date), &date); 02570 if(FAILED(hres)) 02571 return hres; 02572 02573 di = (DateInstance*)date; 02574 di->time = utc(di->time, di); 02575 } 02576 } 02577 02578 V_VT(retv) = VT_DISPATCH; 02579 V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(date); 02580 return S_OK; 02581 02582 case INVOKE_FUNC: { 02583 FILETIME system_time, local_time; 02584 LONGLONG lltime; 02585 02586 GetSystemTimeAsFileTime(&system_time); 02587 FileTimeToLocalFileTime(&system_time, &local_time); 02588 lltime = ((LONGLONG)local_time.dwHighDateTime<<32) 02589 + local_time.dwLowDateTime; 02590 02591 return date_to_string(lltime/10000-TIME_EPOCH, FALSE, 0, retv); 02592 } 02593 02594 default: 02595 FIXME("unimplemented flags %x\n", flags); 02596 return E_NOTIMPL; 02597 } 02598 02599 return S_OK; 02600 } 02601 02602 static const builtin_prop_t DateConstr_props[] = { 02603 {UTCW, DateConstr_UTC, PROPF_METHOD}, 02604 {parseW, DateConstr_parse, PROPF_METHOD} 02605 }; 02606 02607 static const builtin_info_t DateConstr_info = { 02608 JSCLASS_FUNCTION, 02609 {NULL, Function_value, 0}, 02610 sizeof(DateConstr_props)/sizeof(*DateConstr_props), 02611 DateConstr_props, 02612 NULL, 02613 NULL 02614 }; 02615 02616 HRESULT create_date_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret) 02617 { 02618 DispatchEx *date; 02619 HRESULT hres; 02620 02621 static const WCHAR DateW[] = {'D','a','t','e',0}; 02622 02623 hres = create_date(ctx, object_prototype, 0.0, &date); 02624 if(FAILED(hres)) 02625 return hres; 02626 02627 hres = create_builtin_function(ctx, DateConstr_value, DateW, &DateConstr_info, 02628 PROPF_CONSTR|7, date, ret); 02629 02630 jsdisp_release(date); 02631 return hres; 02632 } Generated on Thu May 24 2012 04:18:23 for ReactOS by
1.7.6.1
|