diff --git a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp index 982c454625..0a0d82c76f 100644 --- a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -147,6 +147,11 @@ static double parse_simplified_iso8601(String const& iso_8601) return time_clip(time_ms); } +static constexpr AK::Array extra_formats = { + "%a %b %e %T %z %Y"sv, + "%m/%e/%Y"sv +}; + static double parse_date_string(String const& date_string) { auto value = parse_simplified_iso8601(date_string); @@ -155,9 +160,15 @@ static double parse_date_string(String const& date_string) // Date.parse() is allowed to accept an arbitrary number of implementation-defined formats. // Parse formats of this type: "Wed Apr 17 23:08:53 +0000 2019" - auto maybe_datetime = Core::DateTime::parse("%a %b %e %T %z %Y"sv, date_string); - if (maybe_datetime.has_value()) - return 1000.0 * maybe_datetime->timestamp(); + // And: "4/17/2019" + // FIXME: Exactly what timezone and which additional formats we should support is unclear. + // Both Chrome and Firefox seem to support "4/17/2019 11:08 PM +0000" with most parts + // being optional, however this is not clearly documented anywhere. + for (auto const& format : extra_formats) { + auto maybe_datetime = Core::DateTime::parse(format, date_string); + if (maybe_datetime.has_value()) + return 1000.0 * maybe_datetime->timestamp(); + } return NAN; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Date/Date.parse.js b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.parse.js index bf07d6722a..e8cb6531e4 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Date/Date.parse.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Date/Date.parse.js @@ -63,3 +63,18 @@ test("extra micro seconds extension", () => { expect(Date.parse("2021-06-26T07:24:40.0079999999999999999+00:00")).toBe(1624692280007); expect(Date.parse("2021-04-15T18:47:25.606000+00:00")).toBe(1618512445606); }); + +test("extra date extension", () => { + function expectStringToGiveDate(input, fullYear, month, dayInMonth) { + // Since the timezone is not specified we just say it has to equal the date parts. + const date = new Date(Date.parse(input)); + expect(date.getFullYear()).toBe(fullYear); + expect(date.getMonth() + 1).toBe(month); + expect(date.getDate()).toBe(dayInMonth); + } + + expectStringToGiveDate("01/30/2021", 2021, 1, 30); + expectStringToGiveDate("10/1/2021", 2021, 10, 1); + expectStringToGiveDate("7/07/1977", 1977, 7, 7); + expectStringToGiveDate("2/27/3058", 3058, 2, 27); +});