mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibWeb: Restore flags to prevent formatting timestamps as local time
The flag to stringify these timestamps as UTC was errantly dropped in
6fb2be96bf
. This was causing test-web to
fail in time zones other than GMT+0.
This commit is contained in:
parent
efa9737cf7
commit
3171d57639
Notes:
github-actions[bot]
2025-06-25 21:42:10 +00:00
Author: https://github.com/trflynn89
Commit: 3171d57639
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5216
Reviewed-by: https://github.com/gmta ✅
7 changed files with 63 additions and 18 deletions
|
@ -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
|
// 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").
|
// 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.);
|
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
|
// https://html.spec.whatwg.org/multipage/input.html#time-state-(type=time):concept-input-value-number-string
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/Date.h>
|
||||||
#include <LibJS/Runtime/VM.h>
|
#include <LibJS/Runtime/VM.h>
|
||||||
|
#include <LibUnicode/TimeZone.h>
|
||||||
#include <LibWeb/Bindings/InternalsPrototype.h>
|
#include <LibWeb/Bindings/InternalsPrototype.h>
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
|
@ -53,6 +55,17 @@ void Internals::gc()
|
||||||
vm().heap().collect_garbage();
|
vm().heap().collect_garbage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<String> 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<JS::InternalError>(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)
|
JS::Object* Internals::hit_test(double x, double y)
|
||||||
{
|
{
|
||||||
auto& active_document = window().associated_document();
|
auto& active_document = window().associated_document();
|
||||||
|
|
|
@ -23,6 +23,8 @@ public:
|
||||||
void signal_test_is_done(String const& text);
|
void signal_test_is_done(String const& text);
|
||||||
void set_test_timeout(double milliseconds);
|
void set_test_timeout(double milliseconds);
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<String> set_time_zone(StringView time_zone);
|
||||||
|
|
||||||
void gc();
|
void gc();
|
||||||
JS::Object* hit_test(double x, double y);
|
JS::Object* hit_test(double x, double y);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ interface Internals {
|
||||||
undefined signalTestIsDone(DOMString text);
|
undefined signalTestIsDone(DOMString text);
|
||||||
undefined setTestTimeout(double milliseconds);
|
undefined setTestTimeout(double milliseconds);
|
||||||
|
|
||||||
|
DOMString setTimeZone(DOMString timeZone);
|
||||||
|
|
||||||
undefined gc();
|
undefined gc();
|
||||||
object hitTest(double x, double y);
|
object hitTest(double x, double y);
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ static HTTP::HeaderMap response_headers_for_file(StringView path, Optional<time_
|
||||||
|
|
||||||
if (modified_time.has_value()) {
|
if (modified_time.has_value()) {
|
||||||
auto const datetime = AK::UnixDateTime::from_seconds_since_epoch(modified_time.value());
|
auto const datetime = AK::UnixDateTime::from_seconds_since_epoch(modified_time.value());
|
||||||
response_headers.set("Last-Modified"sv, datetime.to_byte_string("%a, %d %b %Y %H:%M:%S GMT"sv));
|
response_headers.set("Last-Modified"sv, datetime.to_byte_string("%a, %d %b %Y %H:%M:%S GMT"sv, AK::UnixDateTime::LocalTime::No));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response_headers;
|
return response_headers;
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
4. "1970-01-01T19:46:19.000Z"
|
4. "1970-01-01T19:46:19.000Z"
|
||||||
5. null
|
5. null
|
||||||
6. "1970-01-01"
|
6. "1970-01-01"
|
||||||
7. "2023-12-11"
|
7. "1970-01-01"
|
||||||
8. Exception: TypeError
|
8. "2023-12-11"
|
||||||
9. ""
|
9. "2023-12-11"
|
||||||
10. "18:47:37"
|
10. Exception: TypeError
|
||||||
11. "18:47:37.100"
|
11. ""
|
||||||
12. "18:47:37.864"
|
12. "18:47:37"
|
||||||
13. Exception: TypeError
|
13. "18:47:37.100"
|
||||||
14. ""
|
14. "18:47:37.864"
|
||||||
|
15. Exception: TypeError
|
||||||
|
16. ""
|
||||||
|
|
|
@ -60,7 +60,20 @@
|
||||||
return input.value;
|
return input.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 7. Input date set value as date
|
// 7. Input date set value as date (non-UTC time zone)
|
||||||
|
testPart(() => {
|
||||||
|
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(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'date';
|
input.type = 'date';
|
||||||
|
@ -68,7 +81,20 @@
|
||||||
return input.value;
|
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(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'date';
|
input.type = 'date';
|
||||||
|
@ -76,7 +102,7 @@
|
||||||
return input.value;
|
return input.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 9. Input date null set value as date
|
// 11. Input date null set value as date
|
||||||
testPart(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'date';
|
input.type = 'date';
|
||||||
|
@ -84,7 +110,7 @@
|
||||||
return input.value;
|
return input.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 10. Input time set value as date
|
// 12. Input time set value as date
|
||||||
testPart(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'time';
|
input.type = 'time';
|
||||||
|
@ -92,7 +118,7 @@
|
||||||
return input.value;
|
return input.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 11. Input time set value as date
|
// 13. Input time set value as date
|
||||||
testPart(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'time';
|
input.type = 'time';
|
||||||
|
@ -100,7 +126,7 @@
|
||||||
return input.value;
|
return input.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 12. Input time set value as date
|
// 14. Input time set value as date
|
||||||
testPart(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'time';
|
input.type = 'time';
|
||||||
|
@ -108,7 +134,7 @@
|
||||||
return input.value;
|
return input.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 13. Input time invalid set value as date
|
// 15. Input time invalid set value as date
|
||||||
testPart(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'time';
|
input.type = 'time';
|
||||||
|
@ -116,7 +142,7 @@
|
||||||
return input.value;
|
return input.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 14. Input time null set value as date
|
// 16. Input time null set value as date
|
||||||
testPart(() => {
|
testPart(() => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'time';
|
input.type = 'time';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue