PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/dll/win32/jscript/date.c

https://bitbucket.org/arty/arty-newcc-reactos
C | 2632 lines | 2026 code | 508 blank | 98 comment | 488 complexity | f9eb3a8f9a3ca66747e9f5f09c0cccc8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-3.0, CC-BY-SA-3.0, AGPL-3.0, GPL-3.0, CPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright 2008 Jacek Caban for CodeWeavers
  3. * Copyright 2009 Piotr Caban
  4. *
  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.
  9. *
  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.
  14. *
  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
  18. */
  19. #include "config.h"
  20. #include "wine/port.h"
  21. #include <limits.h>
  22. #include <math.h>
  23. #include "jscript.h"
  24. #include "wine/debug.h"
  25. WINE_DEFAULT_DEBUG_CHANNEL(jscript);
  26. /* 1601 to 1970 is 369 years plus 89 leap days */
  27. #define TIME_EPOCH ((ULONGLONG)(369 * 365 + 89) * 86400 * 1000)
  28. typedef struct {
  29. DispatchEx dispex;
  30. /* ECMA-262 3rd Edition 15.9.1.1 */
  31. DOUBLE time;
  32. LONG bias;
  33. SYSTEMTIME standardDate;
  34. LONG standardBias;
  35. SYSTEMTIME daylightDate;
  36. LONG daylightBias;
  37. } DateInstance;
  38. static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
  39. static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
  40. static const WCHAR propertyIsEnumerableW[] =
  41. {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
  42. static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
  43. static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
  44. static const WCHAR toUTCStringW[] = {'t','o','U','T','C','S','t','r','i','n','g',0};
  45. static const WCHAR toGMTStringW[] = {'t','o','G','M','T','S','t','r','i','n','g',0};
  46. static const WCHAR toDateStringW[] = {'t','o','D','a','t','e','S','t','r','i','n','g',0};
  47. static const WCHAR toTimeStringW[] = {'t','o','T','i','m','e','S','t','r','i','n','g',0};
  48. static const WCHAR toLocaleDateStringW[] = {'t','o','L','o','c','a','l','e','D','a','t','e','S','t','r','i','n','g',0};
  49. static const WCHAR toLocaleTimeStringW[] = {'t','o','L','o','c','a','l','e','T','i','m','e','S','t','r','i','n','g',0};
  50. static const WCHAR getTimeW[] = {'g','e','t','T','i','m','e',0};
  51. static const WCHAR getFullYearW[] = {'g','e','t','F','u','l','l','Y','e','a','r',0};
  52. static const WCHAR getUTCFullYearW[] = {'g','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};
  53. static const WCHAR getMonthW[] = {'g','e','t','M','o','n','t','h',0};
  54. static const WCHAR getUTCMonthW[] = {'g','e','t','U','T','C','M','o','n','t','h',0};
  55. static const WCHAR getDateW[] = {'g','e','t','D','a','t','e',0};
  56. static const WCHAR getUTCDateW[] = {'g','e','t','U','T','C','D','a','t','e',0};
  57. static const WCHAR getDayW[] = {'g','e','t','D','a','y',0};
  58. static const WCHAR getUTCDayW[] = {'g','e','t','U','T','C','D','a','y',0};
  59. static const WCHAR getHoursW[] = {'g','e','t','H','o','u','r','s',0};
  60. static const WCHAR getUTCHoursW[] = {'g','e','t','U','T','C','H','o','u','r','s',0};
  61. static const WCHAR getMinutesW[] = {'g','e','t','M','i','n','u','t','e','s',0};
  62. static const WCHAR getUTCMinutesW[] = {'g','e','t','U','T','C','M','i','n','u','t','e','s',0};
  63. static const WCHAR getSecondsW[] = {'g','e','t','S','e','c','o','n','d','s',0};
  64. static const WCHAR getUTCSecondsW[] = {'g','e','t','U','T','C','S','e','c','o','n','d','s',0};
  65. static const WCHAR getMillisecondsW[] = {'g','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0};
  66. static const WCHAR getUTCMillisecondsW[] = {'g','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0};
  67. static const WCHAR getTimezoneOffsetW[] = {'g','e','t','T','i','m','e','z','o','n','e','O','f','f','s','e','t',0};
  68. static const WCHAR setTimeW[] = {'s','e','t','T','i','m','e',0};
  69. static const WCHAR setMillisecondsW[] = {'s','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0};
  70. static const WCHAR setUTCMillisecondsW[] = {'s','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0};
  71. static const WCHAR setSecondsW[] = {'s','e','t','S','e','c','o','n','d','s',0};
  72. static const WCHAR setUTCSecondsW[] = {'s','e','t','U','T','C','S','e','c','o','n','d','s',0};
  73. static const WCHAR setMinutesW[] = {'s','e','t','M','i','n','u','t','e','s',0};
  74. static const WCHAR setUTCMinutesW[] = {'s','e','t','U','T','C','M','i','n','u','t','e','s',0};
  75. static const WCHAR setHoursW[] = {'s','e','t','H','o','u','r','s',0};
  76. static const WCHAR setUTCHoursW[] = {'s','e','t','U','T','C','H','o','u','r','s',0};
  77. static const WCHAR setDateW[] = {'s','e','t','D','a','t','e',0};
  78. static const WCHAR setUTCDateW[] = {'s','e','t','U','T','C','D','a','t','e',0};
  79. static const WCHAR setMonthW[] = {'s','e','t','M','o','n','t','h',0};
  80. static const WCHAR setUTCMonthW[] = {'s','e','t','U','T','C','M','o','n','t','h',0};
  81. static const WCHAR setFullYearW[] = {'s','e','t','F','u','l','l','Y','e','a','r',0};
  82. static const WCHAR setUTCFullYearW[] = {'s','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};
  83. static const WCHAR getYearW[] = {'g','e','t','Y','e','a','r',0};
  84. static const WCHAR UTCW[] = {'U','T','C',0};
  85. static const WCHAR parseW[] = {'p','a','r','s','e',0};
  86. static inline DateInstance *date_this(vdisp_t *jsthis)
  87. {
  88. return is_vclass(jsthis, JSCLASS_DATE) ? (DateInstance*)jsthis->u.jsdisp : NULL;
  89. }
  90. /*ECMA-262 3rd Edition 15.9.1.2 */
  91. #define MS_PER_DAY 86400000
  92. #define MS_PER_HOUR 3600000
  93. #define MS_PER_MINUTE 60000
  94. /* ECMA-262 3rd Edition 15.9.1.2 */
  95. static inline DOUBLE day(DOUBLE time)
  96. {
  97. return floor(time / MS_PER_DAY);
  98. }
  99. /* ECMA-262 3rd Edition 15.9.1.2 */
  100. static inline DOUBLE time_within_day(DOUBLE time)
  101. {
  102. DOUBLE ret;
  103. ret = fmod(time, MS_PER_DAY);
  104. if(ret < 0)
  105. ret += MS_PER_DAY;
  106. return ret;
  107. }
  108. /* ECMA-262 3rd Edition 15.9.1.3 */
  109. static inline DOUBLE days_in_year(DOUBLE year)
  110. {
  111. int y;
  112. if(year != (int)year)
  113. return ret_nan();
  114. y = year;
  115. if(y%4 != 0) return 365;
  116. if(y%100 != 0) return 366;
  117. if(y%400 != 0) return 365;
  118. return 366;
  119. }
  120. /* ECMA-262 3rd Edition 15.9.1.3 */
  121. static inline DOUBLE day_from_year(DOUBLE year)
  122. {
  123. if(year != (int)year)
  124. return ret_nan();
  125. return floor(365.0*(year-1970) + floor((year-1969)/4)
  126. - floor((year-1901)/100) + floor((year-1601)/400));
  127. }
  128. static inline int day_from_month(int month, int in_leap_year)
  129. {
  130. switch(month)
  131. {
  132. case 0:
  133. return 0;
  134. case 1:
  135. return 31;
  136. case 2:
  137. return 59+in_leap_year;
  138. case 3:
  139. return 90+in_leap_year;
  140. case 4:
  141. return 120+in_leap_year;
  142. case 5:
  143. return 151+in_leap_year;
  144. case 6:
  145. return 181+in_leap_year;
  146. case 7:
  147. return 212+in_leap_year;
  148. case 8:
  149. return 243+in_leap_year;
  150. case 9:
  151. return 273+in_leap_year;
  152. case 10:
  153. return 304+in_leap_year;
  154. default:
  155. return 334+in_leap_year;
  156. }
  157. }
  158. /* ECMA-262 3rd Edition 15.9.1.3 */
  159. static inline DOUBLE time_from_year(DOUBLE year)
  160. {
  161. return MS_PER_DAY*day_from_year(year);
  162. }
  163. /* ECMA-262 3rd Edition 15.9.1.3 */
  164. static inline DOUBLE year_from_time(DOUBLE time)
  165. {
  166. int y;
  167. if(isnan(time))
  168. return ret_nan();
  169. y = 1970 + time/365.25/MS_PER_DAY;
  170. if(time_from_year(y) > time)
  171. while(time_from_year(y) > time) y--;
  172. else
  173. while(time_from_year(y+1)<=time) y++;
  174. return y;
  175. }
  176. /* ECMA-262 3rd Edition 15.9.1.3 */
  177. static inline int in_leap_year(DOUBLE time)
  178. {
  179. if(days_in_year(year_from_time(time))==366)
  180. return 1;
  181. return 0;
  182. }
  183. /* ECMA-262 3rd Edition 15.9.1.4 */
  184. static inline int day_within_year(DOUBLE time)
  185. {
  186. return day(time) - day_from_year(year_from_time(time));
  187. }
  188. /* ECMA-262 3rd Edition 15.9.1.4 */
  189. static inline DOUBLE month_from_time(DOUBLE time)
  190. {
  191. int ily = in_leap_year(time);
  192. int dwy = day_within_year(time);
  193. if(isnan(time))
  194. return ret_nan();
  195. if(0<=dwy && dwy<31) return 0;
  196. if(dwy < 59+ily) return 1;
  197. if(dwy < 90+ily) return 2;
  198. if(dwy < 120+ily) return 3;
  199. if(dwy < 151+ily) return 4;
  200. if(dwy < 181+ily) return 5;
  201. if(dwy < 212+ily) return 6;
  202. if(dwy < 243+ily) return 7;
  203. if(dwy < 273+ily) return 8;
  204. if(dwy < 304+ily) return 9;
  205. if(dwy < 334+ily) return 10;
  206. return 11;
  207. }
  208. /* ECMA-262 3rd Edition 15.9.1.5 */
  209. static inline DOUBLE date_from_time(DOUBLE time)
  210. {
  211. int dwy = day_within_year(time);
  212. int ily = in_leap_year(time);
  213. int mft = month_from_time(time);
  214. if(isnan(time))
  215. return ret_nan();
  216. if(mft==0) return dwy+1;
  217. if(mft==1) return dwy-30;
  218. if(mft==2) return dwy-58-ily;
  219. if(mft==3) return dwy-89-ily;
  220. if(mft==4) return dwy-119-ily;
  221. if(mft==5) return dwy-150-ily;
  222. if(mft==6) return dwy-180-ily;
  223. if(mft==7) return dwy-211-ily;
  224. if(mft==8) return dwy-242-ily;
  225. if(mft==9) return dwy-272-ily;
  226. if(mft==10) return dwy-303-ily;
  227. return dwy-333-ily;
  228. }
  229. /* ECMA-262 3rd Edition 15.9.1.6 */
  230. static inline DOUBLE week_day(DOUBLE time)
  231. {
  232. DOUBLE ret;
  233. if(isnan(time))
  234. return ret_nan();
  235. ret = fmod(day(time)+4, 7);
  236. if(ret<0) ret += 7;
  237. return ret;
  238. }
  239. static inline DOUBLE convert_time(int year, SYSTEMTIME st)
  240. {
  241. DOUBLE time;
  242. int set_week_day;
  243. if(st.wMonth == 0)
  244. return ret_nan();
  245. if(st.wYear != 0)
  246. year = st.wYear;
  247. time = time_from_year(year);
  248. time += (DOUBLE)day_from_month(st.wMonth-1, in_leap_year(time)) * MS_PER_DAY;
  249. if(st.wYear == 0) {
  250. set_week_day = st.wDayOfWeek-week_day(time);
  251. if(set_week_day < 0)
  252. set_week_day += 7;
  253. time += set_week_day * MS_PER_DAY;
  254. time += (DOUBLE)(st.wDay-1) * 7 * MS_PER_DAY;
  255. if(month_from_time(time) != st.wMonth-1)
  256. time -= 7 * MS_PER_DAY;
  257. }
  258. else
  259. time += st.wDay * MS_PER_DAY;
  260. time += st.wHour * MS_PER_HOUR;
  261. time += st.wMinute * MS_PER_MINUTE;
  262. return time;
  263. }
  264. /* ECMA-262 3rd Edition 15.9.1.9 */
  265. static inline DOUBLE daylight_saving_ta(DOUBLE time, DateInstance *date)
  266. {
  267. int year = year_from_time(time);
  268. DOUBLE standardTime, daylightTime;
  269. if(isnan(time))
  270. return 0;
  271. standardTime = convert_time(year, date->standardDate);
  272. daylightTime = convert_time(year, date->daylightDate);
  273. if(isnan(standardTime) || isnan(daylightTime))
  274. return 0;
  275. else if(standardTime > daylightTime) {
  276. if(daylightTime <= time && time < standardTime)
  277. return date->daylightBias;
  278. return date->standardBias;
  279. }
  280. else {
  281. if(standardTime <= time && time < daylightTime)
  282. return date->standardBias;
  283. return date->daylightBias;
  284. }
  285. }
  286. /* ECMA-262 3rd Edition 15.9.1.9 */
  287. static inline DOUBLE local_time(DOUBLE time, DateInstance *date)
  288. {
  289. return time - (daylight_saving_ta(time, date)+date->bias)*MS_PER_MINUTE;
  290. }
  291. /* ECMA-262 3rd Edition 15.9.1.9 */
  292. static inline DOUBLE utc(DOUBLE time, DateInstance *date)
  293. {
  294. time += date->bias * MS_PER_MINUTE;
  295. return time + daylight_saving_ta(time, date)*MS_PER_MINUTE;
  296. }
  297. /* ECMA-262 3rd Edition 15.9.1.10 */
  298. static inline DOUBLE hour_from_time(DOUBLE time)
  299. {
  300. DOUBLE ret;
  301. if(isnan(time))
  302. return ret_nan();
  303. ret = fmod(floor(time/MS_PER_HOUR), 24);
  304. if(ret<0) ret += 24;
  305. return ret;
  306. }
  307. /* ECMA-262 3rd Edition 15.9.1.10 */
  308. static inline DOUBLE min_from_time(DOUBLE time)
  309. {
  310. DOUBLE ret;
  311. if(isnan(time))
  312. return ret_nan();
  313. ret = fmod(floor(time/MS_PER_MINUTE), 60);
  314. if(ret<0) ret += 60;
  315. return ret;
  316. }
  317. /* ECMA-262 3rd Edition 15.9.1.10 */
  318. static inline DOUBLE sec_from_time(DOUBLE time)
  319. {
  320. DOUBLE ret;
  321. if(isnan(time))
  322. return ret_nan();
  323. ret = fmod(floor(time/1000), 60);
  324. if(ret<0) ret += 60;
  325. return ret;
  326. }
  327. /* ECMA-262 3rd Edition 15.9.1.10 */
  328. static inline DOUBLE ms_from_time(DOUBLE time)
  329. {
  330. DOUBLE ret;
  331. if(isnan(time))
  332. return ret_nan();
  333. ret = fmod(time, 1000);
  334. if(ret<0) ret += 1000;
  335. return ret;
  336. }
  337. /* ECMA-262 3rd Edition 15.9.1.11 */
  338. static inline DOUBLE make_time(DOUBLE hour, DOUBLE min, DOUBLE sec, DOUBLE ms)
  339. {
  340. return hour*MS_PER_HOUR + min*MS_PER_MINUTE + sec*1000 + ms;
  341. }
  342. /* ECMA-262 3rd Edition 15.9.1.12 */
  343. static inline DOUBLE make_day(DOUBLE year, DOUBLE month, DOUBLE day)
  344. {
  345. DOUBLE time;
  346. year += floor(month/12);
  347. month = fmod(month, 12);
  348. if(month<0) month += 12;
  349. time = time_from_year(year);
  350. day += floor(time / MS_PER_DAY);
  351. day += day_from_month(month, in_leap_year(time));
  352. return day-1;
  353. }
  354. /* ECMA-262 3rd Edition 15.9.1.13 */
  355. static inline DOUBLE make_date(DOUBLE day, DOUBLE time)
  356. {
  357. return day*MS_PER_DAY + time;
  358. }
  359. /* ECMA-262 3rd Edition 15.9.1.14 */
  360. static inline DOUBLE time_clip(DOUBLE time)
  361. {
  362. if(8.64e15 < time || time < -8.64e15) {
  363. return ret_nan();
  364. }
  365. return floor(time);
  366. }
  367. static SYSTEMTIME create_systemtime(DOUBLE time)
  368. {
  369. SYSTEMTIME st;
  370. st.wYear = year_from_time(time);
  371. st.wMonth = month_from_time(time) + 1;
  372. st.wDayOfWeek = week_day(time);
  373. st.wDay = date_from_time(time);
  374. st.wHour = hour_from_time(time);
  375. st.wMinute = min_from_time(time);
  376. st.wSecond = sec_from_time(time);
  377. st.wMilliseconds = ms_from_time(time);
  378. return st;
  379. }
  380. static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset, VARIANT *retv)
  381. {
  382. static const WCHAR NaNW[] = { 'N','a','N',0 };
  383. static const WCHAR formatW[] = { '%','s',' ','%','s',' ','%','d',' ',
  384. '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ',
  385. 'U','T','C','%','c','%','0','2','d','%','0','2','d',' ','%','d','%','s',0 };
  386. static const WCHAR formatUTCW[] = { '%','s',' ','%','s',' ','%','d',' ',
  387. '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ',
  388. 'U','T','C',' ','%','d','%','s',0 };
  389. static const WCHAR formatNoOffsetW[] = { '%','s',' ','%','s',' ',
  390. '%','d',' ','%','0','2','d',':','%','0','2','d',':',
  391. '%','0','2','d',' ','%','d','%','s',0 };
  392. static const WCHAR ADW[] = { 0 };
  393. static const WCHAR BCW[] = { ' ','B','.','C','.',0 };
  394. static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1,
  395. LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4,
  396. LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 };
  397. static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
  398. LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
  399. LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
  400. LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
  401. LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
  402. LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
  403. BOOL formatAD = TRUE;
  404. BSTR week, month;
  405. BSTR date_str;
  406. int len, size, year, day;
  407. DWORD lcid_en, week_id, month_id;
  408. WCHAR sign = '-';
  409. if(isnan(time)) {
  410. if(retv) {
  411. V_VT(retv) = VT_BSTR;
  412. V_BSTR(retv) = SysAllocString(NaNW);
  413. if(!V_BSTR(retv))
  414. return E_OUTOFMEMORY;
  415. }
  416. return S_OK;
  417. }
  418. if(retv) {
  419. len = 21;
  420. lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
  421. week_id = week_ids[(int)week_day(time)];
  422. size = GetLocaleInfoW(lcid_en, week_id, NULL, 0);
  423. week = SysAllocStringLen(NULL, size);
  424. if(!week)
  425. return E_OUTOFMEMORY;
  426. GetLocaleInfoW(lcid_en, week_id, week, size);
  427. len += size-1;
  428. month_id = month_ids[(int)month_from_time(time)];
  429. size = GetLocaleInfoW(lcid_en, month_id, NULL, 0);
  430. month = SysAllocStringLen(NULL, size);
  431. if(!month) {
  432. SysFreeString(week);
  433. return E_OUTOFMEMORY;
  434. }
  435. GetLocaleInfoW(lcid_en, month_id, month, size);
  436. len += size-1;
  437. year = year_from_time(time);
  438. if(year<0)
  439. year = -year+1;
  440. do {
  441. year /= 10;
  442. len++;
  443. } while(year);
  444. year = year_from_time(time);
  445. if(year<0) {
  446. formatAD = FALSE;
  447. year = -year+1;
  448. len += 5;
  449. }
  450. day = date_from_time(time);
  451. do {
  452. day /= 10;
  453. len++;
  454. } while(day);
  455. day = date_from_time(time);
  456. if(!show_offset) len -= 9;
  457. else if(offset == 0) len -= 5;
  458. else if(offset < 0) {
  459. sign = '+';
  460. offset = -offset;
  461. }
  462. date_str = SysAllocStringLen(NULL, len);
  463. if(!date_str) {
  464. SysFreeString(week);
  465. SysFreeString(month);
  466. return E_OUTOFMEMORY;
  467. }
  468. if(!show_offset)
  469. sprintfW(date_str, formatNoOffsetW, week, month, day,
  470. (int)hour_from_time(time), (int)min_from_time(time),
  471. (int)sec_from_time(time), year, formatAD?ADW:BCW);
  472. else if(offset)
  473. sprintfW(date_str, formatW, week, month, day,
  474. (int)hour_from_time(time), (int)min_from_time(time),
  475. (int)sec_from_time(time), sign, offset/60, offset%60,
  476. year, formatAD?ADW:BCW);
  477. else
  478. sprintfW(date_str, formatUTCW, week, month, day,
  479. (int)hour_from_time(time), (int)min_from_time(time),
  480. (int)sec_from_time(time), year, formatAD?ADW:BCW);
  481. SysFreeString(week);
  482. SysFreeString(month);
  483. V_VT(retv) = VT_BSTR;
  484. V_BSTR(retv) = date_str;
  485. }
  486. return S_OK;
  487. }
  488. /* ECMA-262 3rd Edition 15.9.1.2 */
  489. static HRESULT dateobj_to_string(DateInstance *date, VARIANT *retv)
  490. {
  491. DOUBLE time;
  492. int offset;
  493. time = local_time(date->time, date);
  494. offset = date->bias +
  495. daylight_saving_ta(time, date);
  496. return date_to_string(time, TRUE, offset, retv);
  497. }
  498. static HRESULT Date_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  499. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  500. {
  501. DateInstance *date;
  502. TRACE("\n");
  503. if(!(date = date_this(jsthis)))
  504. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  505. return dateobj_to_string(date, retv);
  506. }
  507. /* ECMA-262 3rd Edition 15.9.1.5 */
  508. static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  509. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  510. {
  511. static const WCHAR NaNW[] = { 'N','a','N',0 };
  512. SYSTEMTIME st;
  513. DateInstance *date;
  514. BSTR date_str;
  515. int date_len, time_len;
  516. TRACE("\n");
  517. if(!(date = date_this(jsthis)))
  518. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  519. if(isnan(date->time)) {
  520. if(retv) {
  521. V_VT(retv) = VT_BSTR;
  522. V_BSTR(retv) = SysAllocString(NaNW);
  523. if(!V_BSTR(retv))
  524. return E_OUTOFMEMORY;
  525. }
  526. return S_OK;
  527. }
  528. st = create_systemtime(local_time(date->time, date));
  529. if(st.wYear<1601 || st.wYear>9999)
  530. return dateobj_to_string(date, retv);
  531. if(retv) {
  532. date_len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
  533. time_len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
  534. date_str = SysAllocStringLen(NULL, date_len+time_len-1);
  535. if(!date_str)
  536. return E_OUTOFMEMORY;
  537. GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, date_len);
  538. GetTimeFormatW(ctx->lcid, 0, &st, NULL, &date_str[date_len], time_len);
  539. date_str[date_len-1] = ' ';
  540. V_VT(retv) = VT_BSTR;
  541. V_BSTR(retv) = date_str;
  542. }
  543. return S_OK;
  544. }
  545. static HRESULT Date_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  546. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  547. {
  548. DateInstance *date;
  549. TRACE("\n");
  550. if(!(date = date_this(jsthis)))
  551. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  552. if(retv)
  553. num_set_val(retv, date->time);
  554. return S_OK;
  555. }
  556. static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis,
  557. VARIANT *retv, jsexcept_t *ei)
  558. {
  559. static const WCHAR NaNW[] = { 'N','a','N',0 };
  560. static const WCHAR formatADW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ',
  561. '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 };
  562. static const WCHAR formatBCW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ','B','.','C','.',' ',
  563. '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 };
  564. static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1,
  565. LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4,
  566. LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 };
  567. static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
  568. LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
  569. LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
  570. LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
  571. LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
  572. LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
  573. BOOL formatAD = TRUE;
  574. BSTR week, month;
  575. DateInstance *date;
  576. BSTR date_str;
  577. int len, size, year, day;
  578. DWORD lcid_en, week_id, month_id;
  579. if(!(date = date_this(jsthis)))
  580. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  581. if(isnan(date->time)) {
  582. if(retv) {
  583. V_VT(retv) = VT_BSTR;
  584. V_BSTR(retv) = SysAllocString(NaNW);
  585. if(!V_BSTR(retv))
  586. return E_OUTOFMEMORY;
  587. }
  588. return S_OK;
  589. }
  590. if(retv) {
  591. len = 17;
  592. lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
  593. week_id = week_ids[(int)week_day(date->time)];
  594. size = GetLocaleInfoW(lcid_en, week_id, NULL, 0);
  595. week = SysAllocStringLen(NULL, size);
  596. if(!week)
  597. return E_OUTOFMEMORY;
  598. GetLocaleInfoW(lcid_en, week_id, week, size);
  599. len += size-1;
  600. month_id = month_ids[(int)month_from_time(date->time)];
  601. size = GetLocaleInfoW(lcid_en, month_id, NULL, 0);
  602. month = SysAllocStringLen(NULL, size);
  603. if(!month) {
  604. SysFreeString(week);
  605. return E_OUTOFMEMORY;
  606. }
  607. GetLocaleInfoW(lcid_en, month_id, month, size);
  608. len += size-1;
  609. year = year_from_time(date->time);
  610. if(year<0)
  611. year = -year+1;
  612. do {
  613. year /= 10;
  614. len++;
  615. } while(year);
  616. year = year_from_time(date->time);
  617. if(year<0) {
  618. formatAD = FALSE;
  619. year = -year+1;
  620. len += 5;
  621. }
  622. day = date_from_time(date->time);
  623. do {
  624. day /= 10;
  625. len++;
  626. } while(day);
  627. day = date_from_time(date->time);
  628. date_str = SysAllocStringLen(NULL, len);
  629. if(!date_str) {
  630. SysFreeString(week);
  631. SysFreeString(month);
  632. return E_OUTOFMEMORY;
  633. }
  634. sprintfW(date_str, formatAD?formatADW:formatBCW, week, day, month, year,
  635. (int)hour_from_time(date->time), (int)min_from_time(date->time),
  636. (int)sec_from_time(date->time));
  637. SysFreeString(week);
  638. SysFreeString(month);
  639. V_VT(retv) = VT_BSTR;
  640. V_BSTR(retv) = date_str;
  641. }
  642. return S_OK;
  643. }
  644. /* ECMA-262 3rd Edition 15.9.5.42 */
  645. static HRESULT Date_toUTCString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  646. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  647. {
  648. TRACE("\n");
  649. return create_utc_string(ctx, jsthis, retv, ei);
  650. }
  651. static HRESULT Date_toGMTString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  652. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  653. {
  654. TRACE("\n");
  655. return create_utc_string(ctx, jsthis, retv, ei);
  656. }
  657. /* ECMA-262 3rd Edition 15.9.5.3 */
  658. static HRESULT dateobj_to_date_string(DateInstance *date, VARIANT *retv)
  659. {
  660. static const WCHAR NaNW[] = { 'N','a','N',0 };
  661. static const WCHAR formatADW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',0 };
  662. static const WCHAR formatBCW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',' ','B','.','C','.',0 };
  663. static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1,
  664. LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4,
  665. LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 };
  666. static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
  667. LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
  668. LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
  669. LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
  670. LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
  671. LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
  672. BOOL formatAD = TRUE;
  673. BSTR week, month;
  674. BSTR date_str;
  675. DOUBLE time;
  676. int len, size, year, day;
  677. DWORD lcid_en, week_id, month_id;
  678. if(isnan(date->time)) {
  679. if(retv) {
  680. V_VT(retv) = VT_BSTR;
  681. V_BSTR(retv) = SysAllocString(NaNW);
  682. if(!V_BSTR(retv))
  683. return E_OUTOFMEMORY;
  684. }
  685. return S_OK;
  686. }
  687. time = local_time(date->time, date);
  688. if(retv) {
  689. len = 5;
  690. lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
  691. week_id = week_ids[(int)week_day(time)];
  692. size = GetLocaleInfoW(lcid_en, week_id, NULL, 0);
  693. week = SysAllocStringLen(NULL, size);
  694. if(!week)
  695. return E_OUTOFMEMORY;
  696. GetLocaleInfoW(lcid_en, week_id, week, size);
  697. len += size-1;
  698. month_id = month_ids[(int)month_from_time(time)];
  699. size = GetLocaleInfoW(lcid_en, month_id, NULL, 0);
  700. month = SysAllocStringLen(NULL, size);
  701. if(!month) {
  702. SysFreeString(week);
  703. return E_OUTOFMEMORY;
  704. }
  705. GetLocaleInfoW(lcid_en, month_id, month, size);
  706. len += size-1;
  707. year = year_from_time(time);
  708. if(year<0)
  709. year = -year+1;
  710. do {
  711. year /= 10;
  712. len++;
  713. } while(year);
  714. year = year_from_time(time);
  715. if(year<0) {
  716. formatAD = FALSE;
  717. year = -year+1;
  718. len += 5;
  719. }
  720. day = date_from_time(time);
  721. do {
  722. day /= 10;
  723. len++;
  724. } while(day);
  725. day = date_from_time(time);
  726. date_str = SysAllocStringLen(NULL, len);
  727. if(!date_str) {
  728. SysFreeString(week);
  729. SysFreeString(month);
  730. return E_OUTOFMEMORY;
  731. }
  732. sprintfW(date_str, formatAD?formatADW:formatBCW, week, month, day, year);
  733. SysFreeString(week);
  734. SysFreeString(month);
  735. V_VT(retv) = VT_BSTR;
  736. V_BSTR(retv) = date_str;
  737. }
  738. return S_OK;
  739. }
  740. static HRESULT Date_toDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  741. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  742. {
  743. DateInstance *date;
  744. if(!(date = date_this(jsthis)))
  745. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  746. return dateobj_to_date_string(date, retv);
  747. }
  748. /* ECMA-262 3rd Edition 15.9.5.4 */
  749. static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  750. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  751. {
  752. static const WCHAR NaNW[] = { 'N','a','N',0 };
  753. static const WCHAR formatW[] = { '%','0','2','d',':','%','0','2','d',':','%','0','2','d',
  754. ' ','U','T','C','%','c','%','0','2','d','%','0','2','d',0 };
  755. static const WCHAR formatUTCW[] = { '%','0','2','d',':','%','0','2','d',
  756. ':','%','0','2','d',' ','U','T','C',0 };
  757. DateInstance *date;
  758. BSTR date_str;
  759. DOUBLE time;
  760. WCHAR sign;
  761. int offset;
  762. TRACE("\n");
  763. if(!(date = date_this(jsthis)))
  764. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  765. if(isnan(date->time)) {
  766. if(retv) {
  767. V_VT(retv) = VT_BSTR;
  768. V_BSTR(retv) = SysAllocString(NaNW);
  769. if(!V_BSTR(retv))
  770. return E_OUTOFMEMORY;
  771. }
  772. return S_OK;
  773. }
  774. time = local_time(date->time, date);
  775. if(retv) {
  776. date_str = SysAllocStringLen(NULL, 17);
  777. if(!date_str)
  778. return E_OUTOFMEMORY;
  779. offset = date->bias +
  780. daylight_saving_ta(time, date);
  781. if(offset < 0) {
  782. sign = '+';
  783. offset = -offset;
  784. }
  785. else sign = '-';
  786. if(offset)
  787. sprintfW(date_str, formatW, (int)hour_from_time(time),
  788. (int)min_from_time(time), (int)sec_from_time(time),
  789. sign, offset/60, offset%60);
  790. else
  791. sprintfW(date_str, formatUTCW, (int)hour_from_time(time),
  792. (int)min_from_time(time), (int)sec_from_time(time));
  793. V_VT(retv) = VT_BSTR;
  794. V_BSTR(retv) = date_str;
  795. }
  796. return S_OK;
  797. }
  798. /* ECMA-262 3rd Edition 15.9.5.6 */
  799. static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  800. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  801. {
  802. static const WCHAR NaNW[] = { 'N','a','N',0 };
  803. SYSTEMTIME st;
  804. DateInstance *date;
  805. BSTR date_str;
  806. int len;
  807. TRACE("\n");
  808. if(!(date = date_this(jsthis)))
  809. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  810. if(isnan(date->time)) {
  811. if(retv) {
  812. V_VT(retv) = VT_BSTR;
  813. V_BSTR(retv) = SysAllocString(NaNW);
  814. if(!V_BSTR(retv))
  815. return E_OUTOFMEMORY;
  816. }
  817. return S_OK;
  818. }
  819. st = create_systemtime(local_time(date->time, date));
  820. if(st.wYear<1601 || st.wYear>9999)
  821. return dateobj_to_date_string(date, retv);
  822. if(retv) {
  823. len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
  824. date_str = SysAllocStringLen(NULL, len);
  825. if(!date_str)
  826. return E_OUTOFMEMORY;
  827. GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, len);
  828. V_VT(retv) = VT_BSTR;
  829. V_BSTR(retv) = date_str;
  830. }
  831. return S_OK;
  832. }
  833. /* ECMA-262 3rd Edition 15.9.5.7 */
  834. static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  835. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  836. {
  837. static const WCHAR NaNW[] = { 'N','a','N',0 };
  838. SYSTEMTIME st;
  839. DateInstance *date;
  840. BSTR date_str;
  841. int len;
  842. TRACE("\n");
  843. if(!(date = date_this(jsthis)))
  844. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  845. if(isnan(date->time)) {
  846. if(retv) {
  847. V_VT(retv) = VT_BSTR;
  848. V_BSTR(retv) = SysAllocString(NaNW);
  849. if(!V_BSTR(retv))
  850. return E_OUTOFMEMORY;
  851. }
  852. return S_OK;
  853. }
  854. st = create_systemtime(local_time(date->time, date));
  855. if(st.wYear<1601 || st.wYear>9999)
  856. return Date_toTimeString(ctx, jsthis, flags, dp, retv, ei, caller);
  857. if(retv) {
  858. len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
  859. date_str = SysAllocStringLen(NULL, len);
  860. if(!date_str)
  861. return E_OUTOFMEMORY;
  862. GetTimeFormatW(ctx->lcid, 0, &st, NULL, date_str, len);
  863. V_VT(retv) = VT_BSTR;
  864. V_BSTR(retv) = date_str;
  865. }
  866. return S_OK;
  867. }
  868. /* ECMA-262 3rd Edition 15.9.5.9 */
  869. static HRESULT Date_getTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  870. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  871. {
  872. DateInstance *date;
  873. TRACE("\n");
  874. if(!(date = date_this(jsthis)))
  875. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  876. if(retv)
  877. num_set_val(retv, date->time);
  878. return S_OK;
  879. }
  880. /* ECMA-262 3rd Edition 15.9.5.10 */
  881. static HRESULT Date_getFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  882. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  883. {
  884. DateInstance *date;
  885. TRACE("\n");
  886. if(!(date = date_this(jsthis)))
  887. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  888. if(retv) {
  889. DOUBLE time = local_time(date->time, date);
  890. num_set_val(retv, year_from_time(time));
  891. }
  892. return S_OK;
  893. }
  894. /* ECMA-262 3rd Edition 15.9.5.11 */
  895. static HRESULT Date_getUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  896. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  897. {
  898. DateInstance *date;
  899. TRACE("\n");
  900. if(!(date = date_this(jsthis)))
  901. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  902. if(retv)
  903. num_set_val(retv, year_from_time(date->time));
  904. return S_OK;
  905. }
  906. /* ECMA-262 3rd Edition 15.9.5.12 */
  907. static HRESULT Date_getMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  908. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  909. {
  910. DateInstance *date;
  911. TRACE("\n");
  912. if(!(date = date_this(jsthis)))
  913. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  914. if(retv) {
  915. DOUBLE time = local_time(date->time, date);
  916. num_set_val(retv, month_from_time(time));
  917. }
  918. return S_OK;
  919. }
  920. /* ECMA-262 3rd Edition 15.9.5.13 */
  921. static HRESULT Date_getUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  922. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  923. {
  924. DateInstance *date;
  925. TRACE("\n");
  926. if(!(date = date_this(jsthis)))
  927. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  928. if(retv)
  929. num_set_val(retv, month_from_time(date->time));
  930. return S_OK;
  931. }
  932. /* ECMA-262 3rd Edition 15.9.5.14 */
  933. static HRESULT Date_getDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  934. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  935. {
  936. DateInstance *date;
  937. TRACE("\n");
  938. if(!(date = date_this(jsthis)))
  939. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  940. if(retv) {
  941. DOUBLE time = local_time(date->time, date);
  942. num_set_val(retv, date_from_time(time));
  943. }
  944. return S_OK;
  945. }
  946. /* ECMA-262 3rd Edition 15.9.5.15 */
  947. static HRESULT Date_getUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  948. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  949. {
  950. DateInstance *date;
  951. TRACE("\n");
  952. if(!(date = date_this(jsthis)))
  953. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  954. if(retv)
  955. num_set_val(retv, date_from_time(date->time));
  956. return S_OK;
  957. }
  958. /* ECMA-262 3rd Edition 15.9.5.16 */
  959. static HRESULT Date_getDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  960. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  961. {
  962. DateInstance *date;
  963. TRACE("\n");
  964. if(!(date = date_this(jsthis)))
  965. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  966. if(retv) {
  967. DOUBLE time = local_time(date->time, date);
  968. num_set_val(retv, week_day(time));
  969. }
  970. return S_OK;
  971. }
  972. /* ECMA-262 3rd Edition 15.9.5.17 */
  973. static HRESULT Date_getUTCDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  974. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  975. {
  976. DateInstance *date;
  977. TRACE("\n");
  978. if(!(date = date_this(jsthis)))
  979. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  980. if(retv)
  981. num_set_val(retv, week_day(date->time));
  982. return S_OK;
  983. }
  984. /* ECMA-262 3rd Edition 15.9.5.18 */
  985. static HRESULT Date_getHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  986. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  987. {
  988. DateInstance *date;
  989. TRACE("\n");
  990. if(!(date = date_this(jsthis)))
  991. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  992. if(retv) {
  993. DOUBLE time = local_time(date->time, date);
  994. num_set_val(retv, hour_from_time(time));
  995. }
  996. return S_OK;
  997. }
  998. /* ECMA-262 3rd Edition 15.9.5.19 */
  999. static HRESULT Date_getUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1000. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1001. {
  1002. DateInstance *date;
  1003. TRACE("\n");
  1004. if(!(date = date_this(jsthis)))
  1005. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1006. if(retv)
  1007. num_set_val(retv, hour_from_time(date->time));
  1008. return S_OK;
  1009. }
  1010. /* ECMA-262 3rd Edition 15.9.5.20 */
  1011. static HRESULT Date_getMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1012. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1013. {
  1014. DateInstance *date;
  1015. TRACE("\n");
  1016. if(!(date = date_this(jsthis)))
  1017. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1018. if(retv) {
  1019. DOUBLE time = local_time(date->time, date);
  1020. num_set_val(retv, min_from_time(time));
  1021. }
  1022. return S_OK;
  1023. }
  1024. /* ECMA-262 3rd Edition 15.9.5.21 */
  1025. static HRESULT Date_getUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1026. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1027. {
  1028. DateInstance *date;
  1029. TRACE("\n");
  1030. if(!(date = date_this(jsthis)))
  1031. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1032. if(retv)
  1033. num_set_val(retv, min_from_time(date->time));
  1034. return S_OK;
  1035. }
  1036. /* ECMA-262 3rd Edition 15.9.5.22 */
  1037. static HRESULT Date_getSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1038. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1039. {
  1040. DateInstance *date;
  1041. TRACE("\n");
  1042. if(!(date = date_this(jsthis)))
  1043. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1044. if(retv) {
  1045. DOUBLE time = local_time(date->time, date);
  1046. num_set_val(retv, sec_from_time(time));
  1047. }
  1048. return S_OK;
  1049. }
  1050. /* ECMA-262 3rd Edition 15.9.5.23 */
  1051. static HRESULT Date_getUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1052. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1053. {
  1054. DateInstance *date;
  1055. TRACE("\n");
  1056. if(!(date = date_this(jsthis)))
  1057. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1058. if(retv)
  1059. num_set_val(retv, sec_from_time(date->time));
  1060. return S_OK;
  1061. }
  1062. /* ECMA-262 3rd Edition 15.9.5.24 */
  1063. static HRESULT Date_getMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1064. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1065. {
  1066. DateInstance *date;
  1067. TRACE("\n");
  1068. if(!(date = date_this(jsthis)))
  1069. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1070. if(retv) {
  1071. DOUBLE time = local_time(date->time, date);
  1072. num_set_val(retv, ms_from_time(time));
  1073. }
  1074. return S_OK;
  1075. }
  1076. /* ECMA-262 3rd Edition 15.9.5.25 */
  1077. static HRESULT Date_getUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1078. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1079. {
  1080. DateInstance *date;
  1081. TRACE("\n");
  1082. if(!(date = date_this(jsthis)))
  1083. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1084. if(retv)
  1085. num_set_val(retv, ms_from_time(date->time));
  1086. return S_OK;
  1087. }
  1088. /* ECMA-262 3rd Edition 15.9.5.26 */
  1089. static HRESULT Date_getTimezoneOffset(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1090. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1091. {
  1092. DateInstance *date;
  1093. TRACE("\n");
  1094. if(!(date = date_this(jsthis)))
  1095. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1096. if(retv)
  1097. num_set_val(retv, floor(
  1098. (date->time-local_time(date->time, date))/MS_PER_MINUTE));
  1099. return S_OK;
  1100. }
  1101. /* ECMA-262 3rd Edition 15.9.5.27 */
  1102. static HRESULT Date_setTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1103. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1104. {
  1105. VARIANT v;
  1106. HRESULT hres;
  1107. DateInstance *date;
  1108. TRACE("\n");
  1109. if(!(date = date_this(jsthis)))
  1110. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1111. if(!arg_cnt(dp))
  1112. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1113. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1114. if(FAILED(hres))
  1115. return hres;
  1116. date->time = time_clip(num_val(&v));
  1117. if(retv)
  1118. num_set_val(retv, date->time);
  1119. return S_OK;
  1120. }
  1121. /* ECMA-262 3rd Edition 15.9.5.28 */
  1122. static HRESULT Date_setMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1123. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1124. {
  1125. VARIANT v;
  1126. HRESULT hres;
  1127. DateInstance *date;
  1128. DOUBLE t;
  1129. TRACE("\n");
  1130. if(!(date = date_this(jsthis)))
  1131. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1132. if(!arg_cnt(dp))
  1133. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1134. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1135. if(FAILED(hres))
  1136. return hres;
  1137. t = local_time(date->time, date);
  1138. t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t),
  1139. sec_from_time(t), num_val(&v)));
  1140. date->time = time_clip(utc(t, date));
  1141. if(retv)
  1142. num_set_val(retv, date->time);
  1143. return S_OK;
  1144. }
  1145. /* ECMA-262 3rd Edition 15.9.5.29 */
  1146. static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1147. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1148. {
  1149. VARIANT v;
  1150. HRESULT hres;
  1151. DateInstance *date;
  1152. DOUBLE t;
  1153. TRACE("\n");
  1154. if(!(date = date_this(jsthis)))
  1155. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1156. if(!arg_cnt(dp))
  1157. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1158. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1159. if(FAILED(hres))
  1160. return hres;
  1161. t = date->time;
  1162. t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t),
  1163. sec_from_time(t), num_val(&v)));
  1164. date->time = time_clip(t);
  1165. if(retv)
  1166. num_set_val(retv, date->time);
  1167. return S_OK;
  1168. }
  1169. /* ECMA-262 3rd Edition 15.9.5.30 */
  1170. static HRESULT Date_setSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1171. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1172. {
  1173. VARIANT v;
  1174. HRESULT hres;
  1175. DateInstance *date;
  1176. DOUBLE t, sec, ms;
  1177. TRACE("\n");
  1178. if(!(date = date_this(jsthis)))
  1179. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1180. if(!arg_cnt(dp))
  1181. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1182. t = local_time(date->time, date);
  1183. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1184. if(FAILED(hres))
  1185. return hres;
  1186. sec = num_val(&v);
  1187. if(arg_cnt(dp) > 1) {
  1188. hres = to_number(ctx, get_arg(dp, 1), ei, &v);
  1189. if(FAILED(hres))
  1190. return hres;
  1191. ms = num_val(&v);
  1192. }
  1193. else ms = ms_from_time(t);
  1194. t = make_date(day(t), make_time(hour_from_time(t),
  1195. min_from_time(t), sec, ms));
  1196. date->time = time_clip(utc(t, date));
  1197. if(retv)
  1198. num_set_val(retv, date->time);
  1199. return S_OK;
  1200. }
  1201. /* ECMA-262 3rd Edition 15.9.5.31 */
  1202. static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1203. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1204. {
  1205. VARIANT v;
  1206. HRESULT hres;
  1207. DateInstance *date;
  1208. DOUBLE t, sec, ms;
  1209. TRACE("\n");
  1210. if(!(date = date_this(jsthis)))
  1211. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1212. if(!arg_cnt(dp))
  1213. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1214. t = date->time;
  1215. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1216. if(FAILED(hres))
  1217. return hres;
  1218. sec = num_val(&v);
  1219. if(arg_cnt(dp) > 1) {
  1220. hres = to_number(ctx, get_arg(dp, 1), ei, &v);
  1221. if(FAILED(hres))
  1222. return hres;
  1223. ms = num_val(&v);
  1224. }
  1225. else ms = ms_from_time(t);
  1226. t = make_date(day(t), make_time(hour_from_time(t),
  1227. min_from_time(t), sec, ms));
  1228. date->time = time_clip(t);
  1229. if(retv)
  1230. num_set_val(retv, date->time);
  1231. return S_OK;
  1232. }
  1233. /* ECMA-262 3rd Edition 15.9.5.33 */
  1234. static HRESULT Date_setMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1235. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1236. {
  1237. VARIANT v;
  1238. HRESULT hres;
  1239. DateInstance *date;
  1240. DOUBLE t, min, sec, ms;
  1241. TRACE("\n");
  1242. if(!(date = date_this(jsthis)))
  1243. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1244. if(!arg_cnt(dp))
  1245. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1246. t = local_time(date->time, date);
  1247. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1248. if(FAILED(hres))
  1249. return hres;
  1250. min = num_val(&v);
  1251. if(arg_cnt(dp) > 1) {
  1252. hres = to_number(ctx, get_arg(dp, 1), ei, &v);
  1253. if(FAILED(hres))
  1254. return hres;
  1255. sec = num_val(&v);
  1256. }
  1257. else sec = sec_from_time(t);
  1258. if(arg_cnt(dp) > 2) {
  1259. hres = to_number(ctx, get_arg(dp, 2), ei, &v);
  1260. if(FAILED(hres))
  1261. return hres;
  1262. ms = num_val(&v);
  1263. }
  1264. else ms = ms_from_time(t);
  1265. t = make_date(day(t), make_time(hour_from_time(t),
  1266. min, sec, ms));
  1267. date->time = time_clip(utc(t, date));
  1268. if(retv)
  1269. num_set_val(retv, date->time);
  1270. return S_OK;
  1271. }
  1272. /* ECMA-262 3rd Edition 15.9.5.34 */
  1273. static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1274. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1275. {
  1276. VARIANT v;
  1277. HRESULT hres;
  1278. DateInstance *date;
  1279. DOUBLE t, min, sec, ms;
  1280. TRACE("\n");
  1281. if(!(date = date_this(jsthis)))
  1282. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1283. if(!arg_cnt(dp))
  1284. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1285. t = date->time;
  1286. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1287. if(FAILED(hres))
  1288. return hres;
  1289. min = num_val(&v);
  1290. if(arg_cnt(dp) > 1) {
  1291. hres = to_number(ctx, get_arg(dp, 1), ei, &v);
  1292. if(FAILED(hres))
  1293. return hres;
  1294. sec = num_val(&v);
  1295. }
  1296. else sec = sec_from_time(t);
  1297. if(arg_cnt(dp) > 2) {
  1298. hres = to_number(ctx, get_arg(dp, 2), ei, &v);
  1299. if(FAILED(hres))
  1300. return hres;
  1301. ms = num_val(&v);
  1302. }
  1303. else ms = ms_from_time(t);
  1304. t = make_date(day(t), make_time(hour_from_time(t),
  1305. min, sec, ms));
  1306. date->time = time_clip(t);
  1307. if(retv)
  1308. num_set_val(retv, date->time);
  1309. return S_OK;
  1310. }
  1311. /* ECMA-262 3rd Edition 15.9.5.35 */
  1312. static HRESULT Date_setHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1313. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1314. {
  1315. VARIANT v;
  1316. HRESULT hres;
  1317. DateInstance *date;
  1318. DOUBLE t, hour, min, sec, ms;
  1319. TRACE("\n");
  1320. if(!(date = date_this(jsthis)))
  1321. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1322. if(!arg_cnt(dp))
  1323. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1324. t = local_time(date->time, date);
  1325. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1326. if(FAILED(hres))
  1327. return hres;
  1328. hour = num_val(&v);
  1329. if(arg_cnt(dp) > 1) {
  1330. hres = to_number(ctx, get_arg(dp, 1), ei, &v);
  1331. if(FAILED(hres))
  1332. return hres;
  1333. min = num_val(&v);
  1334. }
  1335. else min = min_from_time(t);
  1336. if(arg_cnt(dp) > 2) {
  1337. hres = to_number(ctx, get_arg(dp, 2), ei, &v);
  1338. if(FAILED(hres))
  1339. return hres;
  1340. sec = num_val(&v);
  1341. }
  1342. else sec = sec_from_time(t);
  1343. if(arg_cnt(dp) > 3) {
  1344. hres = to_number(ctx, get_arg(dp, 3), ei, &v);
  1345. if(FAILED(hres))
  1346. return hres;
  1347. ms = num_val(&v);
  1348. }
  1349. else ms = ms_from_time(t);
  1350. t = make_date(day(t), make_time(hour, min, sec, ms));
  1351. date->time = time_clip(utc(t, date));
  1352. if(retv)
  1353. num_set_val(retv, date->time);
  1354. return S_OK;
  1355. }
  1356. /* ECMA-262 3rd Edition 15.9.5.36 */
  1357. static HRESULT Date_setUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1358. VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
  1359. {
  1360. DateInstance *date;
  1361. VARIANT v;
  1362. HRESULT hres;
  1363. DOUBLE t, hour, min, sec, ms;
  1364. TRACE("\n");
  1365. if(!(date = date_this(jsthis)))
  1366. return throw_type_error(ctx, ei, IDS_NOT_DATE, NULL);
  1367. if(!arg_cnt(dp))
  1368. return throw_type_error(ctx, ei, IDS_ARG_NOT_OPT, NULL);
  1369. t = date->time;
  1370. hres = to_number(ctx, get_arg(dp, 0), ei, &v);
  1371. if(FAILED(hres))
  1372. return hres;
  1373. hour = num_val(&v);
  1374. if(arg_cnt(dp) > 1) {
  1375. hres = to_number(ctx, get_arg(dp, 1), ei, &v);
  1376. if(FAILED(hres))
  1377. return hres;
  1378. min = num_val(&v);
  1379. }
  1380. else min = min_from_time(t);
  1381. if(arg_cnt(dp) > 2) {
  1382. hres = to_number(ctx, get_arg(dp, 2), ei, &v);
  1383. if(FAILED(hres))
  1384. return hres;
  1385. sec = num_val(&v);
  1386. }
  1387. else sec = sec_from_time(t);
  1388. if(arg_cnt(dp) > 3) {
  1389. hres = to_number(ctx, get_arg(dp, 3), ei, &v);
  1390. if(FAILED(hres))
  1391. return hres;
  1392. ms = num_val(&v);
  1393. }
  1394. else ms = ms_from_time(t);
  1395. t = make_date(day(t), make_time(hour, min, sec, ms));
  1396. date->time = time_clip(t);
  1397. if(retv)
  1398. num_set_val(retv, date->time);
  1399. return S_OK;
  1400. }
  1401. /* ECMA-262 3rd Edition 15.9.5.36 */
  1402. static HRESULT Date_setDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
  1403. VARIAN

Large files files are truncated, but you can click here to view the full file