diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index c5910cbaff..b731a74393 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -223,6 +223,7 @@ namespace JS { P(setMonth) \ P(setPrototypeOf) \ P(setSeconds) \ + P(setTime) \ P(setYear) \ P(shift) \ P(sign) \ diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp index 3acf65c054..5594757bb4 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -56,6 +56,7 @@ void DatePrototype::initialize(GlobalObject& global_object) 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.getUTCDay, get_utc_day, 0, attr); @@ -505,6 +506,29 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time) return Value(this_object->time()); } +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_time) +{ + auto* this_object = typed_this(vm, global_object); + if (!this_object) + return {}; + + auto new_time_value = vm.argument(0).to_number(global_object); + if (vm.exception()) + return {}; + if (!new_time_value.is_finite_number()) { + this_object->set_is_invalid(true); + return js_nan(); + } + auto new_time = new_time_value.as_double(); + + this_object->set_is_invalid(false); + + auto new_date_time = Core::DateTime::from_timestamp(static_cast(new_time / 1000)); + this_object->datetime().set_time(new_date_time.year(), new_date_time.month(), new_date_time.day(), new_date_time.hour(), new_date_time.minute(), new_date_time.second()); + this_object->set_milliseconds(static_cast(fmod(new_time, 1000))); + return Value(this_object->time()); +} + JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_timezone_offset) { auto* this_object = typed_this(vm, global_object); diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.h b/Userland/Libraries/LibJS/Runtime/DatePrototype.h index c994e93b95..93769f4791 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.h @@ -37,6 +37,7 @@ private: 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); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setTime.js b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setTime.js new file mode 100644 index 0000000000..c23267df4a --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setTime.js @@ -0,0 +1,47 @@ +test("no arguments", () => { + let date = new Date(2021, 0, 1); + date.setTime(); + expect(date.getTime()).toBe(NaN); +}); + +test("NaN or undefined as only argument", () => { + let date = new Date(2021, 0, 1); + date.setTime(NaN); + expect(date.getTime()).toBe(NaN); + + date = new Date(2021, 0, 1); + date.setTime(undefined); + expect(date.getTime()).toBe(NaN); + + date = new Date(2021, 0, 1); + date.setTime("a"); + expect(date.getTime()).toBe(NaN); +}); + +test("Timestamp as argument", () => { + let date = new Date(2021, 0, 1); + + date.setTime(1622993746000); + expect(date.getDate()).toBe(6); + expect(date.getMonth()).toBe(5); + expect(date.getFullYear()).toBe(2021); + expect(date.getUTCHours()).toBe(15); + expect(date.getUTCMinutes()).toBe(35); + expect(date.getUTCSeconds()).toBe(46); + expect(date.getUTCMilliseconds()).toBe(0); +}); + +test("Make Invalid Date valid again", () => { + let date = new Date(2021, 0, 1); + date.setTime(NaN); + expect(date.getTime()).toBe(NaN); + + date.setTime(1622993746000); + expect(date.getDate()).toBe(6); + expect(date.getMonth()).toBe(5); + expect(date.getFullYear()).toBe(2021); + expect(date.getUTCHours()).toBe(15); + expect(date.getUTCMinutes()).toBe(35); + expect(date.getUTCSeconds()).toBe(46); + expect(date.getUTCMilliseconds()).toBe(0); +});