Something went wrong. Try again.
Reactos
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551/* * Copyright 2008 Jacek Caban for CodeWeavers * Copyright 2009 Piotr Caban * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#ifdef __REACTOS__#include <wine/config.h>#include <wine/port.h>#endif
#include <limits.h>#include <math.h>#include <assert.h>
#include "jscript.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
/* 1601 to 1970 is 369 years plus 89 leap days */#define TIME_EPOCH ((ULONGLONG)(369 * 365 + 89) * 86400 * 1000)
typedef struct { jsdisp_t dispex;
/* ECMA-262 3rd Edition 15.9.1.1 */ DOUBLE time;
LONG bias; SYSTEMTIME standardDate; LONG standardBias; SYSTEMTIME daylightDate; LONG daylightBias;} DateInstance;
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};static const WCHAR toISOStringW[] = {'t','o','I','S','O','S','t','r','i','n','g',0};static const WCHAR toUTCStringW[] = {'t','o','U','T','C','S','t','r','i','n','g',0};static const WCHAR toGMTStringW[] = {'t','o','G','M','T','S','t','r','i','n','g',0};static const WCHAR toDateStringW[] = {'t','o','D','a','t','e','S','t','r','i','n','g',0};static const WCHAR toTimeStringW[] = {'t','o','T','i','m','e','S','t','r','i','n','g',0};static const WCHAR toLocaleDateStringW[] = {'t','o','L','o','c','a','l','e','D','a','t','e','S','t','r','i','n','g',0};static const WCHAR toLocaleTimeStringW[] = {'t','o','L','o','c','a','l','e','T','i','m','e','S','t','r','i','n','g',0};static const WCHAR getTimeW[] = {'g','e','t','T','i','m','e',0};static const WCHAR getFullYearW[] = {'g','e','t','F','u','l','l','Y','e','a','r',0};static const WCHAR getUTCFullYearW[] = {'g','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};static const WCHAR getMonthW[] = {'g','e','t','M','o','n','t','h',0};static const WCHAR getUTCMonthW[] = {'g','e','t','U','T','C','M','o','n','t','h',0};static const WCHAR getDateW[] = {'g','e','t','D','a','t','e',0};static const WCHAR getUTCDateW[] = {'g','e','t','U','T','C','D','a','t','e',0};static const WCHAR getDayW[] = {'g','e','t','D','a','y',0};static const WCHAR getUTCDayW[] = {'g','e','t','U','T','C','D','a','y',0};static const WCHAR getHoursW[] = {'g','e','t','H','o','u','r','s',0};static const WCHAR getUTCHoursW[] = {'g','e','t','U','T','C','H','o','u','r','s',0};static const WCHAR getMinutesW[] = {'g','e','t','M','i','n','u','t','e','s',0};static const WCHAR getUTCMinutesW[] = {'g','e','t','U','T','C','M','i','n','u','t','e','s',0};static const WCHAR getSecondsW[] = {'g','e','t','S','e','c','o','n','d','s',0};static const WCHAR getUTCSecondsW[] = {'g','e','t','U','T','C','S','e','c','o','n','d','s',0};static const WCHAR getMillisecondsW[] = {'g','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0};static const WCHAR getUTCMillisecondsW[] = {'g','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0};static const WCHAR getTimezoneOffsetW[] = {'g','e','t','T','i','m','e','z','o','n','e','O','f','f','s','e','t',0};static const WCHAR setTimeW[] = {'s','e','t','T','i','m','e',0};static const WCHAR setMillisecondsW[] = {'s','e','t','M','i','l','l','i','s','e','c','o','n','d','s',0};static const WCHAR setUTCMillisecondsW[] = {'s','e','t','U','T','C','M','i','l','l','i','s','e','c','o','n','d','s',0};static const WCHAR setSecondsW[] = {'s','e','t','S','e','c','o','n','d','s',0};static const WCHAR setUTCSecondsW[] = {'s','e','t','U','T','C','S','e','c','o','n','d','s',0};static const WCHAR setMinutesW[] = {'s','e','t','M','i','n','u','t','e','s',0};static const WCHAR setUTCMinutesW[] = {'s','e','t','U','T','C','M','i','n','u','t','e','s',0};static const WCHAR setHoursW[] = {'s','e','t','H','o','u','r','s',0};static const WCHAR setUTCHoursW[] = {'s','e','t','U','T','C','H','o','u','r','s',0};static const WCHAR setDateW[] = {'s','e','t','D','a','t','e',0};static const WCHAR setUTCDateW[] = {'s','e','t','U','T','C','D','a','t','e',0};static const WCHAR setMonthW[] = {'s','e','t','M','o','n','t','h',0};static const WCHAR setUTCMonthW[] = {'s','e','t','U','T','C','M','o','n','t','h',0};static const WCHAR setFullYearW[] = {'s','e','t','F','u','l','l','Y','e','a','r',0};static const WCHAR setUTCFullYearW[] = {'s','e','t','U','T','C','F','u','l','l','Y','e','a','r',0};static const WCHAR getYearW[] = {'g','e','t','Y','e','a','r',0};static const WCHAR setYearW[] = {'s','e','t','Y','e','a','r',0};
static const WCHAR UTCW[] = {'U','T','C',0};static const WCHAR nowW[] = {'n','o','w',0};static const WCHAR parseW[] = {'p','a','r','s','e',0};
static inline DateInstance *date_from_jsdisp(jsdisp_t *jsdisp){ return CONTAINING_RECORD(jsdisp, DateInstance, dispex);}
static inline DateInstance *date_this(vdisp_t *jsthis){ return is_vclass(jsthis, JSCLASS_DATE) ? date_from_jsdisp(jsthis->u.jsdisp) : NULL;}
/*ECMA-262 3rd Edition 15.9.1.2 */#define MS_PER_DAY 86400000#define MS_PER_HOUR 3600000#define MS_PER_MINUTE 60000
/* ECMA-262 3rd Edition 15.9.1.2 */static inline DOUBLE day(DOUBLE time){ return floor(time / MS_PER_DAY);}
/* ECMA-262 3rd Edition 15.9.1.2 */static inline DOUBLE time_within_day(DOUBLE time){ DOUBLE ret;
ret = fmod(time, MS_PER_DAY); if(ret < 0) ret += MS_PER_DAY;
return ret;}
/* ECMA-262 3rd Edition 15.9.1.3 */static inline DOUBLE days_in_year(DOUBLE year){ int y;
if(year != (int)year) return NAN;
y = year; if(y%4 != 0) return 365; if(y%100 != 0) return 366; if(y%400 != 0) return 365; return 366;}
/* ECMA-262 3rd Edition 15.9.1.3 */static inline DOUBLE day_from_year(DOUBLE year){ if(year != (int)year) return NAN;
return floor(365.0*(year-1970) + floor((year-1969)/4) - floor((year-1901)/100) + floor((year-1601)/400));}
static inline int day_from_month(int month, int in_leap_year){ switch(month) { case 0: return 0; case 1: return 31; case 2: return 59+in_leap_year; case 3: return 90+in_leap_year; case 4: return 120+in_leap_year; case 5: return 151+in_leap_year; case 6: return 181+in_leap_year; case 7: return 212+in_leap_year; case 8: return 243+in_leap_year; case 9: return 273+in_leap_year; case 10: return 304+in_leap_year; default: return 334+in_leap_year; }}
/* ECMA-262 3rd Edition 15.9.1.3 */static inline DOUBLE time_from_year(DOUBLE year){ return MS_PER_DAY*day_from_year(year);}
/* ECMA-262 3rd Edition 15.9.1.3 */static inline DOUBLE year_from_time(DOUBLE time){ int y;
if(isnan(time)) return NAN;
y = 1970 + time/365.25/MS_PER_DAY;
if(time_from_year(y) > time) while(time_from_year(y) > time) y--; else while(time_from_year(y+1)<=time) y++;
return y;}
/* ECMA-262 3rd Edition 15.9.1.3 */static inline int in_leap_year(DOUBLE time){ if(days_in_year(year_from_time(time))==366) return 1; return 0;}
/* ECMA-262 3rd Edition 15.9.1.4 */static inline int day_within_year(DOUBLE time){ return day(time) - day_from_year(year_from_time(time));}
/* ECMA-262 3rd Edition 15.9.1.4 */static inline DOUBLE month_from_time(DOUBLE time){ int ily = in_leap_year(time); int dwy = day_within_year(time);
if(isnan(time)) return NAN;
if(0<=dwy && dwy<31) return 0; if(dwy < 59+ily) return 1; if(dwy < 90+ily) return 2; if(dwy < 120+ily) return 3; if(dwy < 151+ily) return 4; if(dwy < 181+ily) return 5; if(dwy < 212+ily) return 6; if(dwy < 243+ily) return 7; if(dwy < 273+ily) return 8; if(dwy < 304+ily) return 9; if(dwy < 334+ily) return 10; return 11;}
/* ECMA-262 3rd Edition 15.9.1.5 */static inline DOUBLE date_from_time(DOUBLE time){ int dwy = day_within_year(time); int ily = in_leap_year(time); int mft = month_from_time(time);
if(isnan(time)) return NAN;
if(mft==0) return dwy+1; if(mft==1) return dwy-30; if(mft==2) return dwy-58-ily; if(mft==3) return dwy-89-ily; if(mft==4) return dwy-119-ily; if(mft==5) return dwy-150-ily; if(mft==6) return dwy-180-ily; if(mft==7) return dwy-211-ily; if(mft==8) return dwy-242-ily; if(mft==9) return dwy-272-ily; if(mft==10) return dwy-303-ily; return dwy-333-ily;}
/* ECMA-262 3rd Edition 15.9.1.6 */static inline DOUBLE week_day(DOUBLE time){ DOUBLE ret;
if(isnan(time)) return NAN;
ret = fmod(day(time)+4, 7); if(ret<0) ret += 7;
return ret;}
static inline DOUBLE convert_time(int year, SYSTEMTIME st){ DOUBLE time; int set_week_day;
if(st.wMonth == 0) return NAN;
if(st.wYear != 0) year = st.wYear;
time = time_from_year(year); time += (DOUBLE)day_from_month(st.wMonth-1, in_leap_year(time)) * MS_PER_DAY;
if(st.wYear == 0) { set_week_day = st.wDayOfWeek-week_day(time); if(set_week_day < 0) set_week_day += 7; time += set_week_day * MS_PER_DAY;
time += (DOUBLE)(st.wDay-1) * 7 * MS_PER_DAY; if(month_from_time(time) != st.wMonth-1) time -= 7 * MS_PER_DAY; } else time += st.wDay * MS_PER_DAY;
time += st.wHour * MS_PER_HOUR; time += st.wMinute * MS_PER_MINUTE;
return time;}
/* ECMA-262 3rd Edition 15.9.1.9 */static inline DOUBLE daylight_saving_ta(DOUBLE time, DateInstance *date){ int year = year_from_time(time); DOUBLE standardTime, daylightTime;
if(isnan(time)) return 0;
standardTime = convert_time(year, date->standardDate); daylightTime = convert_time(year, date->daylightDate);
if(isnan(standardTime) || isnan(daylightTime)) return 0; else if(standardTime > daylightTime) { if(daylightTime <= time && time < standardTime) return date->daylightBias;
return date->standardBias; } else { if(standardTime <= time && time < daylightTime) return date->standardBias;
return date->daylightBias; }}
/* ECMA-262 3rd Edition 15.9.1.9 */static inline DOUBLE local_time(DOUBLE time, DateInstance *date){ return time - (daylight_saving_ta(time, date)+date->bias)*MS_PER_MINUTE;}
/* ECMA-262 3rd Edition 15.9.1.9 */static inline DOUBLE utc(DOUBLE time, DateInstance *date){ time += date->bias * MS_PER_MINUTE; return time + daylight_saving_ta(time, date)*MS_PER_MINUTE;}
/* ECMA-262 3rd Edition 15.9.1.10 */static inline DOUBLE hour_from_time(DOUBLE time){ DOUBLE ret;
if(isnan(time)) return NAN;
ret = fmod(floor(time/MS_PER_HOUR), 24); if(ret<0) ret += 24;
return ret;}
/* ECMA-262 3rd Edition 15.9.1.10 */static inline DOUBLE min_from_time(DOUBLE time){ DOUBLE ret;
if(isnan(time)) return NAN;
ret = fmod(floor(time/MS_PER_MINUTE), 60); if(ret<0) ret += 60;
return ret;}
/* ECMA-262 3rd Edition 15.9.1.10 */static inline DOUBLE sec_from_time(DOUBLE time){ DOUBLE ret;
if(isnan(time)) return NAN;
ret = fmod(floor(time/1000), 60); if(ret<0) ret += 60;
return ret;}
/* ECMA-262 3rd Edition 15.9.1.10 */static inline DOUBLE ms_from_time(DOUBLE time){ DOUBLE ret;
if(isnan(time)) return NAN;
ret = fmod(time, 1000); if(ret<0) ret += 1000;
return ret;}
/* ECMA-262 3rd Edition 15.9.1.11 */static inline DOUBLE make_time(DOUBLE hour, DOUBLE min, DOUBLE sec, DOUBLE ms){ return hour*MS_PER_HOUR + min*MS_PER_MINUTE + sec*1000 + ms;}
/* ECMA-262 3rd Edition 15.9.1.12 */static inline DOUBLE make_day(DOUBLE year, DOUBLE month, DOUBLE day){ DOUBLE time;
year += floor(month/12);
month = fmod(month, 12); if(month<0) month += 12;
time = time_from_year(year);
day += floor(time / MS_PER_DAY); day += day_from_month(month, in_leap_year(time));
return day-1;}
/* ECMA-262 3rd Edition 15.9.1.13 */static inline DOUBLE make_date(DOUBLE day, DOUBLE time){ return day*MS_PER_DAY + time;}
/* ECMA-262 3rd Edition 15.9.1.14 */static inline DOUBLE time_clip(DOUBLE time){ if(8.64e15 < time || time < -8.64e15) { return NAN; }
return floor(time);}
static double date_now(void){ FILETIME ftime; LONGLONG time;
GetSystemTimeAsFileTime(&ftime); time = ((LONGLONG)ftime.dwHighDateTime << 32) + ftime.dwLowDateTime;
return time/10000 - TIME_EPOCH;}
static SYSTEMTIME create_systemtime(DOUBLE time){ SYSTEMTIME st;
st.wYear = year_from_time(time); st.wMonth = month_from_time(time) + 1; st.wDayOfWeek = week_day(time); st.wDay = date_from_time(time); st.wHour = hour_from_time(time); st.wMinute = min_from_time(time); st.wSecond = sec_from_time(time); st.wMilliseconds = ms_from_time(time);
return st;}
static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset, jsval_t *r){ static const WCHAR formatW[] = { '%','s',' ','%','s',' ','%','d',' ', '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ', 'U','T','C','%','c','%','0','2','d','%','0','2','d',' ','%','d','%','s',0 }; static const WCHAR formatUTCW[] = { '%','s',' ','%','s',' ','%','d',' ', '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ', 'U','T','C',' ','%','d','%','s',0 }; static const WCHAR formatNoOffsetW[] = { '%','s',' ','%','s',' ', '%','d',' ','%','0','2','d',':','%','0','2','d',':', '%','0','2','d',' ','%','d','%','s',0 }; static const WCHAR ADW[] = { 0 }; static const WCHAR BCW[] = { ' ','B','.','C','.',0 };
static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 }; static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
BOOL formatAD = TRUE; WCHAR week[64], month[64]; WCHAR buf[192]; jsstr_t *date_jsstr; int year, day; DWORD lcid_en; WCHAR sign = '-';
if(isnan(time)) { if(r) *r = jsval_string(jsstr_nan()); return S_OK; }
if(r) { lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
week[0] = 0; GetLocaleInfoW(lcid_en, week_ids[(int)week_day(time)], week, ARRAY_SIZE(week));
month[0] = 0; GetLocaleInfoW(lcid_en, month_ids[(int)month_from_time(time)], month, ARRAY_SIZE(month));
year = year_from_time(time); if(year<0) { formatAD = FALSE; year = -year+1; }
day = date_from_time(time);
if(offset < 0) { sign = '+'; offset = -offset; }
if(!show_offset) swprintf(buf, formatNoOffsetW, week, month, day, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), year, formatAD?ADW:BCW); else if(offset) swprintf(buf, formatW, week, month, day, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), sign, offset/60, offset%60, year, formatAD?ADW:BCW); else swprintf(buf, formatUTCW, week, month, day, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), year, formatAD?ADW:BCW);
date_jsstr = jsstr_alloc(buf); if(!date_jsstr) return E_OUTOFMEMORY;
*r = jsval_string(date_jsstr); } return S_OK;}
/* ECMA-262 3rd Edition 15.9.1.2 */static HRESULT dateobj_to_string(DateInstance *date, jsval_t *r){ DOUBLE time; int offset;
time = local_time(date->time, date); offset = date->bias + daylight_saving_ta(time, date);
return date_to_string(time, TRUE, offset, r);}
static HRESULT Date_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
return dateobj_to_string(date, r);}
/* ECMA-262 3rd Edition 15.9.1.5 */static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ SYSTEMTIME st; DateInstance *date; jsstr_t *date_str; int date_len, time_len;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(isnan(date->time)) { if(r) *r = jsval_string(jsstr_nan()); return S_OK; }
st = create_systemtime(local_time(date->time, date));
if(st.wYear<1601 || st.wYear>9999) return dateobj_to_string(date, r);
if(r) { WCHAR *ptr;
date_len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0); time_len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
date_str = jsstr_alloc_buf(date_len+time_len-1, &ptr); if(!date_str) return E_OUTOFMEMORY;
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, ptr, date_len); GetTimeFormatW(ctx->lcid, 0, &st, NULL, ptr+date_len, time_len); ptr[date_len-1] = ' ';
*r = jsval_string(date_str); } return S_OK;}
static HRESULT Date_toISOString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; WCHAR buf[64], *p = buf; double year;
static const WCHAR short_year_formatW[] = {'%','0','4','d',0}; static const WCHAR long_year_formatW[] = {'%','0','6','d',0}; static const WCHAR formatW[] = {'-','%','0','2','d','-','%','0','2','d', 'T','%','0','2','d',':','%','0','2','d',':','%','0','2','d','.','%','0','3','d','Z',0};
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
year = year_from_time(date->time); if(isnan(year) || year > 999999 || year < -999999) { FIXME("year %lf should throw an exception\n", year); return E_FAIL; }
if(year < 0) { *p++ = '-'; p += swprintf(p, long_year_formatW, -(int)year); }else if(year > 9999) { *p++ = '+'; p += swprintf(p, long_year_formatW, (int)year); }else { p += swprintf(p, short_year_formatW, (int)year); }
swprintf(p, formatW, (int)month_from_time(date->time) + 1, (int)date_from_time(date->time), (int)hour_from_time(date->time), (int)min_from_time(date->time), (int)sec_from_time(date->time), (int)ms_from_time(date->time));
if(r) { jsstr_t *ret; if(!(ret = jsstr_alloc(buf))) return E_OUTOFMEMORY; *r = jsval_string(ret); } return S_OK;}
static HRESULT Date_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(date->time); return S_OK;}
static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r){ static const WCHAR formatADW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ', '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 }; static const WCHAR formatBCW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ','B','.','C','.',' ', '%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 };
static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 }; static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
BOOL formatAD = TRUE; WCHAR week[64], month[64]; WCHAR buf[192]; DateInstance *date; jsstr_t *date_str; int year, day; DWORD lcid_en;
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(isnan(date->time)) { if(r) *r = jsval_string(jsstr_nan()); return S_OK; }
if(r) { lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
week[0] = 0; GetLocaleInfoW(lcid_en, week_ids[(int)week_day(date->time)], week, ARRAY_SIZE(week));
month[0] = 0; GetLocaleInfoW(lcid_en, month_ids[(int)month_from_time(date->time)], month, ARRAY_SIZE(month));
year = year_from_time(date->time); if(year<0) { formatAD = FALSE; year = -year+1; }
day = date_from_time(date->time);
swprintf(buf, formatAD ? formatADW : formatBCW, week, day, month, year, (int)hour_from_time(date->time), (int)min_from_time(date->time), (int)sec_from_time(date->time));
date_str = jsstr_alloc(buf); if(!date_str) return E_OUTOFMEMORY;
*r = jsval_string(date_str); } return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.42 */static HRESULT Date_toUTCString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ TRACE("\n"); return create_utc_string(ctx, jsthis, r);}
static HRESULT Date_toGMTString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ TRACE("\n"); return create_utc_string(ctx, jsthis, r);}
/* ECMA-262 3rd Edition 15.9.5.3 */static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r){ static const WCHAR formatADW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',0 }; static const WCHAR formatBCW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',' ','B','.','C','.',0 };
static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6 }; static const DWORD month_ids[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
BOOL formatAD = TRUE; WCHAR week[64], month[64]; WCHAR buf[192]; jsstr_t *date_str; DOUBLE time; int year, day; DWORD lcid_en;
if(isnan(date->time)) { if(r) *r = jsval_string(jsstr_nan()); return S_OK; }
time = local_time(date->time, date);
if(r) { lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
week[0] = 0; GetLocaleInfoW(lcid_en, week_ids[(int)week_day(time)], week, ARRAY_SIZE(week));
month[0] = 0; GetLocaleInfoW(lcid_en, month_ids[(int)month_from_time(time)], month, ARRAY_SIZE(month));
year = year_from_time(time); if(year<0) { formatAD = FALSE; year = -year+1; }
day = date_from_time(time);
swprintf(buf, formatAD ? formatADW : formatBCW, week, month, day, year);
date_str = jsstr_alloc(buf); if(!date_str) return E_OUTOFMEMORY;
*r = jsval_string(date_str); } return S_OK;}
static HRESULT Date_toDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
return dateobj_to_date_string(date, r);}
/* ECMA-262 3rd Edition 15.9.5.4 */static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ static const WCHAR formatW[] = { '%','0','2','d',':','%','0','2','d',':','%','0','2','d', ' ','U','T','C','%','c','%','0','2','d','%','0','2','d',0 }; static const WCHAR formatUTCW[] = { '%','0','2','d',':','%','0','2','d', ':','%','0','2','d',' ','U','T','C',0 }; DateInstance *date; jsstr_t *date_str; WCHAR buf[32]; DOUBLE time; WCHAR sign; int offset;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(isnan(date->time)) { if(r) *r = jsval_string(jsstr_nan()); return S_OK; }
time = local_time(date->time, date);
if(r) { offset = date->bias + daylight_saving_ta(time, date);
if(offset < 0) { sign = '+'; offset = -offset; } else sign = '-';
if(offset) swprintf(buf, formatW, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), sign, offset/60, offset%60); else swprintf(buf, formatUTCW, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time));
date_str = jsstr_alloc(buf); if(!date_str) return E_OUTOFMEMORY;
*r = jsval_string(date_str); } return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.6 */static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ SYSTEMTIME st; DateInstance *date; jsstr_t *date_str; int len;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(isnan(date->time)) { if(r) *r = jsval_string(jsstr_nan()); return S_OK; }
st = create_systemtime(local_time(date->time, date));
if(st.wYear<1601 || st.wYear>9999) return dateobj_to_date_string(date, r);
if(r) { WCHAR *ptr;
len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0); date_str = jsstr_alloc_buf(len-1, &ptr); if(!date_str) return E_OUTOFMEMORY; GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, ptr, len);
*r = jsval_string(date_str); } return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.7 */static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ SYSTEMTIME st; DateInstance *date; jsstr_t *date_str; int len;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(isnan(date->time)) { if(r) *r = jsval_string(jsstr_nan()); return S_OK; }
st = create_systemtime(local_time(date->time, date));
if(st.wYear<1601 || st.wYear>9999) return Date_toTimeString(ctx, jsthis, flags, argc, argv, r);
if(r) { WCHAR *ptr;
len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0); date_str = jsstr_alloc_buf(len-1, &ptr); if(!date_str) return E_OUTOFMEMORY; GetTimeFormatW(ctx->lcid, 0, &st, NULL, ptr, len);
*r = jsval_string(date_str); } return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.9 */static HRESULT Date_getTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.10 */static HRESULT Date_getFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) { DOUBLE time = local_time(date->time, date);
*r = jsval_number(year_from_time(time)); } return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.11 */static HRESULT Date_getUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(year_from_time(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.12 */static HRESULT Date_getMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(month_from_time(local_time(date->time, date))); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.13 */static HRESULT Date_getUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(month_from_time(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.14 */static HRESULT Date_getDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(date_from_time(local_time(date->time, date))); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.15 */static HRESULT Date_getUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(date_from_time(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.16 */static HRESULT Date_getDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(week_day(local_time(date->time, date))); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.17 */static HRESULT Date_getUTCDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(week_day(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.18 */static HRESULT Date_getHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(hour_from_time(local_time(date->time, date))); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.19 */static HRESULT Date_getUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(hour_from_time(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.20 */static HRESULT Date_getMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(min_from_time(local_time(date->time, date))); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.21 */static HRESULT Date_getUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(min_from_time(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.22 */static HRESULT Date_getSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(sec_from_time(local_time(date->time, date))); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.23 */static HRESULT Date_getUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(sec_from_time(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.24 */static HRESULT Date_getMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(ms_from_time(local_time(date->time, date))); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.25 */static HRESULT Date_getUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(ms_from_time(date->time)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.26 */static HRESULT Date_getTimezoneOffset(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(r) *r = jsval_number(floor((date->time-local_time(date->time, date))/MS_PER_MINUTE)); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.27 */static HRESULT Date_setTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ double n; HRESULT hres; DateInstance *date;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
hres = to_number(ctx, argv[0], &n); if(FAILED(hres)) return hres;
date->time = time_clip(n);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.28 */static HRESULT Date_setMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double n, t; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
hres = to_number(ctx, argv[0], &n); if(FAILED(hres)) return hres;
t = local_time(date->time, date); t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t), sec_from_time(t), n)); date->time = time_clip(utc(t, date));
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.29 */static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double n, t; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
hres = to_number(ctx, argv[0], &n); if(FAILED(hres)) return hres;
t = date->time; t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t), sec_from_time(t), n)); date->time = time_clip(t);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.30 */static HRESULT Date_setSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, sec, ms; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = local_time(date->time, date);
hres = to_number(ctx, argv[0], &sec); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &ms); if(FAILED(hres)) return hres; }else { ms = ms_from_time(t); }
t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t), sec, ms)); date->time = time_clip(utc(t, date));
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.31 */static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, sec, ms; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = date->time;
hres = to_number(ctx, argv[0], &sec); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &ms); if(FAILED(hres)) return hres; }else { ms = ms_from_time(t); }
t = make_date(day(t), make_time(hour_from_time(t), min_from_time(t), sec, ms)); date->time = time_clip(t);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.33 */static HRESULT Date_setMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, min, sec, ms; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = local_time(date->time, date);
hres = to_number(ctx, argv[0], &min); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &sec); if(FAILED(hres)) return hres; }else { sec = sec_from_time(t); }
if(argc > 2) { hres = to_number(ctx, argv[2], &ms); if(FAILED(hres)) return hres; }else { ms = ms_from_time(t); }
t = make_date(day(t), make_time(hour_from_time(t), min, sec, ms)); date->time = time_clip(utc(t, date));
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.34 */static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, min, sec, ms; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = date->time;
hres = to_number(ctx, argv[0], &min); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &sec); if(FAILED(hres)) return hres; }else { sec = sec_from_time(t); }
if(argc > 2) { hres = to_number(ctx, argv[2], &ms); if(FAILED(hres)) return hres; }else { ms = ms_from_time(t); }
t = make_date(day(t), make_time(hour_from_time(t), min, sec, ms)); date->time = time_clip(t);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.35 */static HRESULT Date_setHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, hour, min, sec, ms; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = local_time(date->time, date);
hres = to_number(ctx, argv[0], &hour); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &min); if(FAILED(hres)) return hres; }else { min = min_from_time(t); }
if(argc > 2) { hres = to_number(ctx, argv[2], &sec); if(FAILED(hres)) return hres; }else { sec = sec_from_time(t); }
if(argc > 3) { hres = to_number(ctx, argv[3], &ms); if(FAILED(hres)) return hres; }else { ms = ms_from_time(t); }
t = make_date(day(t), make_time(hour, min, sec, ms)); date->time = time_clip(utc(t, date));
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.36 */static HRESULT Date_setUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, hour, min, sec, ms; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = date->time;
hres = to_number(ctx, argv[0], &hour); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &min); if(FAILED(hres)) return hres; }else { min = min_from_time(t); }
if(argc > 2) { hres = to_number(ctx, argv[2], &sec); if(FAILED(hres)) return hres; }else { sec = sec_from_time(t); }
if(argc > 3) { hres = to_number(ctx, argv[3], &ms); if(FAILED(hres)) return hres; }else { ms = ms_from_time(t); }
t = make_date(day(t), make_time(hour, min, sec, ms)); date->time = time_clip(t);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.36 */static HRESULT Date_setDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, n; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
hres = to_number(ctx, argv[0], &n); if(FAILED(hres)) return hres;
t = local_time(date->time, date); t = make_date(make_day(year_from_time(t), month_from_time(t), n), time_within_day(t)); date->time = time_clip(utc(t, date));
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.37 */static HRESULT Date_setUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, n; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
hres = to_number(ctx, argv[0], &n); if(FAILED(hres)) return hres;
t = date->time; t = make_date(make_day(year_from_time(t), month_from_time(t), n), time_within_day(t)); date->time = time_clip(t);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.38 */static HRESULT Date_setMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; DOUBLE t, month, ddate; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = local_time(date->time, date);
hres = to_number(ctx, argv[0], &month); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &ddate); if(FAILED(hres)) return hres; }else { ddate = date_from_time(t); }
t = make_date(make_day(year_from_time(t), month, ddate), time_within_day(t)); date->time = time_clip(utc(t, date));
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.39 */static HRESULT Date_setUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, month, ddate; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = date->time;
hres = to_number(ctx, argv[0], &month); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &ddate); if(FAILED(hres)) return hres; }else { ddate = date_from_time(t); }
t = make_date(make_day(year_from_time(t), month, ddate), time_within_day(t)); date->time = time_clip(t);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.40 */static HRESULT Date_setFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, year, month, ddate; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = local_time(date->time, date);
hres = to_number(ctx, argv[0], &year); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &month); if(FAILED(hres)) return hres; }else { month = month_from_time(t); }
if(argc > 2) { hres = to_number(ctx, argv[2], &ddate); if(FAILED(hres)) return hres; }else { ddate = date_from_time(t); }
t = make_date(make_day(year, month, ddate), time_within_day(t)); date->time = time_clip(utc(t, date));
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition 15.9.5.41 */static HRESULT Date_setUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; double t, year, month, ddate; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = date->time;
hres = to_number(ctx, argv[0], &year); if(FAILED(hres)) return hres;
if(argc > 1) { hres = to_number(ctx, argv[1], &month); if(FAILED(hres)) return hres; }else { month = month_from_time(t); }
if(argc > 2) { hres = to_number(ctx, argv[2], &ddate); if(FAILED(hres)) return hres; }else { ddate = date_from_time(t); }
t = make_date(make_day(year, month, ddate), time_within_day(t)); date->time = time_clip(t);
if(r) *r = jsval_number(date->time); return S_OK;}
/* ECMA-262 3rd Edition B2.4 */static HRESULT Date_getYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; DOUBLE t, year;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
t = local_time(date->time, date); if(isnan(t)) { if(r) *r = jsval_number(NAN); return S_OK; }
year = year_from_time(t); if(r) *r = jsval_number((1900<=year && year<2000)?year-1900:year); return S_OK;}
/* ECMA-262 3rd Edition B2.5 */static HRESULT Date_setYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ DateInstance *date; DOUBLE t, year; HRESULT hres;
TRACE("\n");
if(!(date = date_this(jsthis))) return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
if(!argc) return throw_type_error(ctx, JS_E_MISSING_ARG, NULL);
t = local_time(date->time, date);
hres = to_number(ctx, argv[0], &year); if(FAILED(hres)) return hres;
if(isnan(year)) { date->time = year; if(r) *r = jsval_number(NAN); return S_OK; }
year = year >= 0.0 ? floor(year) : -floor(-year); if(-1.0 < year && year < 100.0) year += 1900.0;
date->time = time_clip(utc(make_date(make_day(year, month_from_time(t), date_from_time(t)), time_within_day(t)), date));
if(r) *r = jsval_number(date->time); return S_OK;}
static HRESULT Date_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r){ TRACE("\n");
return dateobj_to_string(date_from_jsdisp(jsthis), r);}
static const builtin_prop_t Date_props[] = { {getDateW, Date_getDate, PROPF_METHOD}, {getDayW, Date_getDay, PROPF_METHOD}, {getFullYearW, Date_getFullYear, PROPF_METHOD}, {getHoursW, Date_getHours, PROPF_METHOD}, {getMillisecondsW, Date_getMilliseconds, PROPF_METHOD}, {getMinutesW, Date_getMinutes, PROPF_METHOD}, {getMonthW, Date_getMonth, PROPF_METHOD}, {getSecondsW, Date_getSeconds, PROPF_METHOD}, {getTimeW, Date_getTime, PROPF_METHOD}, {getTimezoneOffsetW, Date_getTimezoneOffset, PROPF_METHOD}, {getUTCDateW, Date_getUTCDate, PROPF_METHOD}, {getUTCDayW, Date_getUTCDay, PROPF_METHOD}, {getUTCFullYearW, Date_getUTCFullYear, PROPF_METHOD}, {getUTCHoursW, Date_getUTCHours, PROPF_METHOD}, {getUTCMillisecondsW, Date_getUTCMilliseconds, PROPF_METHOD}, {getUTCMinutesW, Date_getUTCMinutes, PROPF_METHOD}, {getUTCMonthW, Date_getUTCMonth, PROPF_METHOD}, {getUTCSecondsW, Date_getUTCSeconds, PROPF_METHOD}, {getYearW, Date_getYear, PROPF_METHOD}, {setDateW, Date_setDate, PROPF_METHOD|1}, {setFullYearW, Date_setFullYear, PROPF_METHOD|3}, {setHoursW, Date_setHours, PROPF_METHOD|4}, {setMillisecondsW, Date_setMilliseconds, PROPF_METHOD|1}, {setMinutesW, Date_setMinutes, PROPF_METHOD|3}, {setMonthW, Date_setMonth, PROPF_METHOD|2}, {setSecondsW, Date_setSeconds, PROPF_METHOD|2}, {setTimeW, Date_setTime, PROPF_METHOD|1}, {setUTCDateW, Date_setUTCDate, PROPF_METHOD|1}, {setUTCFullYearW, Date_setUTCFullYear, PROPF_METHOD|3}, {setUTCHoursW, Date_setUTCHours, PROPF_METHOD|4}, {setUTCMillisecondsW, Date_setUTCMilliseconds, PROPF_METHOD|1}, {setUTCMinutesW, Date_setUTCMinutes, PROPF_METHOD|3}, {setUTCMonthW, Date_setUTCMonth, PROPF_METHOD|2}, {setUTCSecondsW, Date_setUTCSeconds, PROPF_METHOD|2}, {setYearW, Date_setYear, PROPF_METHOD|1}, {toDateStringW, Date_toDateString, PROPF_METHOD}, {toGMTStringW, Date_toGMTString, PROPF_METHOD}, {toISOStringW, Date_toISOString, PROPF_METHOD|PROPF_ES5}, {toLocaleDateStringW, Date_toLocaleDateString, PROPF_METHOD}, {toLocaleStringW, Date_toLocaleString, PROPF_METHOD}, {toLocaleTimeStringW, Date_toLocaleTimeString, PROPF_METHOD}, {toStringW, Date_toString, PROPF_METHOD}, {toTimeStringW, Date_toTimeString, PROPF_METHOD}, {toUTCStringW, Date_toUTCString, PROPF_METHOD}, {valueOfW, Date_valueOf, PROPF_METHOD},};
static const builtin_info_t Date_info = { JSCLASS_DATE, {NULL, NULL,0, Date_get_value}, ARRAY_SIZE(Date_props), Date_props, NULL, NULL};
static const builtin_info_t DateInst_info = { JSCLASS_DATE, {NULL, NULL,0, Date_get_value}, 0, NULL, NULL, NULL};
static HRESULT create_date(script_ctx_t *ctx, jsdisp_t *object_prototype, DOUBLE time, jsdisp_t **ret){ DateInstance *date; HRESULT hres; TIME_ZONE_INFORMATION tzi;
GetTimeZoneInformation(&tzi);
date = heap_alloc_zero(sizeof(DateInstance)); if(!date) return E_OUTOFMEMORY;
if(object_prototype) hres = init_dispex(&date->dispex, ctx, &Date_info, object_prototype); else hres = init_dispex_from_constr(&date->dispex, ctx, &DateInst_info, ctx->date_constr); if(FAILED(hres)) { heap_free(date); return hres; }
date->time = time; date->bias = tzi.Bias; date->standardDate = tzi.StandardDate; date->standardBias = tzi.StandardBias; date->daylightDate = tzi.DaylightDate; date->daylightBias = tzi.DaylightBias;
*ret = &date->dispex; return S_OK;}
static inline HRESULT date_parse(jsstr_t *input_str, double *ret) { static const DWORD string_ids[] = { LOCALE_SMONTHNAME12, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME3, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME1, LOCALE_SDAYNAME7, LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, LOCALE_SDAYNAME5, LOCALE_SDAYNAME6 }; WCHAR *strings[ARRAY_SIZE(string_ids)]; WCHAR *parse; int input_len, parse_len = 0, nest_level = 0, i, size; int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0; int ms = 0, offset = 0, hour_adjust = 0; BOOL set_year = FALSE, set_month = FALSE, set_day = FALSE, set_hour = FALSE; BOOL set_offset = FALSE, set_era = FALSE, ad = TRUE, set_am = FALSE, am = TRUE; BOOL set_hour_adjust = TRUE; TIME_ZONE_INFORMATION tzi; const WCHAR *input; DateInstance di; DWORD lcid_en;
input_len = jsstr_length(input_str); input = jsstr_flatten(input_str); if(!input) return E_OUTOFMEMORY;
for(i=0; i<input_len; i++) { if(input[i] == '(') nest_level++; else if(input[i] == ')') { nest_level--; if(nest_level<0) { *ret = NAN; return S_OK; } } else if(!nest_level) parse_len++; }
parse = heap_alloc((parse_len+1)*sizeof(WCHAR)); if(!parse) return E_OUTOFMEMORY; nest_level = 0; parse_len = 0; for(i=0; i<input_len; i++) { if(input[i] == '(') nest_level++; else if(input[i] == ')') nest_level--; else if(!nest_level) parse[parse_len++] = towupper(input[i]); } parse[parse_len] = 0;
GetTimeZoneInformation(&tzi); di.bias = tzi.Bias; di.standardDate = tzi.StandardDate; di.standardBias = tzi.StandardBias; di.daylightDate = tzi.DaylightDate; di.daylightBias = tzi.DaylightBias;
/* FIXME: Cache strings */ lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT); for(i=0; i<ARRAY_SIZE(string_ids); i++) { size = GetLocaleInfoW(lcid_en, string_ids[i], NULL, 0); strings[i] = heap_alloc((size+1)*sizeof(WCHAR)); if(!strings[i]) { i--; while(i-- >= 0) heap_free(strings[i]); heap_free(parse); return E_OUTOFMEMORY; } GetLocaleInfoW(lcid_en, string_ids[i], strings[i], size); }
for(i=0; i<parse_len;) { while(iswspace(parse[i])) i++; if(parse[i] == ',') { while(parse[i] == ',') i++; continue; }
if(parse[i]>='0' && parse[i]<='9') { int tmp = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++; while(iswspace(parse[i])) i++;
if(parse[i] == ':') { /* Time */ if(set_hour) break; set_hour = TRUE;
hour = tmp;
while(parse[i] == ':') i++; while(iswspace(parse[i])) i++; if(parse[i]>='0' && parse[i]<='9') { min = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++; }
while(iswspace(parse[i])) i++; while(parse[i] == ':') i++; while(iswspace(parse[i])) i++; if(parse[i]>='0' && parse[i]<='9') { sec = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++; } } else if(parse[i]=='-' || parse[i]=='/') { /* Short or long date */ if(set_day || set_month || set_year) break; set_day = TRUE; set_month = TRUE; set_year = TRUE;
month = tmp-1;
while(iswspace(parse[i])) i++; while(parse[i]=='-' || parse[i]=='/') i++; while(iswspace(parse[i])) i++; if(parse[i]<'0' || parse[i]>'9') break; day = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++;
while(parse[i]=='-' || parse[i]=='/') i++; while(iswspace(parse[i])) i++; if(parse[i]<'0' || parse[i]>'9') break; year = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++;
if(tmp >= 70){ /* long date */ month = day - 1; day = year; year = tmp; } } else if(tmp<0) break; else if(tmp<70) { /* Day */ if(set_day) break; set_day = TRUE; day = tmp; } else { /* Year */ if(set_year) break; set_year = TRUE; year = tmp; } } else if(parse[i]=='+' || parse[i]=='-') { /* Timezone offset */ BOOL positive = TRUE;
if(set_offset && set_hour_adjust) break; set_offset = TRUE; set_hour_adjust = FALSE;
if(parse[i] == '-') positive = FALSE;
i++; while(iswspace(parse[i])) i++; if(parse[i]<'0' || parse[i]>'9') break; offset = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++;
if(offset<24) offset *= 60; else offset = (offset/100)*60 + offset%100;
if(positive) offset = -offset;
} else { if(parse[i]<'A' || parse[i]>'Z') break; else if(parse[i]=='B' && (parse[i+1]=='C' || (parse[i+1]=='.' && parse[i+2]=='C'))) { /* AD/BC */ if(set_era) break; set_era = TRUE; ad = FALSE;
i++; if(parse[i] == '.') i++; i++; if(parse[i] == '.') i++; } else if(parse[i]=='A' && (parse[i+1]=='D' || (parse[i+1]=='.' && parse[i+2]=='D'))) { /* AD/BC */ if(set_era) break; set_era = TRUE;
i++; if(parse[i] == '.') i++; i++; if(parse[i] == '.') i++; } else if(parse[i+1]<'A' || parse[i+1]>'Z') { /* Timezone */ if(set_offset) break; set_offset = TRUE;
if(parse[i] <= 'I') hour_adjust = parse[i]-'A'+2; else if(parse[i] == 'J') break; else if(parse[i] <= 'M') hour_adjust = parse[i]-'K'+11; else if(parse[i] <= 'Y') hour_adjust = parse[i]-'N'; else hour_adjust = 1;
i++; if(parse[i] == '.') i++; } else if(parse[i]=='A' && parse[i+1]=='M') { /* AM/PM */ if(set_am) break; set_am = TRUE; am = TRUE; i += 2; } else if(parse[i]=='P' && parse[i+1]=='M') { /* AM/PM */ if(set_am) break; set_am = TRUE; am = FALSE; i += 2; } else if((parse[i]=='U' && parse[i+1]=='T' && parse[i+2]=='C') || (parse[i]=='G' && parse[i+1]=='M' && parse[i+2]=='T')) { /* Timezone */ if(set_offset) break; set_offset = TRUE; set_hour_adjust = FALSE;
i += 3; } else { /* Month or garbage */ unsigned int j;
for(size=i; parse[size]>='A' && parse[size]<='Z'; size++); size -= i;
for(j=0; j<ARRAY_SIZE(string_ids); j++) if(!_wcsnicmp(&parse[i], strings[j], size)) break;
if(j < 12) { if(set_month) break; set_month = TRUE; month = 11-j; } else if(j == ARRAY_SIZE(string_ids)) break;
i += size; } } }
if(i == parse_len && set_year && set_month && set_day && (!set_am || hour<13)) { if(set_am) { if(hour == 12) hour = 0; if(!am) hour += 12; }
if(!ad) year = -year+1; else if(year<100) year += 1900;
*ret = time_clip(make_date(make_day(year, month, day), make_time(hour+hour_adjust, min, sec, ms)) + offset*MS_PER_MINUTE);
if(set_hour_adjust) *ret = utc(*ret, &di); }else { *ret = NAN; }
for(i=0; i<ARRAY_SIZE(string_ids); i++) heap_free(strings[i]); heap_free(parse);
return S_OK;}
static HRESULT DateConstr_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ jsstr_t *parse_str; double n; HRESULT hres;
TRACE("\n");
if(!argc) { if(r) *r = jsval_number(NAN); return S_OK; }
hres = to_string(ctx, argv[0], &parse_str); if(FAILED(hres)) return hres;
hres = date_parse(parse_str, &n); jsstr_release(parse_str); if(FAILED(hres)) return hres;
*r = jsval_number(n); return S_OK;}
static HRESULT date_utc(script_ctx_t *ctx, unsigned argc, jsval_t *argv, double *ret){ double year, month, vdate, hours, minutes, seconds, ms; HRESULT hres;
TRACE("\n");
if(argc) { hres = to_number(ctx, argv[0], &year); if(FAILED(hres)) return hres; if(0 <= year && year <= 99) year += 1900; }else { year = 1900; }
if(argc>1) { hres = to_number(ctx, argv[1], &month); if(FAILED(hres)) return hres; }else { month = 0; }
if(argc>2) { hres = to_number(ctx, argv[2], &vdate); if(FAILED(hres)) return hres; }else { vdate = 1; }
if(argc>3) { hres = to_number(ctx, argv[3], &hours); if(FAILED(hres)) return hres; }else { hours = 0; }
if(argc>4) { hres = to_number(ctx, argv[4], &minutes); if(FAILED(hres)) return hres; }else { minutes = 0; }
if(argc>5) { hres = to_number(ctx, argv[5], &seconds); if(FAILED(hres)) return hres; }else { seconds = 0; }
if(argc>6) { hres = to_number(ctx, argv[6], &ms); if(FAILED(hres)) return hres; } else { ms = 0; }
*ret = time_clip(make_date(make_day(year, month, vdate), make_time(hours, minutes,seconds, ms))); return S_OK;}
static HRESULT DateConstr_UTC(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ double n; HRESULT hres;
TRACE("\n");
hres = date_utc(ctx, argc, argv, &n); if(SUCCEEDED(hres) && r) *r = jsval_number(n); return hres;}
/* ECMA-262 5.1 Edition 15.9.4.4 */static HRESULT DateConstr_now(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ TRACE("\n");
if(r) *r = jsval_number(date_now()); return S_OK;}
static HRESULT DateConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r){ jsdisp_t *date; HRESULT hres;
TRACE("\n");
switch(flags) { case DISPATCH_CONSTRUCT: switch(argc) { /* ECMA-262 3rd Edition 15.9.3.3 */ case 0: hres = create_date(ctx, NULL, date_now(), &date); if(FAILED(hres)) return hres; break;
/* ECMA-262 3rd Edition 15.9.3.2 */ case 1: { jsval_t prim; double n;
hres = to_primitive(ctx, argv[0], &prim, NO_HINT); if(FAILED(hres)) return hres;
if(is_string(prim)) hres = date_parse(get_string(prim), &n); else hres = to_number(ctx, prim, &n);
jsval_release(prim); if(FAILED(hres)) return hres;
hres = create_date(ctx, NULL, time_clip(n), &date); if(FAILED(hres)) return hres; break; }
/* ECMA-262 3rd Edition 15.9.3.1 */ default: { double ret_date; DateInstance *di;
hres = date_utc(ctx, argc, argv, &ret_date); if(FAILED(hres)) return hres;
hres = create_date(ctx, NULL, ret_date, &date); if(FAILED(hres)) return hres;
di = date_from_jsdisp(date); di->time = utc(di->time, di); } }
*r = jsval_obj(date); return S_OK;
case INVOKE_FUNC: { FILETIME system_time, local_time; LONGLONG lltime;
GetSystemTimeAsFileTime(&system_time); FileTimeToLocalFileTime(&system_time, &local_time); lltime = ((LONGLONG)local_time.dwHighDateTime<<32) + local_time.dwLowDateTime;
return date_to_string(lltime/10000-TIME_EPOCH, FALSE, 0, r); }
default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; }
return S_OK;}
static const builtin_prop_t DateConstr_props[] = { {UTCW, DateConstr_UTC, PROPF_METHOD}, {nowW, DateConstr_now, PROPF_HTML|PROPF_METHOD}, {parseW, DateConstr_parse, PROPF_METHOD}};
static const builtin_info_t DateConstr_info = { JSCLASS_FUNCTION, DEFAULT_FUNCTION_VALUE, ARRAY_SIZE(DateConstr_props), DateConstr_props, NULL, NULL};
HRESULT create_date_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret){ jsdisp_t *date; HRESULT hres;
static const WCHAR DateW[] = {'D','a','t','e',0};
hres = create_date(ctx, object_prototype, 0.0, &date); if(FAILED(hres)) return hres;
hres = create_builtin_constructor(ctx, DateConstr_value, DateW, &DateConstr_info, PROPF_CONSTR|7, date, ret);
jsdisp_release(date); return hres;}