diff --git a/Libraries/LibJS/Runtime/DateConstructor.cpp b/Libraries/LibJS/Runtime/DateConstructor.cpp index 583230c1b1d..1f614ef6260 100644 --- a/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -195,6 +195,13 @@ Value DateConstructor::construct(Interpreter& interpreter, Function&) int seconds = arg_or(5, 0); int milliseconds = arg_or(6, 0); + seconds += milliseconds / 1000; + milliseconds %= 1000; + if (milliseconds < 0) { + seconds -= 1; + milliseconds += 1000; + } + if (year >= 0 && year <= 99) year += 1900; int month = month_index + 1; diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.js b/Libraries/LibJS/Tests/builtins/Date/Date.js index 80551e638b2..e232b79137c 100644 --- a/Libraries/LibJS/Tests/builtins/Date/Date.js +++ b/Libraries/LibJS/Tests/builtins/Date/Date.js @@ -30,11 +30,12 @@ test("tuple constructor", () => { // The tuple constructor takes a date in local time. expect(new Date(2019, 11).getFullYear()).toBe(2019); expect(new Date(2019, 11).getMonth()).toBe(11); - expect(new Date(2019, 11).getDate()).toBe(1); // getDay() returns day of week, getDate() returnsn day in month + expect(new Date(2019, 11).getDate()).toBe(1); // getDay() returns day of week, getDate() returns day in month expect(new Date(2019, 11).getHours()).toBe(0); expect(new Date(2019, 11).getMinutes()).toBe(0); expect(new Date(2019, 11).getSeconds()).toBe(0); expect(new Date(2019, 11).getMilliseconds()).toBe(0); + expect(new Date(2019, 11).getDay()).toBe(0); let date = new Date(2019, 11, 15, 9, 16, 14, 123); // Note: Month is 0-based. expect(date.getFullYear()).toBe(2019); @@ -44,6 +45,7 @@ test("tuple constructor", () => { expect(date.getMinutes()).toBe(16); expect(date.getSeconds()).toBe(14); expect(date.getMilliseconds()).toBe(123); + expect(date.getDay()).toBe(0); // getTime() returns a time stamp in UTC, but we can at least check it's in the right interval, which will be true independent of the local timezone if the range is big enough. let timestamp_lower_bound = 1575072000000; // 2019-12-01T00:00:00Z @@ -51,3 +53,25 @@ test("tuple constructor", () => { expect(date.getTime()).toBeGreaterThan(timestamp_lower_bound); expect(date.getTime()).toBeLessThan(timestamp_upper_bound); }); + +test("tuple constructor overflow", () => { + let date = new Date(2019, 13, 33, 30, 70, 80, 2345); + expect(date.getFullYear()).toBe(2020); + expect(date.getMonth()).toBe(2); + expect(date.getDate()).toBe(5); + expect(date.getHours()).toBe(7); + expect(date.getMinutes()).toBe(11); + expect(date.getSeconds()).toBe(22); + expect(date.getMilliseconds()).toBe(345); + expect(date.getDay()).toBe(4); + + let date = new Date(2019, -13, -33, -30, -70, -80, -2345); + expect(date.getFullYear()).toBe(2017); + expect(date.getMonth()).toBe(9); + expect(date.getDate()).toBe(26); + expect(date.getHours()).toBe(16); + expect(date.getMinutes()).toBe(48); + expect(date.getSeconds()).toBe(37); + expect(date.getMilliseconds()).toBe(655); + expect(date.getDay()).toBe(4); +});