diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-01-14 12:01:05 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-01-15 20:13:48 +0100 |
commit | 5f5bcd549e2690e9cd040a1194faa77ed34a4403 (patch) | |
tree | 73678c63655f159db4928f6f934493a5116e3a90 /Userland | |
parent | 247caac7a8ee421efe3aa33f37f43d027e2187f1 (diff) | |
download | serenity-5f5bcd549e2690e9cd040a1194faa77ed34a4403.zip |
LibJS: Sort Date.prototype methods by spec order
When viewing the code side-by-side with the spec, it's much nicer when
everything is in the same order.
Also fixes the spec link for Date.prototype.getMilliseconds (it pointed
at setMilliseconds by mistake).
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/DatePrototype.cpp | 566 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/DatePrototype.h | 30 |
2 files changed, 301 insertions, 295 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp index 826143b5f7..1f9db3c1ef 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -35,50 +35,51 @@ void DatePrototype::initialize(GlobalObject& global_object) Object::initialize(global_object); u8 attr = Attribute::Writable | Attribute::Configurable; define_native_function(vm.names.getDate, get_date, 0, attr); - define_native_function(vm.names.setDate, set_date, 1, attr); define_native_function(vm.names.getDay, get_day, 0, attr); define_native_function(vm.names.getFullYear, get_full_year, 0, attr); - define_native_function(vm.names.setFullYear, set_full_year, 3, attr); - define_native_function(vm.names.getYear, get_year, 0, attr); - define_native_function(vm.names.setYear, set_year, 1, attr); define_native_function(vm.names.getHours, get_hours, 0, attr); - define_native_function(vm.names.setHours, set_hours, 4, attr); define_native_function(vm.names.getMilliseconds, get_milliseconds, 0, attr); - define_native_function(vm.names.setMilliseconds, set_milliseconds, 1, attr); define_native_function(vm.names.getMinutes, get_minutes, 0, attr); - define_native_function(vm.names.setMinutes, set_minutes, 3, attr); define_native_function(vm.names.getMonth, get_month, 0, attr); - define_native_function(vm.names.setMonth, set_month, 2, attr); define_native_function(vm.names.getSeconds, get_seconds, 0, attr); - define_native_function(vm.names.setSeconds, set_seconds, 2, attr); define_native_function(vm.names.getTime, get_time, 0, attr); - define_native_function(vm.names.setTime, set_time, 1, attr); define_native_function(vm.names.getTimezoneOffset, get_timezone_offset, 0, attr); define_native_function(vm.names.getUTCDate, get_utc_date, 0, attr); - define_native_function(vm.names.setUTCDate, set_date, 1, attr); // FIXME: This is a hack, Serenity doesn't currently support timezones other than UTC. define_native_function(vm.names.getUTCDay, get_utc_day, 0, attr); define_native_function(vm.names.getUTCFullYear, get_utc_full_year, 0, attr); - define_native_function(vm.names.setUTCFullYear, set_full_year, 3, attr); // FIXME: see above define_native_function(vm.names.getUTCHours, get_utc_hours, 0, attr); - define_native_function(vm.names.setUTCHours, set_hours, 4, attr); // FIXME: see above define_native_function(vm.names.getUTCMilliseconds, get_utc_milliseconds, 0, attr); - define_native_function(vm.names.setUTCMilliseconds, set_milliseconds, 1, attr); // FIXME: see above define_native_function(vm.names.getUTCMinutes, get_utc_minutes, 0, attr); - define_native_function(vm.names.setUTCMinutes, set_minutes, 3, attr); // FIXME: see above define_native_function(vm.names.getUTCMonth, get_utc_month, 0, attr); - define_native_function(vm.names.setUTCMonth, set_month, 2, attr); // FIXME: see above define_native_function(vm.names.getUTCSeconds, get_utc_seconds, 0, attr); - define_native_function(vm.names.setUTCSeconds, set_seconds, 2, attr); // FIXME: see above + define_native_function(vm.names.setDate, set_date, 1, attr); + define_native_function(vm.names.setFullYear, set_full_year, 3, attr); + define_native_function(vm.names.setHours, set_hours, 4, attr); + define_native_function(vm.names.setMilliseconds, set_milliseconds, 1, attr); + define_native_function(vm.names.setMinutes, set_minutes, 3, attr); + define_native_function(vm.names.setMonth, set_month, 2, attr); + define_native_function(vm.names.setSeconds, set_seconds, 2, attr); + define_native_function(vm.names.setTime, set_time, 1, attr); + define_native_function(vm.names.setUTCDate, set_date, 1, attr); // FIXME: This is a hack, Serenity doesn't currently support timezones other than UTC. + define_native_function(vm.names.setUTCFullYear, set_full_year, 3, attr); // FIXME: see above + define_native_function(vm.names.setUTCHours, set_hours, 4, attr); // FIXME: see above + define_native_function(vm.names.setUTCMilliseconds, set_milliseconds, 1, attr); // FIXME: see above + define_native_function(vm.names.setUTCMinutes, set_minutes, 3, attr); // FIXME: see above + define_native_function(vm.names.setUTCMonth, set_month, 2, attr); // FIXME: see above + define_native_function(vm.names.setUTCSeconds, set_seconds, 2, attr); // FIXME: see above define_native_function(vm.names.toDateString, to_date_string, 0, attr); - define_native_function(vm.names.toUTCString, to_utc_string, 0, attr); define_native_function(vm.names.toISOString, to_iso_string, 0, attr); + define_native_function(vm.names.toJSON, to_json, 1, attr); define_native_function(vm.names.toLocaleDateString, to_locale_date_string, 0, attr); define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr); define_native_function(vm.names.toLocaleTimeString, to_locale_time_string, 0, attr); - define_native_function(vm.names.toTimeString, to_time_string, 0, attr); define_native_function(vm.names.toString, to_string, 0, attr); - define_native_function(vm.names.toJSON, to_json, 1, attr); define_native_function(vm.names.toTemporalInstant, to_temporal_instant, 0, attr); + define_native_function(vm.names.toTimeString, to_time_string, 0, attr); + define_native_function(vm.names.toUTCString, to_utc_string, 0, attr); + + define_native_function(vm.names.getYear, get_year, 0, attr); + define_native_function(vm.names.setYear, set_year, 1, attr); // 21.4.4.45 Date.prototype [ @@toPrimitive ] ( hint ), https://tc39.es/ecma262/#sec-date.prototype-@@toprimitive define_native_function(*vm.well_known_symbol_to_primitive(), symbol_to_primitive, 1, Attribute::Configurable); @@ -121,142 +122,259 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_date) return Value(this_object->date()); } -// 21.4.4.20 Date.prototype.setDate ( date ), https://tc39.es/ecma262/#sec-date.prototype.setdate -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_date) +// 21.4.4.3 Date.prototype.getDay ( ), https://tc39.es/ecma262/#sec-date.prototype.getday +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_day) { auto* this_object = TRY(typed_this_object(global_object)); - auto& datetime = this_object->datetime(); + if (this_object->is_invalid()) + return js_nan(); - auto new_date_value = TRY(vm.argument(0).to_number(global_object)); - if (!new_date_value.is_finite_number()) { - this_object->set_is_invalid(true); + return Value(this_object->day()); +} + +// 21.4.4.4 Date.prototype.getFullYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getfullyear +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_full_year) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) return js_nan(); - } - auto new_date = new_date_value.as_i32(); - datetime.set_time(datetime.year(), datetime.month(), new_date, datetime.hour(), datetime.minute(), datetime.second()); - if (this_object->time() > Date::time_clip) { - this_object->set_is_invalid(true); + return Value(this_object->year()); +} + +// 21.4.4.5 Date.prototype.getHours ( ), https://tc39.es/ecma262/#sec-date.prototype.gethours +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_nan(); + + return Value(this_object->hours()); +} + +// 21.4.4.6 Date.prototype.getMilliseconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getmilliseconds +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_nan(); + + return Value(this_object->milliseconds()); +} + +// 21.4.4.7 Date.prototype.getMinutes ( ), https://tc39.es/ecma262/#sec-date.prototype.getminutes +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_nan(); + + return Value(this_object->minutes()); +} + +// 21.4.4.8 Date.prototype.getMonth ( ), https://tc39.es/ecma262/#sec-date.prototype.getmonth +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_nan(); + + return Value(this_object->month()); +} + +// 21.4.4.9 Date.prototype.getSeconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getseconds +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_seconds) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_nan(); + + return Value(this_object->seconds()); +} + +// 21.4.4.10 Date.prototype.getTime ( ), https://tc39.es/ecma262/#sec-date.prototype.gettime +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) return js_nan(); - } - this_object->set_is_invalid(false); return Value(this_object->time()); } -// 21.4.4.3 Date.prototype.getDay ( ), https://tc39.es/ecma262/#sec-date.prototype.getday -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_day) +// 21.4.4.11 Date.prototype.getTimezoneOffset ( ), https://tc39.es/ecma262/#sec-date.prototype.gettimezoneoffset +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_timezone_offset) { auto* this_object = TRY(typed_this_object(global_object)); if (this_object->is_invalid()) return js_nan(); - return Value(this_object->day()); + // FIXME: Make this actually do something once we support timezones instead of just UTC + return Value(0); } -// 21.4.4.4 Date.prototype.getFullYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getfullyear -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_full_year) +// 21.4.4.12 Date.prototype.getUTCDate ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcdate +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_date) { auto* this_object = TRY(typed_this_object(global_object)); if (this_object->is_invalid()) return js_nan(); - return Value(this_object->year()); + return Value(this_object->utc_date()); } -// 21.4.4.21 Date.prototype.setFullYear ( year [ , month [ , date ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setfullyear -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_full_year) +// 21.4.4.13 Date.prototype.getUTCDay ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcday +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_day) { auto* this_object = TRY(typed_this_object(global_object)); - auto& datetime = this_object->datetime(); + if (this_object->is_invalid()) + return js_nan(); - auto arg_or = [&vm, &global_object](size_t i, i32 fallback) -> ThrowCompletionOr<Value> { - return vm.argument_count() > i ? vm.argument(i).to_number(global_object) : Value(fallback); - }; + return Value(this_object->utc_day()); +} - auto new_year_value = TRY(vm.argument(0).to_number(global_object)); - if (!new_year_value.is_finite_number()) { - this_object->set_is_invalid(true); +// 21.4.4.14 Date.prototype.getUTCFullYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcfullyear +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_full_year) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) return js_nan(); - } - auto new_year = new_year_value.as_i32(); - auto new_month_value = TRY(arg_or(1, datetime.month() - 1)); - if (!new_month_value.is_finite_number()) { - this_object->set_is_invalid(true); + return Value(this_object->utc_full_year()); +} + +// 21.4.4.15 Date.prototype.getUTCHours ( ), https://tc39.es/ecma262/#sec-date.prototype.getutchours +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_hours) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) return js_nan(); - } - auto new_month = new_month_value.as_i32() + 1; // JS Months: 0 - 11, DateTime months: 1-12 - auto new_day_value = TRY(arg_or(2, datetime.day())); - if (!new_day_value.is_finite_number()) { - this_object->set_is_invalid(true); + return Value(this_object->utc_hours()); +} + +// 21.4.4.16 Date.prototype.getUTCMilliseconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcmilliseconds +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_milliseconds) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) return js_nan(); - } - auto new_day = new_day_value.as_i32(); - datetime.set_time(new_year, new_month, new_day, datetime.hour(), datetime.minute(), datetime.second()); - if (this_object->time() > Date::time_clip) { - this_object->set_is_invalid(true); + return Value(this_object->utc_milliseconds()); +} + +// 21.4.4.17 Date.prototype.getUTCMinutes ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcminutes +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_minutes) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) return js_nan(); - } - this_object->set_is_invalid(false); + return Value(this_object->utc_minutes()); +} - return Value(this_object->time()); +// 21.4.4.18 Date.prototype.getUTCMonth ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcmonth +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_month) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_nan(); + + return Value(this_object->utc_month()); } -// B.2.4.1 Date.prototype.getYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getyear -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_year) +// 21.4.4.19 Date.prototype.getUTCSeconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcseconds +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_seconds) { auto* this_object = TRY(typed_this_object(global_object)); if (this_object->is_invalid()) return js_nan(); - return Value(this_object->year() - 1900); + return Value(this_object->utc_seconds()); } -// B.2.4.2 Date.prototype.setYear ( year ), https://tc39.es/ecma262/#sec-date.prototype.setyear -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_year) +// 21.4.4.20 Date.prototype.setDate ( date ), https://tc39.es/ecma262/#sec-date.prototype.setdate +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_date) { auto* this_object = TRY(typed_this_object(global_object)); auto& datetime = this_object->datetime(); - auto new_year_value = TRY(vm.argument(0).to_number(global_object)); - if (!new_year_value.is_finite_number()) { + auto new_date_value = TRY(vm.argument(0).to_number(global_object)); + if (!new_date_value.is_finite_number()) { this_object->set_is_invalid(true); return js_nan(); } - auto new_year = new_year_value.as_i32(); - if (new_year >= 0 && new_year <= 99) - new_year += 1900; + auto new_date = new_date_value.as_i32(); - datetime.set_time(new_year, datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), datetime.second()); + datetime.set_time(datetime.year(), datetime.month(), new_date, datetime.hour(), datetime.minute(), datetime.second()); if (this_object->time() > Date::time_clip) { this_object->set_is_invalid(true); return js_nan(); } this_object->set_is_invalid(false); - return Value(this_object->time()); } -// 21.4.4.5 Date.prototype.getHours ( ), https://tc39.es/ecma262/#sec-date.prototype.gethours -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours) +// 21.4.4.21 Date.prototype.setFullYear ( year [ , month [ , date ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setfullyear +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_full_year) { auto* this_object = TRY(typed_this_object(global_object)); - if (this_object->is_invalid()) + auto& datetime = this_object->datetime(); + + auto arg_or = [&vm, &global_object](size_t i, i32 fallback) -> ThrowCompletionOr<Value> { + return vm.argument_count() > i ? vm.argument(i).to_number(global_object) : Value(fallback); + }; + + auto new_year_value = TRY(vm.argument(0).to_number(global_object)); + if (!new_year_value.is_finite_number()) { + this_object->set_is_invalid(true); return js_nan(); + } + auto new_year = new_year_value.as_i32(); - return Value(this_object->hours()); + auto new_month_value = TRY(arg_or(1, datetime.month() - 1)); + if (!new_month_value.is_finite_number()) { + this_object->set_is_invalid(true); + return js_nan(); + } + auto new_month = new_month_value.as_i32() + 1; // JS Months: 0 - 11, DateTime months: 1-12 + + auto new_day_value = TRY(arg_or(2, datetime.day())); + if (!new_day_value.is_finite_number()) { + this_object->set_is_invalid(true); + return js_nan(); + } + auto new_day = new_day_value.as_i32(); + + datetime.set_time(new_year, new_month, new_day, datetime.hour(), datetime.minute(), datetime.second()); + if (this_object->time() > Date::time_clip) { + this_object->set_is_invalid(true); + return js_nan(); + } + + this_object->set_is_invalid(false); + + return Value(this_object->time()); } // 21.4.4.22 Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] ), https://tc39.es/ecma262/#sec-date.prototype.sethours @@ -312,17 +430,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_hours) } // 21.4.4.23 Date.prototype.setMilliseconds ( ms ), https://tc39.es/ecma262/#sec-date.prototype.setmilliseconds -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->milliseconds()); -} - -// 21.4.4.23 Date.prototype.setMilliseconds ( ms ), https://tc39.es/ecma262/#sec-date.prototype.setmilliseconds JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_milliseconds) { auto* this_object = TRY(typed_this_object(global_object)); @@ -354,17 +461,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_milliseconds) return Value(this_object->time()); } -// 21.4.4.7 Date.prototype.getMinutes ( ), https://tc39.es/ecma262/#sec-date.prototype.getminutes -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->minutes()); -} - // 21.4.4.24 Date.prototype.setMinutes ( min [ , sec [ , ms ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setminutes JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_minutes) { @@ -410,17 +506,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_minutes) return Value(this_object->time()); } -// 21.4.4.8 Date.prototype.getMonth ( ), https://tc39.es/ecma262/#sec-date.prototype.getmonth -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->month()); -} - // 21.4.4.25 Date.prototype.setMonth ( month [ , date ] ), https://tc39.es/ecma262/#sec-date.prototype.setmonth JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_month) { @@ -456,17 +541,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_month) return Value(this_object->time()); } -// 21.4.4.9 Date.prototype.getSeconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getseconds -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_seconds) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->seconds()); -} - // 21.4.4.26 Date.prototype.setSeconds ( sec [ , ms ] ), https://tc39.es/ecma262/#sec-date.prototype.setseconds JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_seconds) { @@ -505,17 +579,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_seconds) return Value(this_object->time()); } -// 21.4.4.10 Date.prototype.getTime ( ), https://tc39.es/ecma262/#sec-date.prototype.gettime -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->time()); -} - // 21.4.4.27 Date.prototype.setTime ( time ), https://tc39.es/ecma262/#sec-date.prototype.settime JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_time) { @@ -541,106 +604,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_time) return Value(this_object->time()); } -// 21.4.4.11 Date.prototype.getTimezoneOffset ( ), https://tc39.es/ecma262/#sec-date.prototype.gettimezoneoffset -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_timezone_offset) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - // FIXME: Make this actually do something once we support timezones instead of just UTC - return Value(0); -} - -// 21.4.4.12 Date.prototype.getUTCDate ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcdate -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_date) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_date()); -} - -// 21.4.4.13 Date.prototype.getUTCDay ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcday -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_day) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_day()); -} - -// 21.4.4.14 Date.prototype.getUTCFullYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcfullyear -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_full_year) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_full_year()); -} - -// 21.4.4.15 Date.prototype.getUTCHours ( ), https://tc39.es/ecma262/#sec-date.prototype.getutchours -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_hours) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_hours()); -} - -// 21.4.4.16 Date.prototype.getUTCMilliseconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcmilliseconds -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_milliseconds) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_milliseconds()); -} - -// 21.4.4.18 Date.prototype.getUTCMonth ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcmonth -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_month) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_month()); -} - -// 21.4.4.17 Date.prototype.getUTCMinutes ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcminutes -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_minutes) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_minutes()); -} - -// 21.4.4.19 Date.prototype.getUTCSeconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcseconds -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_seconds) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_nan(); - - return Value(this_object->utc_seconds()); -} - // 21.4.4.35 Date.prototype.toDateString ( ), https://tc39.es/ecma262/#sec-date.prototype.todatestring JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_date_string) { @@ -653,36 +616,29 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_date_string) return js_string(vm, move(string)); } -// B.2.4.3 Date.prototype.toGMTString ( ), https://tc39.es/ecma262/#sec-date.prototype.togmtstring -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_gmt_string) -{ - // NOTE: The toUTCString method is preferred. The toGMTString method is provided principally for compatibility with old code. - return to_utc_string(vm, global_object); -} - -// 21.4.4.43 Date.prototype.toUTCString ( ), https://tc39.es/ecma262/#sec-date.prototype.toutcstring -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_utc_string) +// 21.4.4.36 Date.prototype.toISOString ( ), https://tc39.es/ecma262/#sec-date.prototype.toisostring +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_iso_string) { auto* this_object = TRY(typed_this_object(global_object)); if (this_object->is_invalid()) - return js_string(vm, "Invalid Date"); + return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidTimeValue); - // HTTP dates are always expressed in GMT. - auto string = this_object->gmt_date_string(); + auto string = this_object->iso_date_string(); return js_string(vm, move(string)); } -// 21.4.4.36 Date.prototype.toISOString ( ), https://tc39.es/ecma262/#sec-date.prototype.toisostring -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_iso_string) +// 21.4.4.37 Date.prototype.toJSON ( key ), https://tc39.es/ecma262/#sec-date.prototype.tojson +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_json) { - auto* this_object = TRY(typed_this_object(global_object)); + auto this_value = vm.this_value(global_object); - if (this_object->is_invalid()) - return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidTimeValue); + auto time_value = TRY(this_value.to_primitive(global_object, Value::PreferredType::Number)); - auto string = this_object->iso_date_string(); - return js_string(vm, move(string)); + if (time_value.is_number() && !time_value.is_finite_number()) + return js_null(); + + return TRY(this_value.invoke(global_object, vm.names.toISOString)); } static ThrowCompletionOr<Intl::DateTimeFormat*> construct_date_time_format(GlobalObject& global_object, Value locales, Value options) @@ -695,6 +651,7 @@ static ThrowCompletionOr<Intl::DateTimeFormat*> construct_date_time_format(Globa return static_cast<Intl::DateTimeFormat*>(date_time_format); } +// 21.4.4.38 Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-date.prototype.tolocaledatestring // 18.4.2 Date.prototype.toLocaleDateString ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sup-date.prototype.tolocaledatestring JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string) { @@ -719,6 +676,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string) return js_string(vm, move(formatted)); } +// 21.4.4.39 Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-date.prototype.tolocalestring // 18.4.1 Date.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sup-date.prototype.tolocalestring JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_string) { @@ -743,6 +701,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_string) return js_string(vm, move(formatted)); } +// 21.4.4.40 Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-date.prototype.tolocaletimestring // 18.4.3 Date.prototype.toLocaleTimeString ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sup-date.prototype.tolocaletimestring JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_time_string) { @@ -767,18 +726,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_time_string) return js_string(vm, move(formatted)); } -// 21.4.4.42 Date.prototype.toTimeString ( ), https://tc39.es/ecma262/#sec-date.prototype.totimestring -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_time_string) -{ - auto* this_object = TRY(typed_this_object(global_object)); - - if (this_object->is_invalid()) - return js_string(vm, "Invalid Date"); - - auto string = this_object->time_string(); - return js_string(vm, move(string)); -} - // 21.4.4.41 Date.prototype.toString ( ), https://tc39.es/ecma262/#sec-date.prototype.tostring JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_string) { @@ -791,19 +738,6 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_string) return js_string(vm, move(string)); } -// 21.4.4.37 Date.prototype.toJSON ( key ), https://tc39.es/ecma262/#sec-date.prototype.tojson -JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_json) -{ - auto this_value = vm.this_value(global_object); - - auto time_value = TRY(this_value.to_primitive(global_object, Value::PreferredType::Number)); - - if (time_value.is_number() && !time_value.is_finite_number()) - return js_null(); - - return TRY(this_value.invoke(global_object, vm.names.toISOString)); -} - // 14.1.1 Date.prototype.toTemporalInstant ( ), https://tc39.es/proposal-temporal/#sec-date.prototype.totemporalinstant JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_temporal_instant) { @@ -818,6 +752,31 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_temporal_instant) return MUST(Temporal::create_temporal_instant(global_object, *ns)); } +// 21.4.4.42 Date.prototype.toTimeString ( ), https://tc39.es/ecma262/#sec-date.prototype.totimestring +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_time_string) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_string(vm, "Invalid Date"); + + auto string = this_object->time_string(); + return js_string(vm, move(string)); +} + +// 21.4.4.43 Date.prototype.toUTCString ( ), https://tc39.es/ecma262/#sec-date.prototype.toutcstring +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_utc_string) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_string(vm, "Invalid Date"); + + // HTTP dates are always expressed in GMT. + auto string = this_object->gmt_date_string(); + return js_string(vm, move(string)); +} + // 21.4.4.45 Date.prototype [ @@toPrimitive ] ( hint ), https://tc39.es/ecma262/#sec-date.prototype-@@toprimitive JS_DEFINE_NATIVE_FUNCTION(DatePrototype::symbol_to_primitive) { @@ -838,4 +797,49 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::symbol_to_primitive) return TRY(this_value.as_object().ordinary_to_primitive(try_first)); } +// B.2.4.1 Date.prototype.getYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getyear +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_year) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + if (this_object->is_invalid()) + return js_nan(); + + return Value(this_object->year() - 1900); +} + +// B.2.4.2 Date.prototype.setYear ( year ), https://tc39.es/ecma262/#sec-date.prototype.setyear +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_year) +{ + auto* this_object = TRY(typed_this_object(global_object)); + + auto& datetime = this_object->datetime(); + + auto new_year_value = TRY(vm.argument(0).to_number(global_object)); + if (!new_year_value.is_finite_number()) { + this_object->set_is_invalid(true); + return js_nan(); + } + auto new_year = new_year_value.as_i32(); + if (new_year >= 0 && new_year <= 99) + new_year += 1900; + + datetime.set_time(new_year, datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), datetime.second()); + if (this_object->time() > Date::time_clip) { + this_object->set_is_invalid(true); + return js_nan(); + } + + this_object->set_is_invalid(false); + + return Value(this_object->time()); +} + +// B.2.4.3 Date.prototype.toGMTString ( ), https://tc39.es/ecma262/#sec-date.prototype.togmtstring +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_gmt_string) +{ + // NOTE: The toUTCString method is preferred. The toGMTString method is provided principally for compatibility with old code. + return to_utc_string(vm, global_object); +} + } diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.h b/Userland/Libraries/LibJS/Runtime/DatePrototype.h index 9c164aed40..4dc436f490 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.h @@ -21,24 +21,14 @@ public: private: JS_DECLARE_NATIVE_FUNCTION(get_date); - JS_DECLARE_NATIVE_FUNCTION(set_date); JS_DECLARE_NATIVE_FUNCTION(get_day); JS_DECLARE_NATIVE_FUNCTION(get_full_year); - JS_DECLARE_NATIVE_FUNCTION(set_full_year); - JS_DECLARE_NATIVE_FUNCTION(get_year); - JS_DECLARE_NATIVE_FUNCTION(set_year); JS_DECLARE_NATIVE_FUNCTION(get_hours); - JS_DECLARE_NATIVE_FUNCTION(set_hours); JS_DECLARE_NATIVE_FUNCTION(get_milliseconds); - JS_DECLARE_NATIVE_FUNCTION(set_milliseconds); JS_DECLARE_NATIVE_FUNCTION(get_minutes); - JS_DECLARE_NATIVE_FUNCTION(set_minutes); JS_DECLARE_NATIVE_FUNCTION(get_month); - JS_DECLARE_NATIVE_FUNCTION(set_month); JS_DECLARE_NATIVE_FUNCTION(get_seconds); - JS_DECLARE_NATIVE_FUNCTION(set_seconds); JS_DECLARE_NATIVE_FUNCTION(get_time); - JS_DECLARE_NATIVE_FUNCTION(set_time); JS_DECLARE_NATIVE_FUNCTION(get_timezone_offset); JS_DECLARE_NATIVE_FUNCTION(get_utc_date); JS_DECLARE_NATIVE_FUNCTION(get_utc_day); @@ -48,17 +38,29 @@ private: JS_DECLARE_NATIVE_FUNCTION(get_utc_minutes); JS_DECLARE_NATIVE_FUNCTION(get_utc_month); JS_DECLARE_NATIVE_FUNCTION(get_utc_seconds); + JS_DECLARE_NATIVE_FUNCTION(set_date); + JS_DECLARE_NATIVE_FUNCTION(set_full_year); + JS_DECLARE_NATIVE_FUNCTION(set_hours); + JS_DECLARE_NATIVE_FUNCTION(set_milliseconds); + JS_DECLARE_NATIVE_FUNCTION(set_minutes); + JS_DECLARE_NATIVE_FUNCTION(set_month); + JS_DECLARE_NATIVE_FUNCTION(set_seconds); + JS_DECLARE_NATIVE_FUNCTION(set_time); JS_DECLARE_NATIVE_FUNCTION(to_date_string); - JS_DECLARE_NATIVE_FUNCTION(to_gmt_string); - JS_DECLARE_NATIVE_FUNCTION(to_utc_string); JS_DECLARE_NATIVE_FUNCTION(to_iso_string); + JS_DECLARE_NATIVE_FUNCTION(to_json); JS_DECLARE_NATIVE_FUNCTION(to_locale_date_string); JS_DECLARE_NATIVE_FUNCTION(to_locale_string); JS_DECLARE_NATIVE_FUNCTION(to_locale_time_string); - JS_DECLARE_NATIVE_FUNCTION(to_time_string); JS_DECLARE_NATIVE_FUNCTION(to_string); - JS_DECLARE_NATIVE_FUNCTION(to_json); JS_DECLARE_NATIVE_FUNCTION(to_temporal_instant); + JS_DECLARE_NATIVE_FUNCTION(to_time_string); + JS_DECLARE_NATIVE_FUNCTION(to_utc_string); + + JS_DECLARE_NATIVE_FUNCTION(get_year); + JS_DECLARE_NATIVE_FUNCTION(set_year); + JS_DECLARE_NATIVE_FUNCTION(to_gmt_string); + JS_DECLARE_NATIVE_FUNCTION(symbol_to_primitive); }; |