diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 8e8b5bf228f..39f4b41f988 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -2326,7 +2326,7 @@ static String convert_number_to_date_string(double input) // date string that represents the date that, in UTC, is current input milliseconds after midnight UTC // on the morning of 1970-01-01 (the time represented by the value "1970-01-01T00:00:00.0Z"). auto date = AK::UnixDateTime::from_seconds_since_epoch(input / 1000.); - return MUST(date.to_string("%Y-%m-%d"sv)); + return MUST(date.to_string("%Y-%m-%d"sv, AK::UnixDateTime::LocalTime::No)); } // https://html.spec.whatwg.org/multipage/input.html#time-state-(type=time):concept-input-value-number-string diff --git a/Libraries/LibWeb/Internals/Internals.cpp b/Libraries/LibWeb/Internals/Internals.cpp index b9c75e61d6a..8aa181d2e7c 100644 --- a/Libraries/LibWeb/Internals/Internals.cpp +++ b/Libraries/LibWeb/Internals/Internals.cpp @@ -4,7 +4,9 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include +#include #include #include #include @@ -53,6 +55,17 @@ void Internals::gc() vm().heap().collect_garbage(); } +WebIDL::ExceptionOr Internals::set_time_zone(StringView time_zone) +{ + auto current_time_zone = Unicode::current_time_zone(); + + if (auto result = Unicode::set_current_time_zone(time_zone); result.is_error()) + return vm().throw_completion(MUST(String::formatted("Could not set time zone: {}", result.error()))); + + JS::clear_system_time_zone_cache(); + return current_time_zone; +} + JS::Object* Internals::hit_test(double x, double y) { auto& active_document = window().associated_document(); diff --git a/Libraries/LibWeb/Internals/Internals.h b/Libraries/LibWeb/Internals/Internals.h index 070053d6162..806d0f23492 100644 --- a/Libraries/LibWeb/Internals/Internals.h +++ b/Libraries/LibWeb/Internals/Internals.h @@ -23,6 +23,8 @@ public: void signal_test_is_done(String const& text); void set_test_timeout(double milliseconds); + WebIDL::ExceptionOr set_time_zone(StringView time_zone); + void gc(); JS::Object* hit_test(double x, double y); diff --git a/Libraries/LibWeb/Internals/Internals.idl b/Libraries/LibWeb/Internals/Internals.idl index 27ad7e3c2fe..30e61fc6d16 100644 --- a/Libraries/LibWeb/Internals/Internals.idl +++ b/Libraries/LibWeb/Internals/Internals.idl @@ -8,6 +8,8 @@ interface Internals { undefined signalTestIsDone(DOMString text); undefined setTestTimeout(double milliseconds); + DOMString setTimeZone(DOMString timeZone); + undefined gc(); object hitTest(double x, double y); diff --git a/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Libraries/LibWeb/Loader/ResourceLoader.cpp index f4456fd58eb..9d3270d9153 100644 --- a/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -146,7 +146,7 @@ static HTTP::HeaderMap response_headers_for_file(StringView path, Optional { + const originalTimeZone = internals.setTimeZone('America/New_York'); + + const input = document.createElement('input'); + input.type = 'date'; + input.valueAsDate = new Date(0); + const result = input.value; + + internals.setTimeZone(originalTimeZone); + return result; + }); + + // 8. Input date set value as date testPart(() => { const input = document.createElement('input'); input.type = 'date'; @@ -68,7 +81,20 @@ return input.value; }); - // 8. Input date invalid set value as date + // 9. Input date set value as date (non-UTC time zone) + testPart(() => { + const originalTimeZone = internals.setTimeZone('Europe/Paris'); + + const input = document.createElement('input'); + input.type = "date"; + input.valueAsDate = new Date(1702320457860); + const result = input.value; + + internals.setTimeZone(originalTimeZone); + return result; + }); + + // 10. Input date invalid set value as date testPart(() => { const input = document.createElement('input'); input.type = 'date'; @@ -76,7 +102,7 @@ return input.value; }); - // 9. Input date null set value as date + // 11. Input date null set value as date testPart(() => { const input = document.createElement('input'); input.type = 'date'; @@ -84,7 +110,7 @@ return input.value; }); - // 10. Input time set value as date + // 12. Input time set value as date testPart(() => { const input = document.createElement('input'); input.type = 'time'; @@ -92,7 +118,7 @@ return input.value; }); - // 11. Input time set value as date + // 13. Input time set value as date testPart(() => { const input = document.createElement('input'); input.type = 'time'; @@ -100,7 +126,7 @@ return input.value; }); - // 12. Input time set value as date + // 14. Input time set value as date testPart(() => { const input = document.createElement('input'); input.type = 'time'; @@ -108,7 +134,7 @@ return input.value; }); - // 13. Input time invalid set value as date + // 15. Input time invalid set value as date testPart(() => { const input = document.createElement('input'); input.type = 'time'; @@ -116,7 +142,7 @@ return input.value; }); - // 14. Input time null set value as date + // 16. Input time null set value as date testPart(() => { const input = document.createElement('input'); input.type = 'time';