summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-01-15 15:51:17 -0500
committerAndreas Kling <kling@serenityos.org>2022-01-16 11:07:02 +0100
commit51bc973eccca853c69110525235916b274598d0e (patch)
treeb8c4c175567ba4b90a834afe27564426d1992432
parent6998c0a796f37b5e3f591160db2d6feb8d973a8b (diff)
downloadserenity-51bc973eccca853c69110525235916b274598d0e.zip
LibJS: Implement Date.prototype.setUTCHours
-rw-r--r--Userland/Libraries/LibJS/Runtime/DatePrototype.cpp36
-rw-r--r--Userland/Libraries/LibJS/Runtime/DatePrototype.h1
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCHours.js65
3 files changed, 101 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
index 8d74984245..2f64d16946 100644
--- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
@@ -74,7 +74,7 @@ void DatePrototype::initialize(GlobalObject& global_object)
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.setUTCHours, set_utc_hours, 4, attr);
define_native_function(vm.names.setUTCMilliseconds, set_utc_milliseconds, 1, attr);
define_native_function(vm.names.setUTCMinutes, set_utc_minutes, 3, attr);
define_native_function(vm.names.setUTCMonth, set_utc_month, 2, attr);
@@ -619,6 +619,40 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_time)
return time;
}
+// 21.4.4.30 Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setutchours
+JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_hours)
+{
+ // 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 h be ? ToNumber(hour).
+ auto hour = TRY(vm.argument(0).to_number(global_object));
+
+ // 3. If min is not present, let m be MinFromTime(t); otherwise, let m be ? ToNumber(min).
+ auto minute = TRY(argument_or_value(global_object, 1, min_from_time(time)));
+
+ // 4. If sec is not present, let s be SecFromTime(t); otherwise, let s be ? ToNumber(sec).
+ auto second = TRY(argument_or_value(global_object, 2, sec_from_time(time)));
+
+ // 5. If ms is not present, let milli be msFromTime(t); otherwise, let milli be ? ToNumber(ms).
+ auto millisecond = TRY(argument_or_value(global_object, 3, ms_from_time(time)));
+
+ // 6. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
+ auto new_time = make_time(global_object, hour, minute, second, millisecond);
+ auto date = make_date(Value(day(time)), new_time);
+
+ // 7. Let v be TimeClip(newDate).
+ date = time_clip(global_object, date);
+
+ // 8. 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(date.as_double());
+
+ // 9. Return v.
+ return date;
+}
+
// 21.4.4.31 Date.prototype.setUTCMilliseconds ( ms ), https://tc39.es/ecma262/#sec-date.prototype.setutcmilliseconds
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_milliseconds)
{
diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.h b/Userland/Libraries/LibJS/Runtime/DatePrototype.h
index 619c8dbd2d..5005ef4570 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_hours);
JS_DECLARE_NATIVE_FUNCTION(set_utc_milliseconds);
JS_DECLARE_NATIVE_FUNCTION(set_utc_minutes);
JS_DECLARE_NATIVE_FUNCTION(set_utc_month);
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCHours.js b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCHours.js
new file mode 100644
index 0000000000..b69faa4d24
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setUTCHours.js
@@ -0,0 +1,65 @@
+describe("errors", () => {
+ test("called on non-Date object", () => {
+ expect(() => {
+ Date.prototype.setUTCHours();
+ }).toThrowWithMessage(TypeError, "Not an object of type Date");
+ });
+
+ test("called with non-numeric parameters", () => {
+ expect(() => {
+ new Date().setUTCHours(Symbol.hasInstance);
+ }).toThrowWithMessage(TypeError, "Cannot convert symbol to number");
+
+ expect(() => {
+ new Date().setUTCHours(8, Symbol.hasInstance);
+ }).toThrowWithMessage(TypeError, "Cannot convert symbol to number");
+
+ expect(() => {
+ new Date().setUTCHours(8, 9, Symbol.hasInstance);
+ }).toThrowWithMessage(TypeError, "Cannot convert symbol to number");
+
+ expect(() => {
+ new Date().setUTCHours(8, 9, 10, Symbol.hasInstance);
+ }).toThrowWithMessage(TypeError, "Cannot convert symbol to number");
+ });
+});
+
+describe("correct behavior", () => {
+ const d = new Date(2000, 2, 1);
+
+ test("basic functionality", () => {
+ d.setUTCHours(8);
+ expect(d.getUTCHours()).toBe(8);
+
+ d.setUTCHours(9, 15);
+ expect(d.getUTCHours()).toBe(9);
+ expect(d.getUTCMinutes()).toBe(15);
+
+ d.setUTCHours(10, 25, 35);
+ expect(d.getUTCHours()).toBe(10);
+ expect(d.getUTCMinutes()).toBe(25);
+ expect(d.getUTCSeconds()).toBe(35);
+
+ d.setUTCHours(11, 35, 45, 789);
+ expect(d.getUTCHours()).toBe(11);
+ expect(d.getUTCMinutes()).toBe(35);
+ expect(d.getUTCSeconds()).toBe(45);
+ expect(d.getUTCMilliseconds()).toBe(789);
+
+ d.setUTCHours("");
+ expect(d.getUTCHours()).toBe(0);
+
+ d.setUTCHours("a");
+ expect(d.getUTCHours()).toBe(NaN);
+ });
+
+ test("NaN", () => {
+ d.setUTCHours(NaN);
+ expect(d.getUTCHours()).toBeNaN();
+ });
+
+ test("time clip", () => {
+ d.setUTCHours(8.65e15);
+ expect(d.getUTCHours()).toBeNaN();
+ });
+});