1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123 |
- using System;
- using System.Globalization;
- using Jint.Runtime;
- using Jint.Runtime.Descriptors;
- using Jint.Runtime.Interop;
- namespace Jint.Native.Date
- {
- /// <summary>
- /// http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.5
- /// </summary>
- public sealed class DatePrototype : DateInstance
- {
- private DatePrototype(Engine engine)
- : base(engine)
- {
- }
- public static DatePrototype CreatePrototypeObject(Engine engine, DateConstructor dateConstructor)
- {
- var obj = new DatePrototype(engine)
- {
- Prototype = engine.Object.PrototypeObject,
- Extensible = true,
- PrimitiveValue = double.NaN
- };
- obj.SetOwnProperty("constructor", new PropertyDescriptor(dateConstructor, PropertyFlag.NonEnumerable));
- return obj;
- }
- public void Configure()
- {
- FastAddProperty("toString", new ClrFunctionInstance(Engine, "toString", ToString, 0), true, false, true);
- FastAddProperty("toDateString", new ClrFunctionInstance(Engine, "toDateString", ToDateString, 0), true, false, true);
- FastAddProperty("toTimeString", new ClrFunctionInstance(Engine, "toTimeString", ToTimeString, 0), true, false, true);
- FastAddProperty("toLocaleString", new ClrFunctionInstance(Engine, "toLocaleString", ToLocaleString, 0), true, false, true);
- FastAddProperty("toLocaleDateString", new ClrFunctionInstance(Engine, "toLocaleDateString", ToLocaleDateString, 0), true, false, true);
- FastAddProperty("toLocaleTimeString", new ClrFunctionInstance(Engine, "toLocaleTimeString", ToLocaleTimeString, 0), true, false, true);
- FastAddProperty("valueOf", new ClrFunctionInstance(Engine, "valueOf", ValueOf, 0), true, false, true);
- FastAddProperty("getTime", new ClrFunctionInstance(Engine, "getTime", GetTime, 0), true, false, true);
- FastAddProperty("getFullYear", new ClrFunctionInstance(Engine, "getFullYear", GetFullYear, 0), true, false, true);
- FastAddProperty("getYear", new ClrFunctionInstance(Engine, "getYear", GetYear, 0), true, false, true);
- FastAddProperty("getUTCFullYear", new ClrFunctionInstance(Engine, "getUTCFullYear", GetUTCFullYear, 0), true, false, true);
- FastAddProperty("getMonth", new ClrFunctionInstance(Engine, "getMonth", GetMonth, 0), true, false, true);
- FastAddProperty("getUTCMonth", new ClrFunctionInstance(Engine, "getUTCMonth", GetUTCMonth, 0), true, false, true);
- FastAddProperty("getDate", new ClrFunctionInstance(Engine, "getDate", GetDate, 0), true, false, true);
- FastAddProperty("getUTCDate", new ClrFunctionInstance(Engine, "getUTCDate", GetUTCDate, 0), true, false, true);
- FastAddProperty("getDay", new ClrFunctionInstance(Engine, "getDay", GetDay, 0), true, false, true);
- FastAddProperty("getUTCDay", new ClrFunctionInstance(Engine, "getUTCDay", GetUTCDay, 0), true, false, true);
- FastAddProperty("getHours", new ClrFunctionInstance(Engine, "getHours", GetHours, 0), true, false, true);
- FastAddProperty("getUTCHours", new ClrFunctionInstance(Engine, "getUTCHours", GetUTCHours, 0), true, false, true);
- FastAddProperty("getMinutes", new ClrFunctionInstance(Engine, "getMinutes", GetMinutes, 0), true, false, true);
- FastAddProperty("getUTCMinutes", new ClrFunctionInstance(Engine, "getUTCMInutes", GetUTCMinutes, 0), true, false, true);
- FastAddProperty("getSeconds", new ClrFunctionInstance(Engine, "getSeconds", GetSeconds, 0), true, false, true);
- FastAddProperty("getUTCSeconds", new ClrFunctionInstance(Engine, "getUTCSeconds", GetUTCSeconds, 0), true, false, true);
- FastAddProperty("getMilliseconds", new ClrFunctionInstance(Engine, "getMilliseconds", GetMilliseconds, 0), true, false, true);
- FastAddProperty("getUTCMilliseconds", new ClrFunctionInstance(Engine, "getUTCMilliseconds", GetUTCMilliseconds, 0), true, false, true);
- FastAddProperty("getTimezoneOffset", new ClrFunctionInstance(Engine, "getTimezoneOffset", GetTimezoneOffset, 0), true, false, true);
- FastAddProperty("setTime", new ClrFunctionInstance(Engine, "setTime", SetTime, 1), true, false, true);
- FastAddProperty("setMilliseconds", new ClrFunctionInstance(Engine, "setMilliseconds", SetMilliseconds, 1), true, false, true);
- FastAddProperty("setUTCMilliseconds", new ClrFunctionInstance(Engine, "setUTCMilliseconds", SetUTCMilliseconds, 1), true, false, true);
- FastAddProperty("setSeconds", new ClrFunctionInstance(Engine, "setSeconds", SetSeconds, 2), true, false, true);
- FastAddProperty("setUTCSeconds", new ClrFunctionInstance(Engine, "setUTCSeconds", SetUTCSeconds, 2), true, false, true);
- FastAddProperty("setMinutes", new ClrFunctionInstance(Engine, "setMinutes", SetMinutes, 3), true, false, true);
- FastAddProperty("setUTCMinutes", new ClrFunctionInstance(Engine, "setUTCMinutes", SetUTCMinutes, 3), true, false, true);
- FastAddProperty("setHours", new ClrFunctionInstance(Engine, "setHours", SetHours, 4), true, false, true);
- FastAddProperty("setUTCHours", new ClrFunctionInstance(Engine, "setUTCHours", SetUTCHours, 4), true, false, true);
- FastAddProperty("setDate", new ClrFunctionInstance(Engine, "setDate", SetDate, 1), true, false, true);
- FastAddProperty("setUTCDate", new ClrFunctionInstance(Engine, "setUTCDate", SetUTCDate, 1), true, false, true);
- FastAddProperty("setMonth", new ClrFunctionInstance(Engine, "setMonth", SetMonth, 2), true, false, true);
- FastAddProperty("setUTCMonth", new ClrFunctionInstance(Engine, "setUTCMonth", SetUTCMonth, 2), true, false, true);
- FastAddProperty("setFullYear", new ClrFunctionInstance(Engine, "setFullYear", SetFullYear, 3), true, false, true);
- FastAddProperty("setYear", new ClrFunctionInstance(Engine, "setYear", SetYear, 1), true, false, true);
- FastAddProperty("setUTCFullYear", new ClrFunctionInstance(Engine, "setUTCFullYear ", SetUTCFullYear, 3), true, false, true);
- FastAddProperty("toUTCString", new ClrFunctionInstance(Engine, "toUTCString", ToUtcString, 0), true, false, true);
- FastAddProperty("toISOString", new ClrFunctionInstance(Engine, "toISOString", ToISOString, 0), true, false, true);
- FastAddProperty("toJSON", new ClrFunctionInstance(Engine, "toJSON", ToJSON, 1), true, false, true);
- }
- private JsValue ValueOf(JsValue thisObj, JsValue[] arguments)
- {
- return EnsureDateInstance(thisObj).PrimitiveValue;
- }
- /// <summary>
- /// Converts a value to a <see cref="DateInstance"/> or throws a TypeError exception.
- /// c.f., http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.5
- /// </summary>
- private DateInstance EnsureDateInstance(JsValue thisObj)
- {
- return thisObj.TryCast<DateInstance>(value =>
- {
- ExceptionHelper.ThrowTypeError(_engine, "Invalid Date");
- });
- }
- public JsValue ToString(JsValue thisObj, JsValue[] arg2)
- {
- return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture);
- }
- private JsValue ToDateString(JsValue thisObj, JsValue[] arguments)
- {
- return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("ddd MMM dd yyyy", CultureInfo.InvariantCulture);
- }
- private JsValue ToTimeString(JsValue thisObj, JsValue[] arguments)
- {
- return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture);
- }
- private JsValue ToLocaleString(JsValue thisObj, JsValue[] arguments)
- {
- return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("F", Engine.Options._Culture);
- }
- private JsValue ToLocaleDateString(JsValue thisObj, JsValue[] arguments)
- {
- return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("D", Engine.Options._Culture);
- }
- private JsValue ToLocaleTimeString(JsValue thisObj, JsValue[] arguments)
- {
- return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("T", Engine.Options._Culture);
- }
- private JsValue GetTime(JsValue thisObj, JsValue[] arguments)
- {
- if (double.IsNaN(EnsureDateInstance(thisObj).PrimitiveValue))
- {
- return JsNumber.DoubleNaN;
- }
- return EnsureDateInstance(thisObj).PrimitiveValue;
- }
- private JsValue GetFullYear(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return YearFromTime(LocalTime(t));
- }
- private JsValue GetYear(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return YearFromTime(LocalTime(t)) - 1900;
- }
- private JsValue GetUTCFullYear(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return YearFromTime(t);
- }
- private JsValue GetMonth(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return MonthFromTime(LocalTime(t));
- }
- private JsValue GetUTCMonth(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return MonthFromTime(t);
- }
- private JsValue GetDate(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return DateFromTime(LocalTime(t));
- }
- private JsValue GetUTCDate(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return DateFromTime(t);
- }
- private JsValue GetDay(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return WeekDay(LocalTime(t));
- }
- private JsValue GetUTCDay(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return WeekDay(t);
- }
- private JsValue GetHours(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return HourFromTime(LocalTime(t));
- }
- private JsValue GetUTCHours(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return HourFromTime(t);
- }
- private JsValue GetMinutes(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return MinFromTime(LocalTime(t));
- }
- private JsValue GetUTCMinutes(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return MinFromTime(t);
- }
- private JsValue GetSeconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = thisObj.TryCast<DateInstance>().PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return SecFromTime(LocalTime(t));
- }
- private JsValue GetUTCSeconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return SecFromTime(t);
- }
- private JsValue GetMilliseconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return MsFromTime(LocalTime(t));
- }
- private JsValue GetUTCMilliseconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return MsFromTime(t);
- }
- private JsValue GetTimezoneOffset(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- if (double.IsNaN(t))
- {
- return JsNumber.DoubleNaN;
- }
- return (t - LocalTime(t))/MsPerMinute;
- }
- private JsValue SetTime(JsValue thisObj, JsValue[] arguments)
- {
- return EnsureDateInstance(thisObj).PrimitiveValue = TimeClip(TypeConverter.ToNumber(arguments.At(0)));
- }
- private JsValue SetMilliseconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
- var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0)));
- var u = TimeClip(Utc(MakeDate(Day(t), time)));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetUTCMilliseconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0)));
- var u = TimeClip(MakeDate(Day(t), time));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetSeconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
- var s = TypeConverter.ToNumber(arguments.At(0));
- var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
- var u = TimeClip(Utc(date));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetUTCSeconds(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- var s = TypeConverter.ToNumber(arguments.At(0));
- var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
- var u = TimeClip(date);
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetMinutes(JsValue thisObj, JsValue[] arguments)
- {
- var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
- var m = TypeConverter.ToNumber(arguments.At(0));
- var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
- var date = MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli));
- var u = TimeClip(Utc(date));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetUTCMinutes(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- var m = TypeConverter.ToNumber(arguments.At(0));
- var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
- var date = MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli));
- var u = TimeClip(date);
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetHours(JsValue thisObj, JsValue[] arguments)
- {
- var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
- var h = TypeConverter.ToNumber(arguments.At(0));
- var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
- var milli = arguments.Length <= 3 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(3));
- var date = MakeDate(Day(t), MakeTime(h, m, s, milli));
- var u = TimeClip(Utc(date));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetUTCHours(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- var h = TypeConverter.ToNumber(arguments.At(0));
- var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
- var milli = arguments.Length <= 3 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(3));
- var date = MakeDate(Day(t), MakeTime(h, m, s, milli));
- var u = TimeClip(date);
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetDate(JsValue thisObj, JsValue[] arguments)
- {
- var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
- var dt = TypeConverter.ToNumber(arguments.At(0));
- var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t));
- var u = TimeClip(Utc(newDate));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetUTCDate(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- var dt = TypeConverter.ToNumber(arguments.At(0));
- var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t));
- var u = TimeClip(newDate);
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetMonth(JsValue thisObj, JsValue[] arguments)
- {
- var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue);
- var m = TypeConverter.ToNumber(arguments.At(0));
- var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t));
- var u = TimeClip(Utc(newDate));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetUTCMonth(JsValue thisObj, JsValue[] arguments)
- {
- var t = EnsureDateInstance(thisObj).PrimitiveValue;
- var m = TypeConverter.ToNumber(arguments.At(0));
- var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t));
- var u = TimeClip(newDate);
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetFullYear(JsValue thisObj, JsValue[] arguments)
- {
- var thisTime = EnsureDateInstance(thisObj).PrimitiveValue;
- var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime);
- var y = TypeConverter.ToNumber(arguments.At(0));
- var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var dt = arguments.Length <= 2 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
- var newDate = MakeDate(MakeDay(y, m, dt), TimeWithinDay(t));
- var u = TimeClip(Utc(newDate));
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue SetYear(JsValue thisObj, JsValue[] arguments)
- {
- var thisTime = EnsureDateInstance(thisObj).PrimitiveValue;
- var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime);
- var y = TypeConverter.ToNumber(arguments.At(0));
- if (double.IsNaN(y))
- {
- EnsureDateInstance(thisObj).PrimitiveValue = double.NaN;
- return JsNumber.DoubleNaN;
- }
- var fy = TypeConverter.ToInteger(y);
- if (y >= 0 && y <= 99)
- {
- fy = fy + 1900;
- }
- var newDate = MakeDay(fy, MonthFromTime(t), DateFromTime(t));
- var u = Utc(MakeDate(newDate, TimeWithinDay(t)));
- EnsureDateInstance(thisObj).PrimitiveValue = TimeClip(u);
- return u;
- }
- private JsValue SetUTCFullYear(JsValue thisObj, JsValue[] arguments)
- {
- var thisTime = EnsureDateInstance(thisObj).PrimitiveValue;
- var t = double.IsNaN(thisTime) ? +0 : thisTime;
- var y = TypeConverter.ToNumber(arguments.At(0));
- var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1));
- var dt = arguments.Length <= 2 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(2));
- var newDate = MakeDate(MakeDay(y, m, dt), TimeWithinDay(t));
- var u = TimeClip(newDate);
- thisObj.As<DateInstance>().PrimitiveValue = u;
- return u;
- }
- private JsValue ToUtcString(JsValue thisObj, JsValue[] arguments)
- {
- return thisObj.TryCast<DateInstance>(x =>
- {
- ExceptionHelper.ThrowTypeError(_engine);
- } )
- .ToDateTime().ToUniversalTime().ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'", CultureInfo.InvariantCulture);
- }
- private JsValue ToISOString(JsValue thisObj, JsValue[] arguments)
- {
- var t = thisObj.TryCast<DateInstance>(x =>
- {
- ExceptionHelper.ThrowTypeError(_engine);
- }).PrimitiveValue;
- if (double.IsInfinity(t) || double.IsNaN(t))
- {
- ExceptionHelper.ThrowRangeError(_engine);
- }
- double h = HourFromTime(t);
- double m = MinFromTime(t);
- double s = SecFromTime(t);
- double ms = MsFromTime(t);
- if (h < 0) { h += HoursPerDay; }
- if (m < 0) { m += MinutesPerHour; }
- if (s < 0) { s += SecondsPerMinute; }
- if (ms < 0) { ms += MsPerSecond; }
- return $"{YearFromTime(t):0000}-{MonthFromTime(t) + 1:00}-{DateFromTime(t):00}T{h:00}:{m:00}:{s:00}.{ms:000}Z";
- }
- private JsValue ToJSON(JsValue thisObj, JsValue[] arguments)
- {
- var o = TypeConverter.ToObject(Engine, thisObj);
- var tv = TypeConverter.ToPrimitive(o, Types.Number);
- if (tv.IsNumber() && double.IsInfinity(((JsNumber) tv)._value))
- {
- return Null;
- }
- var toIso = o.Get("toISOString");
- if (!toIso.Is<ICallable>())
- {
- ExceptionHelper.ThrowTypeError(Engine);
- }
- return toIso.TryCast<ICallable>().Call(o, Arguments.Empty);
- }
- public const double HoursPerDay = 24;
- public const double MinutesPerHour = 60;
- public const double SecondsPerMinute = 60;
- public const double MsPerSecond = 1000;
- public const double MsPerMinute = 60000;
- public const double MsPerHour = 3600000;
- public const double MsPerDay = 86400000;
- /// <summary>
- /// 15.9.1.2
- /// </summary>
- public static double Day(double t)
- {
- return System.Math.Floor(t / MsPerDay);
- }
- /// <summary>
- /// 15.9.1.2
- /// </summary>
- public static double TimeWithinDay(double t)
- {
- var result = t % MsPerDay;
- if (result < 0)
- {
- result += MsPerDay;
- }
- return result;
- }
- /// <summary>
- /// The number of days in a year
- /// </summary>
- public static double DaysInYear(double y)
- {
- if (!(y%4).Equals(0))
- {
- return 365;
- }
- if ((y%4).Equals(0) && !(y%100).Equals(0))
- {
- return 366;
- }
- if ((y%100).Equals(0) && !(y%400).Equals(0))
- {
- return 365;
- }
- if ((y%400).Equals(0))
- {
- return 366;
- }
- return 365;
- }
- /// <summary>
- /// The day number of the first day of the year.
- /// </summary>
- public static double DayFromYear(double y)
- {
- return 365*(y - 1970)
- + System.Math.Floor((y - 1969)/4)
- - System.Math.Floor((y - 1901)/100)
- + System.Math.Floor((y - 1601)/400);
- }
- /// <summary>
- /// The time value of the start of the year
- /// </summary>
- public static double TimeFromYear(double y)
- {
- return MsPerDay*DayFromYear(y);
- }
- /// <summary>
- /// The year of a time value.
- /// </summary>
- public static double YearFromTime(double t)
- {
- if (!AreFinite(t))
- {
- return double.NaN;
- }
- var sign = (t < 0) ? -1 : 1;
- var year = (sign < 0) ? 1969 : 1970;
- for (var timeToTimeZero = t; ;)
- {
- // Subtract the current year's time from the time that's left.
- var timeInYear = DaysInYear(year) * MsPerDay;
- timeToTimeZero -= sign * timeInYear;
- // If there's less than the current year's worth of time left, then break.
- if (sign < 0)
- {
- if (sign * timeToTimeZero <= 0)
- {
- break;
- }
- else
- {
- year += sign;
- }
- }
- else
- {
- if (sign * timeToTimeZero < 0)
- {
- break;
- }
- else
- {
- year += sign;
- }
- }
- }
- return year;
- }
- /// <summary>
- /// <value>true</value> if the time is within a leap year, <value>false</value> otherwise
- /// </summary>
- public static double InLeapYear(double t)
- {
- var daysInYear = DaysInYear(YearFromTime(t));
- if (daysInYear.Equals(365))
- {
- return 0;
- }
- if (daysInYear.Equals(366))
- {
- return 1;
- }
- ExceptionHelper.ThrowArgumentException();
- return 0;
- }
- /// <summary>
- /// The month number of a time value.
- /// </summary>
- public static double MonthFromTime(double t)
- {
- var dayWithinYear = DayWithinYear(t);
- var inLeapYear = InLeapYear(t);
- if (dayWithinYear < 31)
- {
- return 0;
- }
- if (dayWithinYear < 59 + inLeapYear)
- {
- return 1;
- }
- if (dayWithinYear < 90 + inLeapYear)
- {
- return 2;
- }
- if (dayWithinYear < 120 + inLeapYear)
- {
- return 3;
- }
- if (dayWithinYear < 151 + inLeapYear)
- {
- return 4;
- }
- if (dayWithinYear < 181 + inLeapYear)
- {
- return 5;
- }
- if (dayWithinYear < 212 + inLeapYear)
- {
- return 6;
- }
- if (dayWithinYear < 243 + inLeapYear)
- {
- return 7;
- }
- if (dayWithinYear < 273 + inLeapYear)
- {
- return 8;
- }
- if (dayWithinYear < 304 + inLeapYear)
- {
- return 9;
- }
- if (dayWithinYear < 334 + inLeapYear)
- {
- return 10;
- }
- if (dayWithinYear < 365 + inLeapYear)
- {
- return 11;
- }
- ExceptionHelper.ThrowInvalidOperationException();
- return 0;
- }
- public static double DayWithinYear(double t)
- {
- return Day(t) - DayFromYear(YearFromTime(t));
- }
- public static double DateFromTime(double t)
- {
- var monthFromTime = MonthFromTime(t);
- var dayWithinYear = DayWithinYear(t);
- if (monthFromTime.Equals(0))
- {
- return dayWithinYear + 1;
- }
- if (monthFromTime.Equals(1))
- {
- return dayWithinYear - 30;
- }
- if (monthFromTime.Equals(2))
- {
- return dayWithinYear - 58 - InLeapYear(t);
- }
- if (monthFromTime.Equals(3))
- {
- return dayWithinYear - 89 - InLeapYear(t);
- }
- if (monthFromTime.Equals(4))
- {
- return dayWithinYear - 119 - InLeapYear(t);
- }
- if (monthFromTime.Equals(5))
- {
- return dayWithinYear - 150 - InLeapYear(t);
- }
- if (monthFromTime.Equals(6))
- {
- return dayWithinYear - 180 - InLeapYear(t);
- }
- if (monthFromTime.Equals(7))
- {
- return dayWithinYear - 211 - InLeapYear(t);
- }
- if (monthFromTime.Equals(8))
- {
- return dayWithinYear - 242 - InLeapYear(t);
- }
- if (monthFromTime.Equals(9))
- {
- return dayWithinYear - 272 - InLeapYear(t);
- }
- if (monthFromTime.Equals(10))
- {
- return dayWithinYear - 303 - InLeapYear(t);
- }
- if (monthFromTime.Equals(11))
- {
- return dayWithinYear - 333 - InLeapYear(t);
- }
- ExceptionHelper.ThrowInvalidOperationException();
- return 0;
- }
- /// <summary>
- /// The weekday for a particular time value.
- /// </summary>
- public static double WeekDay(double t)
- {
- return (Day(t) + 4)%7;
- }
- public double LocalTza => Engine.Options._LocalTimeZone.BaseUtcOffset.TotalMilliseconds;
- public double DaylightSavingTa(double t)
- {
- var timeInYear = t - TimeFromYear(YearFromTime(t));
- if (double.IsInfinity(timeInYear) || double.IsNaN(timeInYear))
- {
- return 0;
- }
- var year = YearFromTime(t);
- if (year < 9999 && year > -9999)
- {
- // in DateTimeOffset range so we can use it
- }
- else
- {
- // use similar leap-ed year
- var isLeapYear = InLeapYear(t).Equals(1);
- year = isLeapYear ? 2000 : 1999;
- }
- var dateTime = new DateTime((int)year, 1, 1).AddMilliseconds(timeInYear);
- return Engine.Options._LocalTimeZone.IsDaylightSavingTime(dateTime) ? MsPerHour : 0;
- }
- public DateTimeOffset ToLocalTime(DateTime t)
- {
- switch (t.Kind)
- {
- case DateTimeKind.Local:
- return new DateTimeOffset(TimeZoneInfo.ConvertTime(t.ToUniversalTime(), Engine.Options._LocalTimeZone), Engine.Options._LocalTimeZone.GetUtcOffset(t));
- case DateTimeKind.Utc:
- return new DateTimeOffset(TimeZoneInfo.ConvertTime(t, Engine.Options._LocalTimeZone), Engine.Options._LocalTimeZone.GetUtcOffset(t));
- default:
- return t;
- }
- }
- public double LocalTime(double t)
- {
- return t + LocalTza + DaylightSavingTa(t);
- }
- public double Utc(double t)
- {
- return t - LocalTza - DaylightSavingTa(t - LocalTza);
- }
- public static double HourFromTime(double t)
- {
- var hours = System.Math.Floor(t / MsPerHour) % HoursPerDay;
- if (hours < 0)
- {
- hours += HoursPerDay;
- }
- return hours;
- }
- public static double MinFromTime(double t)
- {
- var minutes = System.Math.Floor(t / MsPerMinute) % MinutesPerHour;
- if (minutes < 0)
- {
- minutes += MinutesPerHour;
- }
- return minutes;
- }
- public static double SecFromTime(double t)
- {
- var seconds = System.Math.Floor(t / MsPerSecond) % SecondsPerMinute;
- if (seconds < 0)
- {
- seconds += SecondsPerMinute;
- }
- return seconds;
- }
- public static double MsFromTime(double t)
- {
- var milli = t % MsPerSecond;
- if (milli < 0)
- {
- milli += MsPerSecond;
- }
- return milli;
- }
- public static double DayFromMonth(double year, double month)
- {
- double day = month * 30;
- if (month >= 7)
- {
- day += month/2 - 1;
- }
- else if (month >= 2)
- {
- day += (month - 1)/2 - 1;
- }
- else
- {
- day += month;
- }
- if (month >= 2 && InLeapYear(year).Equals(1))
- {
- day++;
- }
- return day;
- }
- public static double DaysInMonth(double month, double leap)
- {
- month = month%12;
- switch ((long) month)
- {
- case 0:
- case 2:
- case 4:
- case 6:
- case 7:
- case 9:
- case 11:
- return 31;
- case 3:
- case 5:
- case 8:
- case 10:
- return 30;
- case 1:
- return 28 + leap;
- default:
- ExceptionHelper.ThrowArgumentOutOfRangeException(nameof(month), "invalid month");
- return 0;
- }
- }
- public static double MakeTime(double hour, double min, double sec, double ms)
- {
- if (!AreFinite(hour, min, sec, ms))
- {
- return double.NaN;
- }
- var h = (long) hour;
- var m = (long) min;
- var s = (long) sec;
- var milli = (long) ms;
- var t = h*MsPerHour + m*MsPerMinute + s*MsPerSecond + milli;
- return t;
- }
- public static double MakeDay(double year, double month, double date)
- {
- if (!AreFinite(year, month, date))
- {
- return double.NaN;
- }
- year = TypeConverter.ToInteger(year);
- month = TypeConverter.ToInteger(month);
- date = TypeConverter.ToInteger(date);
- if (month < 0)
- {
- var m = (long) month;
- year += (m - 11) / 12;
- month = (12 + m % 12) % 12;
- }
- var sign = (year < 1970) ? -1 : 1;
- double t = (year < 1970) ? 1 : 0;
- int y;
- if (sign == -1)
- {
- for (y = 1969; y >= year; y += sign)
- {
- t += sign * DaysInYear(y) * MsPerDay;
- }
- }
- else
- {
- for (y = 1970; y < year; y += sign)
- {
- t += sign * DaysInYear(y) * MsPerDay;
- }
- }
- for (var m = 0; m < month; m++)
- {
- t += DaysInMonth(m, InLeapYear(t)) * MsPerDay;
- }
- return Day(t) + date - 1;
- }
- public static double MakeDate(double day, double time)
- {
- if (!AreFinite(day, time))
- {
- return double.NaN;
- }
- return day * MsPerDay + time;
- }
- public static double TimeClip(double time)
- {
- if (!AreFinite(time))
- {
- return double.NaN;
- }
- if (System.Math.Abs(time) > 8640000000000000)
- {
- return double.NaN;
- }
- return (long) time + 0;
- }
- private static bool AreFinite(params double[] values)
- {
- for (int index = 0; index < values.Length; index++)
- {
- var value = values[index];
- if (double.IsNaN(value) || double.IsInfinity(value))
- {
- return false;
- }
- }
- return true;
- }
- }
- }
|