1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 04:07:44 +00:00

LibJS: Add Date methods: setHours, setMinutes, setSeconds, setMilliseconds

This commit is contained in:
tuqqu 2021-03-19 22:12:08 +03:00 committed by Andreas Kling
parent 974a981ded
commit 43f0c92bcd
8 changed files with 190 additions and 1 deletions

View file

@ -201,7 +201,11 @@ namespace JS {
P(round) \
P(set) \
P(setFullYear) \
P(setHours) \
P(setMilliseconds) \
P(setMinutes) \
P(setPrototypeOf) \
P(setSeconds) \
P(shift) \
P(sign) \
P(sin) \

View file

@ -63,6 +63,11 @@ public:
int utc_month() const;
int utc_seconds() const;
void set_milliseconds(u16 milliseconds)
{
m_milliseconds = milliseconds;
}
String date_string() const { return m_datetime.to_string("%a %b %d %Y"); }
// FIXME: Deal with timezones once SerenityOS has a working tzset(3)
String time_string() const { return m_datetime.to_string("%T GMT+0000 (UTC)"); }

View file

@ -62,10 +62,14 @@ void DatePrototype::initialize(GlobalObject& global_object)
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.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.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.getUTCDate, get_utc_date, 0, attr);
define_native_function(vm.names.getUTCDay, get_utc_day, 0, attr);
@ -150,7 +154,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_full_year)
}
datetime.set_time(new_year, new_month, new_day, datetime.hour(), datetime.minute(), datetime.second());
return Value { this_object->time() };
return Value(this_object->time());
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours)
@ -161,6 +165,48 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours)
return Value(static_cast<double>(this_object->hours()));
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_hours)
{
auto* this_object = typed_this(vm, global_object);
if (!this_object)
return {};
auto new_hours = vm.argument(0).to_i32(global_object);
if (vm.exception())
return {};
auto& datetime = this_object->datetime();
i32 new_minutes;
if (vm.argument_count() >= 2) {
new_minutes = vm.argument(1).to_i32(global_object);
if (vm.exception())
return {};
} else {
new_minutes = datetime.minute();
}
i32 new_seconds;
if (vm.argument_count() >= 3) {
new_seconds = vm.argument(2).to_i32(global_object);
if (vm.exception())
return {};
} else {
new_seconds = datetime.second();
}
if (vm.argument_count() >= 4) {
auto new_milliseconds = vm.argument(3).to_i32(global_object);
if (vm.exception())
return {};
new_seconds += new_milliseconds / 1000;
this_object->set_milliseconds(new_milliseconds % 1000);
}
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), new_hours, new_minutes, new_seconds);
return Value(this_object->time());
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds)
{
auto* this_object = typed_this(vm, global_object);
@ -169,6 +215,27 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds)
return Value(static_cast<double>(this_object->milliseconds()));
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_milliseconds)
{
auto* this_object = typed_this(vm, global_object);
if (!this_object)
return {};
auto new_milliseconds = vm.argument(0).to_i32(global_object);
if (vm.exception())
return {};
this_object->set_milliseconds(new_milliseconds % 1000);
auto added_seconds = new_milliseconds / 1000;
if (added_seconds > 0) {
auto& datetime = this_object->datetime();
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), datetime.second() + added_seconds);
}
return Value(this_object->time());
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes)
{
auto* this_object = typed_this(vm, global_object);
@ -177,6 +244,39 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes)
return Value(static_cast<double>(this_object->minutes()));
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_minutes)
{
auto* this_object = typed_this(vm, global_object);
if (!this_object)
return {};
auto new_minutes = vm.argument(0).to_i32(global_object);
if (vm.exception())
return {};
auto& datetime = this_object->datetime();
i32 new_seconds;
if (vm.argument_count() >= 2) {
new_seconds = vm.argument(1).to_i32(global_object);
if (vm.exception())
return {};
} else {
new_seconds = datetime.second();
}
if (vm.argument_count() >= 3) {
auto new_milliseconds = vm.argument(2).to_i32(global_object);
if (vm.exception())
return {};
new_seconds += new_milliseconds / 1000;
this_object->set_milliseconds(new_milliseconds % 1000);
}
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), new_minutes, new_seconds);
return Value(this_object->time());
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month)
{
auto* this_object = typed_this(vm, global_object);
@ -193,6 +293,30 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_seconds)
return Value(static_cast<double>(this_object->seconds()));
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_seconds)
{
auto* this_object = typed_this(vm, global_object);
if (!this_object)
return {};
auto new_seconds = vm.argument(0).to_i32(global_object);
if (vm.exception())
return {};
if (vm.argument_count() >= 2) {
auto new_milliseconds = vm.argument(1).to_i32(global_object);
if (vm.exception())
return {};
new_seconds += new_milliseconds / 1000;
this_object->set_milliseconds(new_milliseconds % 1000);
}
auto& datetime = this_object->datetime();
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), new_seconds);
return Value(this_object->time());
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time)
{
auto* this_object = typed_this(vm, global_object);

View file

@ -44,10 +44,14 @@ private:
JS_DECLARE_NATIVE_FUNCTION(get_full_year);
JS_DECLARE_NATIVE_FUNCTION(set_full_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(get_seconds);
JS_DECLARE_NATIVE_FUNCTION(set_seconds);
JS_DECLARE_NATIVE_FUNCTION(get_time);
JS_DECLARE_NATIVE_FUNCTION(get_utc_date);
JS_DECLARE_NATIVE_FUNCTION(get_utc_day);

View file

@ -0,0 +1,21 @@
test("basic functionality", () => {
let d = new Date(2000, 2, 1);
d.setHours(2);
expect(d.getHours()).toBe(2);
d.setHours(2, 30);
expect(d.getHours()).toBe(2);
expect(d.getMinutes()).toBe(30);
d.setHours(2, 30, 50);
expect(d.getHours()).toBe(2);
expect(d.getMinutes()).toBe(30);
expect(d.getSeconds()).toBe(50);
d.setHours(2, 30, 50, 600);
expect(d.getHours()).toBe(2);
expect(d.getMinutes()).toBe(30);
expect(d.getSeconds()).toBe(50);
expect(d.getMilliseconds()).toBe(600);
});

View file

@ -0,0 +1,6 @@
test("basic functionality", () => {
let d = new Date(2000, 2, 1);
d.setMilliseconds(600);
expect(d.getMilliseconds()).toBe(600);
});

View file

@ -0,0 +1,15 @@
test("basic functionality", () => {
let d = new Date(2000, 2, 1);
d.setMinutes(30);
expect(d.getMinutes()).toBe(30);
d.setMinutes(30, 50);
expect(d.getMinutes()).toBe(30);
expect(d.getSeconds()).toBe(50);
d.setMinutes(30, 50, 600);
expect(d.getMinutes()).toBe(30);
expect(d.getSeconds()).toBe(50);
expect(d.getMilliseconds()).toBe(600);
});

View file

@ -0,0 +1,10 @@
test("basic functionality", () => {
let d = new Date(2000, 2, 1);
d.setSeconds(50);
expect(d.getSeconds()).toBe(50);
d.setSeconds(50, 600);
expect(d.getSeconds()).toBe(50);
expect(d.getMilliseconds()).toBe(600);
});