Mercurial > projects > dmdscript-tango
diff dmdscript_tango/ddate.d @ 0:55c2951c07be
initial, files origin, premoved tree
author | saaadel |
---|---|
date | Sun, 24 Jan 2010 12:34:47 +0200 |
parents | |
children | 8363a4bf6a8f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmdscript_tango/ddate.d Sun Jan 24 12:34:47 2010 +0200 @@ -0,0 +1,1527 @@ + +/* Digital Mars DMDScript source code. + * Copyright (c) 2000-2002 by Chromium Communications + * D version Copyright (c) 2004-2005 by Digital Mars + * All Rights Reserved + * written by Walter Bright + * www.digitalmars.com + * Use at your own risk. There is no warranty, express or implied. + * License for redistribution is by the GNU General Public License in gpl.txt. + * + * A binary, non-exclusive license for commercial use can be + * purchased from www.digitalmars.com/dscript/buy.html. + * + * DMDScript is implemented in the D Programming Language, + * www.digitalmars.com/d/ + * + * For a C++ implementation of DMDScript, including COM support, + * see www.digitalmars.com/dscript/cppscript.html. + */ + + +module dmdscript.ddate; + +import std.math; +import std.date; + +import dmdscript.script; +import dmdscript.dobject; +import dmdscript.value; +import dmdscript.threadcontext; +import dmdscript.dfunction; +import dmdscript.dnative; +import dmdscript.property; +import dmdscript.text; +import dmdscript.errmsgs; + +version = DATETOSTRING; // use DateToString + +enum TIMEFORMAT +{ + String, + DateString, + TimeString, + LocaleString, + LocaleDateString, + LocaleTimeString, + UTCString, +} + +d_time parseDateString(CallContext *cc, d_string s) +{ + return std.date.parse(s); +} + +d_string dateToString(CallContext *cc, d_time t, TIMEFORMAT tf) +{ tchar[] p; + + if (t == d_time_nan) + p = "Invalid Date"; + else + { + switch (tf) + { + case TIMEFORMAT.String: + t = std.date.LocalTimetoUTC(t); + p = std.date.toString(t); + break; + + case TIMEFORMAT.DateString: + t = std.date.LocalTimetoUTC(t); + p = std.date.toDateString(t); + break; + + case TIMEFORMAT.TimeString: + t = std.date.LocalTimetoUTC(t); + p = std.date.toTimeString(t); + break; + + case TIMEFORMAT.LocaleString: + //p = std.date.toLocaleString(t); + p = std.date.toString(t); + break; + + case TIMEFORMAT.LocaleDateString: + //p = std.date.toLocaleDateString(t); + p = std.date.toDateString(t); + break; + + case TIMEFORMAT.LocaleTimeString: + //p = std.date.toLocaleTimeString(t); + p = std.date.toTimeString(t); + break; + + case TIMEFORMAT.UTCString: + p = std.date.toUTCString(t); + //p = std.date.toString(t); + break; + + default: + assert(0); + } + } + return p; +} + + +/* ===================== Ddate.constructor functions ==================== */ + +void* Ddate_parse(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + + // ECMA 15.9.4.2 + d_string s; + d_time n; + + if (arglist.length == 0) + n = d_time_nan; + else + { + s = arglist[0].toString(); + n = parseDateString(cc, s); + } + + ret.putVtime(n); + return null; +} + +void* Ddate_UTC(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.4.3 - 15.9.4.10 + + d_time n; + + d_time year; + d_time month = 0; + d_time date = 0; + d_time hours = 0; + d_time minutes = 0; + d_time seconds = 0; + d_time ms = 0; + + d_time day; + d_time time = 0; + + switch (arglist.length) + { + default: + case 7: + ms = arglist[6].toDtime(); + case 6: + seconds = arglist[5].toDtime(); + case 5: + minutes = arglist[4].toDtime(); + case 4: + hours = arglist[3].toDtime(); + time = std.date.MakeTime(hours, minutes, seconds, ms); + case 3: + date = arglist[2].toDtime(); + case 2: + month = arglist[1].toDtime(); + case 1: + year = arglist[0].toDtime(); + + if (year != d_time_nan && year >= 0 && year <= 99) + year += 1900; + day = std.date.MakeDay(year, month, date); + n = std.date.TimeClip(std.date.MakeDate(day,time)); + break; + + case 0: + n = std.date.getUTCtime(); + break; + } + ret.putVtime(n); + return null; +} + +/* ===================== Ddate_constructor ==================== */ + +class Ddate_constructor : Dfunction +{ + this(ThreadContext *tc) + { + super(7, tc.Dfunction_prototype); + name = "Date"; + + static NativeFunctionData nfd[] = + [ + { &TEXT_parse, &Ddate_parse, 1 }, + { &TEXT_UTC, &Ddate_UTC, 7 }, + ]; + + DnativeFunction.init(this, nfd, 0); + } + + void *Construct(CallContext *cc, Value *ret, Value[] arglist) + { + // ECMA 15.9.3 + Dobject o; + d_time n; + + d_time year; + d_time month; + d_time date = 0; + d_time hours = 0; + d_time minutes = 0; + d_time seconds = 0; + d_time ms = 0; + + d_time day; + d_time time = 0; + + //writefln("Ddate_constructor.Construct()"); + switch (arglist.length) + { + default: + case 7: + ms = arglist[6].toDtime(); + case 6: + seconds = arglist[5].toDtime(); + case 5: + minutes = arglist[4].toDtime(); + case 4: + hours = arglist[3].toDtime(); + time = std.date.MakeTime(hours, minutes, seconds, ms); + case 3: + date = arglist[2].toDtime(); + case 2: + month = arglist[1].toDtime(); + year = arglist[0].toDtime(); + + if (year != d_time_nan && year >= 0 && year <= 99) + year += 1900; + day = std.date.MakeDay(year, month, date); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(day, time))); + break; + + case 1: + arglist[0].toPrimitive(ret, null); + if (ret.getType() == TypeString) + { + n = parseDateString(cc, ret.string); + } + else + { + n = ret.toDtime(); + n = std.date.TimeClip(n); + } + break; + + case 0: + n = std.date.getUTCtime(); + break; + } + //writefln("\tn = %s", n); + o = new Ddate(n); + ret.putVobject(o); + return null; + } + + void *Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) + { + // ECMA 15.9.2 + // return string as if (new Date()).toString() + d_string s; + d_time t; + + version (DATETOSTRING) + { + t = std.date.getUTCtime(); + t = std.date.UTCtoLocalTime(t); + s = dateToString(cc, t, TIMEFORMAT.String); + } + else + { + t = std.date.time(); + s = std.date.toString(t); + } + ret.putVstring(s); + return null; + } +} + + +/* ===================== Ddate.prototype functions =============== */ + +void *checkdate(Value* ret, tchar[] name, Dobject othis) +{ + ret.putVundefined(); + ErrInfo errinfo; + return Dobject.RuntimeError(&errinfo, errmsgtbl[ERR_FUNCTION_WANTS_DATE], + name, othis.classname); +} + +int getThisTime(Value* ret, Dobject othis, out d_time n) +{ d_number x; + + n = cast(d_time)othis.value.number; + ret.putVtime(n); + return (n == d_time_nan) ? 1 : 0; +} + +int getThisLocalTime(Value* ret, Dobject othis, out d_time n) +{ int isn = 1; + + n = cast(d_time)othis.value.number; + if (n != d_time_nan) + { isn = 0; + n = std.date.UTCtoLocalTime(n); + } + ret.putVtime(n); + return isn; +} + +void* Ddate_prototype_toString(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.2 + d_time n; + d_string s; + + //writefln("Ddate_prototype_toString()"); + if (!othis.isDdate()) + return checkdate(ret, TEXT_toString, othis); + + version (DATETOSTRING) + { + getThisLocalTime(ret, othis, n); + s = dateToString(cc, n, TIMEFORMAT.String); + } + else + { + getThisTime(ret, othis, n); + s = std.date.ToString(n); + } + ret.putVstring(s); + return null; +} + +void* Ddate_prototype_toDateString(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.3 + d_time n; + d_string s; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_toDateString, othis); + + version (DATETOSTRING) + { + getThisLocalTime(ret, othis, n); + s = dateToString(cc, n, TIMEFORMAT.DateString); + } + else + { + getThisTime(ret, othis, n); + s = std.date.ToDateString(n); + } + ret.putVstring(s); + return null; +} + +void* Ddate_prototype_toTimeString(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.4 + d_time n; + d_string s; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_toTimeString, othis); + + version (DATETOSTRING) + { + getThisLocalTime(ret, othis, n); + s = dateToString(cc, n, TIMEFORMAT.TimeString); + } + else + { + getThisTime(ret, othis, n); + s = std.date.ToTimeString(n); + } + //s = std.date.ToTimeString(n); + ret.putVstring(s); + return null; +} + +void* Ddate_prototype_valueOf(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.3 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_valueOf, othis); + getThisTime(ret, othis, n); + return null; +} + +void* Ddate_prototype_getTime(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.4 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getTime, othis); + getThisTime(ret, othis, n); + return null; +} + +void* Ddate_prototype_getYear(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.5 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getYear, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.YearFromTime(n); + if (n != d_time_nan) + { + n -= 1900; + version (all) // emulate jscript bug + { + if (n < 0 || n >= 100) + n += 1900; + } + } + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getFullYear(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.6 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getFullYear, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.YearFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCFullYear(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.7 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCFullYear, othis); + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.YearFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getMonth(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.8 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getMonth, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.MonthFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCMonth(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.9 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCMonth, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.MonthFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getDate(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.10 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getDate, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + //printf("LocalTime = %.16g\n", n); + //printf("DaylightSavingTA(n) = %d\n", std.date.DaylightSavingTA(n)); + n = std.date.DateFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCDate(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.11 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCDate, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.DateFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getDay(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.12 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getDay, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.WeekDay(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCDay(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.13 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCDay, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.WeekDay(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getHours(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.14 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getHours, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.HourFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCHours(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.15 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCHours, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.HourFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getMinutes(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.16 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getMinutes, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.MinFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCMinutes(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.17 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCMinutes, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.MinFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getSeconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.18 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getSeconds, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.SecFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCSeconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.19 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCSeconds, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.SecFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getMilliseconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.20 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getMilliseconds, othis); + + if (getThisLocalTime(ret, othis, n) == 0) + { + n = std.date.msFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getUTCMilliseconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.21 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getUTCMilliseconds, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = std.date.msFromTime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_getTimezoneOffset(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.22 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_getTimezoneOffset, othis); + + if (getThisTime(ret, othis, n) == 0) + { + n = (n - std.date.UTCtoLocalTime(n)) / (60 * 1000); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setTime(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.23 + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setTime, othis); + + if (!arglist.length) + n = d_time_nan; + else + n = arglist[0].toDtime(); + n = std.date.TimeClip(n); + othis.value.putVtime(n); + ret.putVtime(n); + return null; +} + +void* Ddate_prototype_setMilliseconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.24 + + d_time ms; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setMilliseconds, othis); + + if (getThisLocalTime(ret, othis, t) == 0) + { + if (!arglist.length) + ms = d_time_nan; + else + ms = arglist[0].toDtime(); + time = std.date.MakeTime(std.date.HourFromTime(t), std.date.MinFromTime(t), std.date.SecFromTime(t), ms); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(std.date.Day(t),time))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setUTCMilliseconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.25 + d_time ms; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setUTCMilliseconds, othis); + + if (getThisTime(ret, othis, t) == 0) + { + if (!arglist.length) + ms = d_time_nan; + else + ms = arglist[0].toDtime(); + time = std.date.MakeTime(std.date.HourFromTime(t), std.date.MinFromTime(t), std.date.SecFromTime(t), ms); + n = std.date.TimeClip(std.date.MakeDate(std.date.Day(t),time)); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setSeconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.26 + d_time ms; + d_time seconds; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setSeconds, othis); + + if (getThisLocalTime(ret, othis, t) == 0) + { + switch (arglist.length) + { + default: + case 2: + ms = arglist[1].toDtime(); + seconds = arglist[0].toDtime(); + break; + + case 1: + ms = std.date.msFromTime(t); + seconds = arglist[0].toDtime(); + break; + + case 0: + ms = std.date.msFromTime(t); + seconds = d_time_nan; + break; + } + time = std.date.MakeTime(std.date.HourFromTime(t), std.date.MinFromTime(t), seconds, ms); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(std.date.Day(t),time))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setUTCSeconds(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.27 + d_time ms; + d_time seconds; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setUTCSeconds, othis); + + if (getThisTime(ret, othis, t) == 0) + { + switch (arglist.length) + { + default: + case 2: + ms = arglist[1].toDtime(); + seconds = arglist[0].toDtime(); + break; + + case 1: + ms = std.date.msFromTime(t); + seconds = arglist[0].toDtime(); + break; + + case 0: + ms = std.date.msFromTime(t); + seconds = d_time_nan; + break; + } + time = std.date.MakeTime(std.date.HourFromTime(t), std.date.MinFromTime(t), seconds, ms); + n = std.date.TimeClip(std.date.MakeDate(std.date.Day(t),time)); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setMinutes(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.28 + d_time ms; + d_time seconds; + d_time minutes; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setMinutes, othis); + + if (getThisLocalTime(ret, othis, t) == 0) + { + switch (arglist.length) + { + default: + case 3: + ms = arglist[2].toDtime(); + seconds = arglist[1].toDtime(); + minutes = arglist[0].toDtime(); + break; + + case 2: + ms = std.date.msFromTime(t); + seconds = arglist[1].toDtime(); + minutes = arglist[0].toDtime(); + break; + + case 1: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = arglist[0].toDtime(); + break; + + case 0: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = d_time_nan; + break; + } + time = std.date.MakeTime(std.date.HourFromTime(t), minutes, seconds, ms); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(std.date.Day(t),time))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setUTCMinutes(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.29 + d_time ms; + d_time seconds; + d_time minutes; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setUTCMinutes, othis); + + if (getThisTime(ret, othis, t) == 0) + { + switch (arglist.length) + { + default: + case 3: + ms = arglist[2].toDtime(); + seconds = arglist[1].toDtime(); + minutes = arglist[0].toDtime(); + break; + + case 2: + ms = std.date.msFromTime(t); + seconds = arglist[1].toDtime(); + minutes = arglist[0].toDtime(); + break; + + case 1: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = arglist[0].toDtime(); + break; + + case 0: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = d_time_nan; + break; + } + time = std.date.MakeTime(std.date.HourFromTime(t), minutes, seconds, ms); + n = std.date.TimeClip(std.date.MakeDate(std.date.Day(t),time)); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setHours(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.30 + d_time ms; + d_time seconds; + d_time minutes; + d_time hours; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setHours, othis); + + if (getThisLocalTime(ret, othis, t) == 0) + { + switch (arglist.length) + { + default: + case 4: + ms = arglist[3].toDtime(); + seconds = arglist[2].toDtime(); + minutes = arglist[1].toDtime(); + hours = arglist[0].toDtime(); + break; + + case 3: + ms = std.date.msFromTime(t); + seconds = arglist[2].toDtime(); + minutes = arglist[1].toDtime(); + hours = arglist[0].toDtime(); + break; + + case 2: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = arglist[1].toDtime(); + hours = arglist[0].toDtime(); + break; + + case 1: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = std.date.MinFromTime(t); + hours = arglist[0].toDtime(); + break; + + case 0: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = std.date.MinFromTime(t); + hours = d_time_nan; + break; + } + time = std.date.MakeTime(hours, minutes, seconds, ms); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(std.date.Day(t),time))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setUTCHours(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.31 + d_time ms; + d_time seconds; + d_time minutes; + d_time hours; + d_time t; + d_time time; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setUTCHours, othis); + + if (getThisTime(ret, othis, t) == 0) + { + switch (arglist.length) + { + default: + case 4: + ms = arglist[3].toDtime(); + seconds = arglist[2].toDtime(); + minutes = arglist[1].toDtime(); + hours = arglist[0].toDtime(); + break; + + case 3: + ms = std.date.msFromTime(t); + seconds = arglist[2].toDtime(); + minutes = arglist[1].toDtime(); + hours = arglist[0].toDtime(); + break; + + case 2: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = arglist[1].toDtime(); + hours = arglist[0].toDtime(); + break; + + case 1: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = std.date.MinFromTime(t); + hours = arglist[0].toDtime(); + break; + + case 0: + ms = std.date.msFromTime(t); + seconds = std.date.SecFromTime(t); + minutes = std.date.MinFromTime(t); + hours = d_time_nan; + break; + } + time = std.date.MakeTime(hours, minutes, seconds, ms); + n = std.date.TimeClip(std.date.MakeDate(std.date.Day(t),time)); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setDate(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.32 + d_time date; + d_time t; + d_time day; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setDate, othis); + + if (getThisLocalTime(ret, othis, t) == 0) + { + if (!arglist.length) + date = d_time_nan; + else + date = arglist[0].toDtime(); + day = std.date.MakeDay(std.date.YearFromTime(t), std.date.MonthFromTime(t), date); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(day, std.date.TimeWithinDay(t)))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setUTCDate(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.33 + d_time date; + d_time t; + d_time day; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setUTCDate, othis); + + if (getThisTime(ret, othis, t) == 0) + { + if (!arglist.length) + date = d_time_nan; + else + date = arglist[0].toDtime(); + day = std.date.MakeDay(std.date.YearFromTime(t), std.date.MonthFromTime(t), date); + n = std.date.TimeClip(std.date.MakeDate(day, std.date.TimeWithinDay(t))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setMonth(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.34 + d_time date; + d_time month; + d_time t; + d_time day; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setMonth, othis); + + if (getThisLocalTime(ret, othis, t) == 0) + { + switch (arglist.length) + { default: + case 2: + month = arglist[0].toDtime(); + date = arglist[1].toDtime(); + break; + + case 1: + month = arglist[0].toDtime(); + date = std.date.DateFromTime(t); + break; + + case 0: + month = d_time_nan; + date = std.date.DateFromTime(t); + break; + } + day = std.date.MakeDay(std.date.YearFromTime(t), month, date); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(day, std.date.TimeWithinDay(t)))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setUTCMonth(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.35 + d_time date; + d_time month; + d_time t; + d_time day; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setUTCMonth, othis); + + if (getThisTime(ret, othis, t) == 0) + { + switch (arglist.length) + { default: + case 2: + month = arglist[0].toDtime(); + date = arglist[1].toDtime(); + break; + + case 1: + month = arglist[0].toDtime(); + date = std.date.DateFromTime(t); + break; + + case 0: + month = d_time_nan; + date = std.date.DateFromTime(t); + break; + } + day = std.date.MakeDay(std.date.YearFromTime(t), month, date); + n = std.date.TimeClip(std.date.MakeDate(day, std.date.TimeWithinDay(t))); + othis.value.putVtime(n); + ret.putVtime(n); + } + return null; +} + +void* Ddate_prototype_setFullYear(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.36 + d_time date; + d_time month; + d_time year; + d_time t; + d_time day; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setFullYear, othis); + + if (getThisLocalTime(ret, othis, t)) + t = 0; + + switch (arglist.length) + { default: + case 3: + date = arglist[2].toDtime(); + month = arglist[1].toDtime(); + year = arglist[0].toDtime(); + break; + + case 2: + date = std.date.DateFromTime(t); + month = arglist[1].toDtime(); + year = arglist[0].toDtime(); + break; + + case 1: + date = std.date.DateFromTime(t); + month = std.date.MonthFromTime(t); + year = arglist[0].toDtime(); + break; + + case 0: + date = std.date.DateFromTime(t); + month = std.date.MonthFromTime(t); + year = d_time_nan; + break; + } + day = std.date.MakeDay(year, month, date); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(day, std.date.TimeWithinDay(t)))); + othis.value.putVtime(n); + ret.putVtime(n); + return null; +} + +void* Ddate_prototype_setUTCFullYear(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.37 + d_time date; + d_time month; + d_time year; + d_time t; + d_time day; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setUTCFullYear, othis); + + getThisTime(ret, othis, t); + if (t == d_time_nan) + t = 0; + switch (arglist.length) + { default: + case 3: + month = arglist[2].toDtime(); + date = arglist[1].toDtime(); + year = arglist[0].toDtime(); + break; + + case 2: + month = std.date.MonthFromTime(t); + date = arglist[1].toDtime(); + year = arglist[0].toDtime(); + break; + + case 1: + month = std.date.MonthFromTime(t); + date = std.date.DateFromTime(t); + year = arglist[0].toDtime(); + break; + + case 0: + month = std.date.MonthFromTime(t); + date = std.date.DateFromTime(t); + year = d_time_nan; + break; + } + day = std.date.MakeDay(year, month, date); + n = std.date.TimeClip(std.date.MakeDate(day, std.date.TimeWithinDay(t))); + othis.value.putVtime(n); + ret.putVtime(n); + return null; +} + +void* Ddate_prototype_setYear(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.38 + d_time date; + d_time month; + d_time year; + d_time t; + d_time day; + d_time n; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_setYear, othis); + + if (getThisLocalTime(ret, othis, t)) + t = 0; + switch (arglist.length) + { default: + case 1: + month = std.date.MonthFromTime(t); + date = std.date.DateFromTime(t); + year = arglist[0].toDtime(); + if (0 <= year && year <= 99) + year += 1900; + day = std.date.MakeDay(year, month, date); + n = std.date.TimeClip(std.date.LocalTimetoUTC(std.date.MakeDate(day, std.date.TimeWithinDay(t)))); + break; + + case 0: + n = d_time_nan; + break; + } + othis.value.putVtime(n); + ret.putVtime(n); + return null; +} + +void* Ddate_prototype_toLocaleString(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.39 + d_string s; + d_time t; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_toLocaleString, othis); + + if (getThisLocalTime(ret, othis, t)) + t = 0; + + s = dateToString(cc, t, TIMEFORMAT.LocaleString); + ret.putVstring(s); + return null; +} + +void* Ddate_prototype_toLocaleDateString(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.6 + d_string s; + d_time t; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_toLocaleDateString, othis); + + if (getThisLocalTime(ret, othis, t)) + t = 0; + + s = dateToString(cc, t, TIMEFORMAT.LocaleDateString); + ret.putVstring(s); + return null; +} + +void* Ddate_prototype_toLocaleTimeString(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.7 + d_string s; + d_time t; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_toLocaleTimeString, othis); + + if (getThisLocalTime(ret, othis, t)) + t = 0; + s = dateToString(cc, t, TIMEFORMAT.LocaleTimeString); + ret.putVstring(s); + return null; +} + +void* Ddate_prototype_toUTCString(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) +{ + // ECMA 15.9.5.40 + d_string s; + d_time t; + + if (!othis.isDdate()) + return checkdate(ret, TEXT_toUTCString, othis); + + if (getThisTime(ret, othis, t)) + t = 0; + s = dateToString(cc, t, TIMEFORMAT.UTCString); + ret.putVstring(s); + return null; +} + +/* ===================== Ddate_prototype ==================== */ + +class Ddate_prototype : Ddate +{ + this(ThreadContext *tc) + { + super(tc.Dobject_prototype); + + Dobject f = tc.Dfunction_prototype; + + Put(TEXT_constructor, tc.Ddate_constructor, DontEnum); + + static NativeFunctionData nfd[] = + [ + { &TEXT_toString, &Ddate_prototype_toString, 0 }, + { &TEXT_toDateString, &Ddate_prototype_toDateString, 0 }, + { &TEXT_toTimeString, &Ddate_prototype_toTimeString, 0 }, + { &TEXT_valueOf, &Ddate_prototype_valueOf, 0 }, + { &TEXT_getTime, &Ddate_prototype_getTime, 0 }, + //{ &TEXT_getVarDate, &Ddate_prototype_getVarDate, 0 }, + { &TEXT_getYear, &Ddate_prototype_getYear, 0 }, + { &TEXT_getFullYear, &Ddate_prototype_getFullYear, 0 }, + { &TEXT_getUTCFullYear, &Ddate_prototype_getUTCFullYear, 0 }, + { &TEXT_getMonth, &Ddate_prototype_getMonth, 0 }, + { &TEXT_getUTCMonth, &Ddate_prototype_getUTCMonth, 0 }, + { &TEXT_getDate, &Ddate_prototype_getDate, 0 }, + { &TEXT_getUTCDate, &Ddate_prototype_getUTCDate, 0 }, + { &TEXT_getDay, &Ddate_prototype_getDay, 0 }, + { &TEXT_getUTCDay, &Ddate_prototype_getUTCDay, 0 }, + { &TEXT_getHours, &Ddate_prototype_getHours, 0 }, + { &TEXT_getUTCHours, &Ddate_prototype_getUTCHours, 0 }, + { &TEXT_getMinutes, &Ddate_prototype_getMinutes, 0 }, + { &TEXT_getUTCMinutes, &Ddate_prototype_getUTCMinutes, 0 }, + { &TEXT_getSeconds, &Ddate_prototype_getSeconds, 0 }, + { &TEXT_getUTCSeconds, &Ddate_prototype_getUTCSeconds, 0 }, + { &TEXT_getMilliseconds, &Ddate_prototype_getMilliseconds, 0 }, + { &TEXT_getUTCMilliseconds, &Ddate_prototype_getUTCMilliseconds, 0 }, + { &TEXT_getTimezoneOffset, &Ddate_prototype_getTimezoneOffset, 0 }, + { &TEXT_setTime, &Ddate_prototype_setTime, 1 }, + { &TEXT_setMilliseconds, &Ddate_prototype_setMilliseconds, 1 }, + { &TEXT_setUTCMilliseconds, &Ddate_prototype_setUTCMilliseconds, 1 }, + { &TEXT_setSeconds, &Ddate_prototype_setSeconds, 2 }, + { &TEXT_setUTCSeconds, &Ddate_prototype_setUTCSeconds, 2 }, + { &TEXT_setMinutes, &Ddate_prototype_setMinutes, 3 }, + { &TEXT_setUTCMinutes, &Ddate_prototype_setUTCMinutes, 3 }, + { &TEXT_setHours, &Ddate_prototype_setHours, 4 }, + { &TEXT_setUTCHours, &Ddate_prototype_setUTCHours, 4 }, + { &TEXT_setDate, &Ddate_prototype_setDate, 1 }, + { &TEXT_setUTCDate, &Ddate_prototype_setUTCDate, 1 }, + { &TEXT_setMonth, &Ddate_prototype_setMonth, 2 }, + { &TEXT_setUTCMonth, &Ddate_prototype_setUTCMonth, 2 }, + { &TEXT_setFullYear, &Ddate_prototype_setFullYear, 3 }, + { &TEXT_setUTCFullYear, &Ddate_prototype_setUTCFullYear, 3 }, + { &TEXT_setYear, &Ddate_prototype_setYear, 1 }, + { &TEXT_toLocaleString, &Ddate_prototype_toLocaleString, 0 }, + { &TEXT_toLocaleDateString, &Ddate_prototype_toLocaleDateString, 0 }, + { &TEXT_toLocaleTimeString, &Ddate_prototype_toLocaleTimeString, 0 }, + { &TEXT_toUTCString, &Ddate_prototype_toUTCString, 0 }, + + // Map toGMTString() onto toUTCString(), per ECMA 15.9.5.41 + { &TEXT_toGMTString, &Ddate_prototype_toUTCString, 0 }, + ]; + + DnativeFunction.init(this, nfd, 0); + assert(proptable.get("toString", Value.calcHash("toString"))); + } +} + + +/* ===================== Ddate ==================== */ + +class Ddate : Dobject +{ + this(d_number n) + { + super(Ddate.getPrototype()); + classname = TEXT_Date; + value.putVnumber(n); + } + + this(d_time n) + { + super(Ddate.getPrototype()); + classname = TEXT_Date; + value.putVtime(n); + } + + this(Dobject prototype) + { + super(prototype); + classname = TEXT_Date; + value.putVnumber(d_number.nan); + } + + static void init(ThreadContext *tc) + { + tc.Ddate_constructor = new Ddate_constructor(tc); + tc.Ddate_prototype = new Ddate_prototype(tc); + + tc.Ddate_constructor.Put(TEXT_prototype, tc.Ddate_prototype, + DontEnum | DontDelete | ReadOnly); + + assert(tc.Ddate_prototype.proptable.table.length != 0); + } + + static Dfunction getConstructor() + { + ThreadContext *tc = ThreadContext.getThreadContext(); + assert(tc); + return tc.Ddate_constructor; + } + + static Dobject getPrototype() + { + ThreadContext *tc = ThreadContext.getThreadContext(); + assert(tc); + return tc.Ddate_prototype; + } +} + +