diff --git a/Libraries/LibJS/Runtime/Date.cpp b/Libraries/LibJS/Runtime/Date.cpp index e50a925b003..08858899ef9 100644 --- a/Libraries/LibJS/Runtime/Date.cpp +++ b/Libraries/LibJS/Runtime/Date.cpp @@ -49,11 +49,47 @@ Date::~Date() { } -String Date::iso_date_string() const +tm Date::to_utc_tm() const { time_t timestamp = m_datetime.timestamp(); struct tm tm; gmtime_r(×tamp, &tm); + return tm; +} + +int Date::utc_date() const +{ + return to_utc_tm().tm_mday; +} + +int Date::utc_day() const +{ + return to_utc_tm().tm_wday; +} + +int Date::utc_full_year() const +{ + return to_utc_tm().tm_year + 1900; +} + +int Date::utc_hours() const +{ + return to_utc_tm().tm_hour; +} + +int Date::utc_minutes() const +{ + return to_utc_tm().tm_min; +} + +int Date::utc_month() const +{ + return to_utc_tm().tm_mon; +} + +String Date::iso_date_string() const +{ + auto tm = to_utc_tm(); int year = tm.tm_year + 1900; int month = tm.tm_mon + 1; diff --git a/Libraries/LibJS/Runtime/Date.h b/Libraries/LibJS/Runtime/Date.h index 3fd7d231471..b4d9370818a 100644 --- a/Libraries/LibJS/Runtime/Date.h +++ b/Libraries/LibJS/Runtime/Date.h @@ -54,6 +54,15 @@ public: double time() const { return datetime().timestamp() * 1000.0 + milliseconds(); } int year() const { return datetime().day(); } + int utc_date() const; + int utc_day() const; + int utc_full_year() const; + int utc_hours() const; + int utc_milliseconds() const { return milliseconds(); } + int utc_minutes() const; + int utc_month() const; + int utc_seconds() const { return seconds(); } + 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)"); } @@ -75,6 +84,7 @@ public: } private: + tm to_utc_tm() const; virtual bool is_date() const final { return true; } Core::DateTime m_datetime; diff --git a/Libraries/LibJS/Runtime/DatePrototype.cpp b/Libraries/LibJS/Runtime/DatePrototype.cpp index 77837c33513..3bc83519670 100644 --- a/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -66,6 +66,14 @@ void DatePrototype::initialize(GlobalObject& global_object) define_native_function("getMonth", get_month, 0, attr); define_native_function("getSeconds", get_seconds, 0, attr); define_native_function("getTime", get_time, 0, attr); + define_native_function("getUTCDate", get_utc_date, 0, attr); + define_native_function("getUTCDay", get_utc_day, 0, attr); + define_native_function("getUTCFullYear", get_utc_full_year, 0, attr); + define_native_function("getUTCHours", get_utc_hours, 0, attr); + define_native_function("getUTCMilliseconds", get_utc_milliseconds, 0, attr); + define_native_function("getUTCMinutes", get_utc_minutes, 0, attr); + define_native_function("getUTCMonth", get_utc_month, 0, attr); + define_native_function("getUTCSeconds", get_utc_seconds, 0, attr); define_native_function("toDateString", to_date_string, 0, attr); define_native_function("toISOString", to_iso_string, 0, attr); define_native_function("toLocaleDateString", to_locale_date_string, 0, attr); @@ -155,9 +163,71 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time) auto* this_object = typed_this(interpreter, global_object); if (!this_object) return {}; - auto seconds = this_object->datetime().timestamp(); - auto milliseconds = this_object->milliseconds(); - return Value(static_cast(seconds * 1000 + milliseconds)); + return Value(this_object->time()); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_date) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_date())); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_day) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_day())); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_full_year) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_full_year())); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_hours) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_hours())); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_milliseconds) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_milliseconds())); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_month) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_month())); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_minutes) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_minutes())); +} + +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_seconds) +{ + auto* this_object = typed_this(interpreter, global_object); + if (!this_object) + return {}; + return Value(static_cast(this_object->utc_seconds())); } JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_date_string) diff --git a/Libraries/LibJS/Runtime/DatePrototype.h b/Libraries/LibJS/Runtime/DatePrototype.h index 2c800f41216..d43404c467f 100644 --- a/Libraries/LibJS/Runtime/DatePrototype.h +++ b/Libraries/LibJS/Runtime/DatePrototype.h @@ -47,6 +47,14 @@ private: JS_DECLARE_NATIVE_FUNCTION(get_month); JS_DECLARE_NATIVE_FUNCTION(get_seconds); JS_DECLARE_NATIVE_FUNCTION(get_time); + JS_DECLARE_NATIVE_FUNCTION(get_utc_date); + JS_DECLARE_NATIVE_FUNCTION(get_utc_day); + JS_DECLARE_NATIVE_FUNCTION(get_utc_full_year); + JS_DECLARE_NATIVE_FUNCTION(get_utc_hours); + JS_DECLARE_NATIVE_FUNCTION(get_utc_milliseconds); + 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(to_date_string); JS_DECLARE_NATIVE_FUNCTION(to_iso_string); JS_DECLARE_NATIVE_FUNCTION(to_locale_date_string); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCDate.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCDate.js new file mode 100644 index 00000000000..d207385bad7 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCDate.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + let d = new Date(); + expect(d.getUTCDate()).toBe(d.getUTCDate()); + expect(d.getUTCDate()).not.toBeNaN(); + expect(d.getUTCDate()).toBeGreaterThanOrEqual(1); + expect(d.getUTCDate()).toBeLessThanOrEqual(31); +}); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCDay.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCDay.js new file mode 100644 index 00000000000..aec696be4a1 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCDay.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + var d = new Date(); + expect(d.getUTCDay()).toBe(d.getUTCDay()); + expect(d.getUTCDay()).not.toBeNaN(); + expect(d.getUTCDay()).toBeGreaterThanOrEqual(0); + expect(d.getUTCDay()).toBeLessThanOrEqual(6); +}); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCFullYear.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCFullYear.js new file mode 100644 index 00000000000..50336d81787 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCFullYear.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + var d = new Date(); + expect(d.getUTCFullYear()).toBe(d.getUTCFullYear()); + expect(d.getUTCFullYear()).not.toBeNaN(); + expect(d.getUTCFullYear()).toBe(d.getUTCFullYear()); + expect(d.getUTCFullYear()).toBeGreaterThanOrEqual(2020); +}); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCHours.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCHours.js new file mode 100644 index 00000000000..298ed178e5f --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCHours.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + var d = new Date(); + expect(d.getUTCHours()).toBe(d.getUTCHours()); + expect(d.getUTCHours()).not.toBeNaN(); + expect(d.getUTCHours()).toBeGreaterThanOrEqual(0); + expect(d.getUTCHours()).toBeLessThanOrEqual(23); +}); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMilliseconds.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMilliseconds.js new file mode 100644 index 00000000000..f53ea70428f --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMilliseconds.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + var d = new Date(); + expect(d.getUTCMilliseconds()).toBe(d.getUTCMilliseconds()); + expect(d.getUTCMilliseconds()).not.toBeNaN(); + expect(d.getUTCMilliseconds()).toBeGreaterThanOrEqual(0); + expect(d.getUTCMilliseconds()).toBeLessThanOrEqual(999); +}); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMinutes.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMinutes.js new file mode 100644 index 00000000000..6b1146331cf --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMinutes.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + var d = new Date(); + expect(d.getUTCMinutes()).toBe(d.getUTCMinutes()); + expect(d.getUTCMinutes()).not.toBeNaN(); + expect(d.getUTCMinutes()).toBeGreaterThanOrEqual(0); + expect(d.getUTCMinutes()).toBeLessThanOrEqual(59); +}); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMonth.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMonth.js new file mode 100644 index 00000000000..8b031497de5 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCMonth.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + var d = new Date(); + expect(d.getUTCMonth()).toBe(d.getUTCMonth()); + expect(d.getUTCMonth()).not.toBeNaN(); + expect(d.getUTCMonth()).toBeGreaterThanOrEqual(0); + expect(d.getUTCMonth()).toBeLessThanOrEqual(11); +}); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCSeconds.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCSeconds.js new file mode 100644 index 00000000000..d087a3c4c82 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.getUTCSeconds.js @@ -0,0 +1,7 @@ +test("basic functionality", () => { + var d = new Date(); + expect(d.getUTCSeconds()).toBe(d.getUTCSeconds()); + expect(d.getUTCSeconds()).not.toBeNaN(); + expect(d.getUTCSeconds()).toBeGreaterThanOrEqual(0); + expect(d.getUTCSeconds()).toBeLessThanOrEqual(59); +});