summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-01-15 16:01:20 -0500
committerAndreas Kling <kling@serenityos.org>2022-01-16 11:07:02 +0100
commitc74f75b910b7f8724b765e19e94048db2e3efcea (patch)
treeea0e562bed9209e1bb09ece9c66f16c7445ef2dc
parent0d73da0328feeee063054b9ea532e1760854c48b (diff)
downloadserenity-c74f75b910b7f8724b765e19e94048db2e3efcea.zip
LibJS: Implement Date.prototype.setUTCDate
-rw-r--r--Userland/Libraries/LibJS/Runtime/DatePrototype.cpp30
-rw-r--r--Userland/Libraries/LibJS/Runtime/DatePrototype.h1
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCDate.js35
3 files changed, 65 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
index f9f8961c6e..5aedcdd71b 100644
--- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
@@ -72,7 +72,7 @@ void DatePrototype::initialize(GlobalObject& global_object)
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.setUTCDate, set_utc_date, 1, attr);
define_native_function(vm.names.setUTCFullYear, set_utc_full_year, 3, attr);
define_native_function(vm.names.setUTCHours, set_utc_hours, 4, attr);
define_native_function(vm.names.setUTCMilliseconds, set_utc_milliseconds, 1, attr);
@@ -619,6 +619,34 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_time)
return time;
}
+// 21.4.4.28 Date.prototype.setUTCDate ( date ), https://tc39.es/ecma262/#sec-date.prototype.setutcdate
+JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_date)
+{
+ // 1. Let t be LocalTime(? thisTimeValue(this value)).
+ auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object)));
+ auto time = local_time(this_time.as_double());
+
+ // 2. Let dt be ? ToNumber(date).
+ auto date = TRY(vm.argument(0).to_number(global_object));
+
+ // 3. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
+ auto year = Value(year_from_time(time));
+ auto month = Value(month_from_time(time));
+
+ auto day = make_day(global_object, year, month, date);
+ auto new_date = make_date(day, Value(time_within_day(time)));
+
+ // 4. Let v be TimeClip(newDate).
+ new_date = time_clip(global_object, new_date);
+
+ // 5. Set the [[DateValue]] internal slot of this Date object to v.
+ auto* this_object = MUST(typed_this_object(global_object));
+ this_object->set_date_value(new_date.as_double());
+
+ // 6. Return v.
+ return new_date;
+}
+
// 21.4.4.29 Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setutcfullyear
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_full_year)
{
diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.h b/Userland/Libraries/LibJS/Runtime/DatePrototype.h
index 87df1305fb..621a0912a5 100644
--- a/Userland/Libraries/LibJS/Runtime/DatePrototype.h
+++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.h
@@ -46,6 +46,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(set_month);
JS_DECLARE_NATIVE_FUNCTION(set_seconds);
JS_DECLARE_NATIVE_FUNCTION(set_time);
+ JS_DECLARE_NATIVE_FUNCTION(set_utc_date);
JS_DECLARE_NATIVE_FUNCTION(set_utc_full_year);
JS_DECLARE_NATIVE_FUNCTION(set_utc_hours);
JS_DECLARE_NATIVE_FUNCTION(set_utc_milliseconds);
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCDate.js b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCDate.js
new file mode 100644
index 0000000000..a6d41f7ae9
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCDate.js
@@ -0,0 +1,35 @@
+describe("errors", () => {
+ test("called on non-Date object", () => {
+ expect(() => {
+ Date.prototype.setUTCDate();
+ }).toThrowWithMessage(TypeError, "Not an object of type Date");
+ });
+
+ test("called with non-numeric parameters", () => {
+ expect(() => {
+ new Date().setUTCDate(Symbol.hasInstance);
+ }).toThrowWithMessage(TypeError, "Cannot convert symbol to number");
+ });
+});
+
+describe("correct behavior", () => {
+ const d = new Date(2000, 2, 1);
+
+ test("basic functionality", () => {
+ d.setUTCDate(8);
+ expect(d.getUTCDate()).toBe(8);
+
+ d.setUTCDate("a");
+ expect(d.getUTCDate()).toBe(NaN);
+ });
+
+ test("NaN", () => {
+ d.setUTCDate(NaN);
+ expect(d.getUTCDate()).toBeNaN();
+ });
+
+ test("time clip", () => {
+ d.setUTCDate(8.65e15);
+ expect(d.getUTCDate()).toBeNaN();
+ });
+});