From f9fa548d43c17d803aeaae2f6c8cdfff3cacecf8 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 18 Feb 2026 12:37:01 -0500 Subject: [PATCH] LibJS: Pass time zone strings around as String more regularly These are String from the outset, so this patch is almost entirely just changing function parameter types. This will allow us to cache time zone parse results without invoking any extra allocations. --- .../Runtime/Temporal/AbstractOperations.cpp | 2 +- Libraries/LibJS/Runtime/Temporal/Duration.cpp | 12 +++++----- Libraries/LibJS/Runtime/Temporal/Duration.h | 14 +++++------ Libraries/LibJS/Runtime/Temporal/Instant.cpp | 4 ++-- Libraries/LibJS/Runtime/Temporal/Instant.h | 4 ++-- .../Runtime/Temporal/InstantPrototype.cpp | 6 ++--- Libraries/LibJS/Runtime/Temporal/TimeZone.cpp | 22 +++++++++-------- Libraries/LibJS/Runtime/Temporal/TimeZone.h | 24 ++++++++++--------- .../LibJS/Runtime/Temporal/ZonedDateTime.cpp | 10 ++++---- .../LibJS/Runtime/Temporal/ZonedDateTime.h | 12 +++++----- .../Temporal/ZonedDateTimeConstructor.cpp | 4 ++-- 11 files changed, 58 insertions(+), 56 deletions(-) diff --git a/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp index 72a8046c53..4987e38364 100644 --- a/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp +++ b/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp @@ -1595,7 +1595,7 @@ ThrowCompletionOr parse_temporal_time_zone_string(VM& // 6. If timeZoneResult.[[Z]] is true, return ! ParseTimeZoneIdentifier("UTC"). if (time_zone_result.z_designator) - return MUST(parse_time_zone_identifier(vm, "UTC"sv)); + return MUST(parse_time_zone_identifier(vm, UTC_TIME_ZONE)); // 7. If timeZoneResult.[[OffsetString]] is not EMPTY, return ? ParseTimeZoneIdentifier(timeZoneResult.[[OffsetString]]). if (time_zone_result.offset_string.has_value()) diff --git a/Libraries/LibJS/Runtime/Temporal/Duration.cpp b/Libraries/LibJS/Runtime/Temporal/Duration.cpp index 1054268198..2bc4a997e7 100644 --- a/Libraries/LibJS/Runtime/Temporal/Duration.cpp +++ b/Libraries/LibJS/Runtime/Temporal/Duration.cpp @@ -847,7 +847,7 @@ Crypto::BigFraction total_time_duration(TimeDuration const& time_duration, Unit } // 7.5.33 ComputeNudgeWindow ( sign, duration, originEpochNs, isoDateTime, timeZone, calendar, increment, unit, additionalShift ), https://tc39.es/proposal-temporal/#sec-temporal-computenudgewindow -ThrowCompletionOr compute_nudge_window(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, u64 increment, Unit unit, bool additional_shift) +ThrowCompletionOr compute_nudge_window(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, u64 increment, Unit unit, bool additional_shift) { DateDuration start_duration; DateDuration end_duration; @@ -1004,7 +1004,7 @@ ThrowCompletionOr compute_nudge_window(VM& vm, i8 sign, InternalDur } // 7.5.34 NudgeToCalendarUnit ( sign, duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, increment, unit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-nudgetocalendarunit -ThrowCompletionOr nudge_to_calendar_unit(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, u64 increment, Unit unit, RoundingMode rounding_mode) +ThrowCompletionOr nudge_to_calendar_unit(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, u64 increment, Unit unit, RoundingMode rounding_mode) { // 1. Let didExpandCalendarUnit be false. auto did_expand_calendar_unit = false; @@ -1155,7 +1155,7 @@ ThrowCompletionOr nudge_to_calendar_unit(VM& vm, i8 sign, I } // 7.5.35 NudgeToZonedTime ( sign, duration, isoDateTime, timeZone, calendar, increment, unit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-nudgetozonedtime -ThrowCompletionOr nudge_to_zoned_time(VM& vm, i8 sign, InternalDuration const& duration, ISODateTime const& iso_date_time, StringView time_zone, StringView calendar, u64 increment, Unit unit, RoundingMode rounding_mode) +ThrowCompletionOr nudge_to_zoned_time(VM& vm, i8 sign, InternalDuration const& duration, ISODateTime const& iso_date_time, String const& time_zone, StringView calendar, u64 increment, Unit unit, RoundingMode rounding_mode) { // 1. Let start be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], duration.[[Date]], CONSTRAIN). auto start = TRY(calendar_date_add(vm, calendar, iso_date_time.iso_date, duration.date, Overflow::Constrain)); @@ -1296,7 +1296,7 @@ ThrowCompletionOr nudge_to_day_or_time(VM& vm, InternalDura } // 7.5.37 BubbleRelativeDuration ( sign, duration, nudgedEpochNs, isoDateTime, timeZone, calendar, largestUnit, smallestUnit ), https://tc39.es/proposal-temporal/#sec-temporal-bubblerelativeduration -ThrowCompletionOr bubble_relative_duration(VM& vm, i8 sign, InternalDuration duration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit) +ThrowCompletionOr bubble_relative_duration(VM& vm, i8 sign, InternalDuration duration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit) { // 1. If smallestUnit is largestUnit, return duration. if (smallest_unit == largest_unit) @@ -1397,7 +1397,7 @@ ThrowCompletionOr bubble_relative_duration(VM& vm, i8 sign, In } // 7.5.38 RoundRelativeDuration ( duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, largestUnit, increment, smallestUnit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundrelativeduration -ThrowCompletionOr round_relative_duration(VM& vm, InternalDuration duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode rounding_mode) +ThrowCompletionOr round_relative_duration(VM& vm, InternalDuration duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode rounding_mode) { // 1. Let irregularLengthUnit be false. auto irregular_length_unit = false; @@ -1451,7 +1451,7 @@ ThrowCompletionOr round_relative_duration(VM& vm, InternalDura } // 7.5.39 TotalRelativeDuration ( duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, unit ), https://tc39.es/proposal-temporal/#sec-temporal-totalrelativeduration -ThrowCompletionOr total_relative_duration(VM& vm, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, Unit unit) +ThrowCompletionOr total_relative_duration(VM& vm, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, Unit unit) { // 1. If IsCalendarUnit(unit) is true, or timeZone is not UNSET and unit is DAY, then if (is_calendar_unit(unit) || (time_zone.has_value() && unit == Unit::Day)) { diff --git a/Libraries/LibJS/Runtime/Temporal/Duration.h b/Libraries/LibJS/Runtime/Temporal/Duration.h index e96fddccc1..a16265cd3a 100644 --- a/Libraries/LibJS/Runtime/Temporal/Duration.h +++ b/Libraries/LibJS/Runtime/Temporal/Duration.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2021-2023, Linus Groh * Copyright (c) 2024, Shannon Booth - * Copyright (c) 2024, Tim Flynn + * Copyright (c) 2024-2026, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -146,13 +146,13 @@ i8 time_duration_sign(TimeDuration const&); ThrowCompletionOr date_duration_days(VM&, DateDuration const&, PlainDate const&); ThrowCompletionOr round_time_duration(VM&, TimeDuration const&, Crypto::UnsignedBigInteger const& increment, Unit, RoundingMode); Crypto::BigFraction total_time_duration(TimeDuration const&, Unit); -ThrowCompletionOr compute_nudge_window(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, u64 increment, Unit, bool additional_shift); -ThrowCompletionOr nudge_to_calendar_unit(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, u64 increment, Unit, RoundingMode); -ThrowCompletionOr nudge_to_zoned_time(VM&, i8 sign, InternalDuration const&, ISODateTime const&, StringView time_zone, StringView calendar, u64 increment, Unit, RoundingMode); +ThrowCompletionOr compute_nudge_window(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional time_zone, StringView calendar, u64 increment, Unit, bool additional_shift); +ThrowCompletionOr nudge_to_calendar_unit(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, u64 increment, Unit, RoundingMode); +ThrowCompletionOr nudge_to_zoned_time(VM&, i8 sign, InternalDuration const&, ISODateTime const&, String const& time_zone, StringView calendar, u64 increment, Unit, RoundingMode); ThrowCompletionOr nudge_to_day_or_time(VM&, InternalDuration const&, Crypto::SignedBigInteger const& dest_epoch_ns, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode); -ThrowCompletionOr bubble_relative_duration(VM&, i8 sign, InternalDuration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit); -ThrowCompletionOr round_relative_duration(VM&, InternalDuration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode); -ThrowCompletionOr total_relative_duration(VM&, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, Unit); +ThrowCompletionOr bubble_relative_duration(VM&, i8 sign, InternalDuration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit); +ThrowCompletionOr round_relative_duration(VM&, InternalDuration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode); +ThrowCompletionOr total_relative_duration(VM&, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional time_zone, StringView calendar, Unit); String temporal_duration_to_string(Duration const&, Precision); ThrowCompletionOr> add_durations(VM&, ArithmeticOperation, Duration const&, Value); diff --git a/Libraries/LibJS/Runtime/Temporal/Instant.cpp b/Libraries/LibJS/Runtime/Temporal/Instant.cpp index 13b340b37d..22bea2d42f 100644 --- a/Libraries/LibJS/Runtime/Temporal/Instant.cpp +++ b/Libraries/LibJS/Runtime/Temporal/Instant.cpp @@ -201,11 +201,11 @@ Crypto::SignedBigInteger round_temporal_instant(Crypto::SignedBigInteger const& } // 8.5.8 TemporalInstantToString ( instant, timeZone, precision ), https://tc39.es/proposal-temporal/#sec-temporal-temporalinstanttostring -String temporal_instant_to_string(Instant const& instant, Optional time_zone, SecondsStringPrecision::Precision precision) +String temporal_instant_to_string(Instant const& instant, Optional time_zone, SecondsStringPrecision::Precision precision) { // 1. Let outputTimeZone be timeZone. // 2. If outputTimeZone is undefined, set outputTimeZone to "UTC". - auto output_time_zone = time_zone.value_or("UTC"sv); + auto const& output_time_zone = time_zone.value_or(UTC_TIME_ZONE); // 3. Let epochNs be instant.[[EpochNanoseconds]]. auto const& epoch_nanoseconds = instant.epoch_nanoseconds()->big_integer(); diff --git a/Libraries/LibJS/Runtime/Temporal/Instant.h b/Libraries/LibJS/Runtime/Temporal/Instant.h index 6f87e9bc96..8fcf1e9e6a 100644 --- a/Libraries/LibJS/Runtime/Temporal/Instant.h +++ b/Libraries/LibJS/Runtime/Temporal/Instant.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2021-2023, Linus Groh * Copyright (c) 2021, Idan Horowitz - * Copyright (c) 2024, Tim Flynn + * Copyright (c) 2024-2026, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -63,7 +63,7 @@ i8 compare_epoch_nanoseconds(Crypto::SignedBigInteger const& epoch_nanoseconds_o ThrowCompletionOr add_instant(VM&, Crypto::SignedBigInteger const& epoch_nanoseconds, TimeDuration const&); InternalDuration difference_instant(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, u64 rounding_increment, Unit smallest_unit, RoundingMode); Crypto::SignedBigInteger round_temporal_instant(Crypto::SignedBigInteger const& nanoseconds, u64 increment, Unit, RoundingMode); -String temporal_instant_to_string(Instant const&, Optional time_zone, SecondsStringPrecision::Precision); +String temporal_instant_to_string(Instant const&, Optional time_zone, SecondsStringPrecision::Precision); ThrowCompletionOr> difference_temporal_instant(VM&, DurationOperation, Instant const&, Value other, Value options); ThrowCompletionOr> add_duration_to_instant(VM&, ArithmeticOperation, Instant const&, Value temporal_duration_like); diff --git a/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp b/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp index 19f35f0ed2..385ec35eb1 100644 --- a/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp +++ b/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp @@ -276,14 +276,12 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::to_string) if (auto const* unit = smallest_unit.get_pointer(); unit && *unit == Unit::Hour) return vm.throw_completion(ErrorType::OptionIsNotValidValue, temporal_unit_to_string(*unit), vm.names.smallestUnit); - String time_zone_buffer; - Optional time_zone; + Optional time_zone; // 11. If timeZone is not undefined, then if (!time_zone_value.is_undefined()) { // a. Set timeZone to ? ToTemporalTimeZoneIdentifier(timeZone). - time_zone_buffer = TRY(to_temporal_time_zone_identifier(vm, time_zone_value)); - time_zone = time_zone_buffer; + time_zone = TRY(to_temporal_time_zone_identifier(vm, time_zone_value)); } // 12. Let precision be ToSecondsStringPrecisionRecord(smallestUnit, digits). diff --git a/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index db0f00a9a1..6520443a0d 100644 --- a/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -23,6 +23,8 @@ namespace JS::Temporal { +String UTC_TIME_ZONE = "UTC"_string; + // 11.1.2 GetISOPartsFromEpoch ( epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-getisopartsfromepoch ISODateTime get_iso_parts_from_epoch(Crypto::SignedBigInteger const& epoch_nanoseconds) { @@ -77,7 +79,7 @@ ISODateTime get_iso_parts_from_epoch(Crypto::SignedBigInteger const& epoch_nanos } // 11.1.3 GetNamedTimeZoneNextTransition ( timeZoneIdentifier, epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-getnamedtimezonenexttransition -Optional get_named_time_zone_next_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) +Optional get_named_time_zone_next_transition(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) { auto epoch_milliseconds = big_floor(epoch_nanoseconds, NANOSECONDS_PER_MILLISECOND); auto time = UnixDateTime::from_milliseconds_since_epoch(clip_bigint_to_sane_time(epoch_milliseconds)); @@ -100,7 +102,7 @@ Optional get_named_time_zone_next_transition(StringVie } // 11.1.4 GetNamedTimeZonePreviousTransition ( timeZoneIdentifier, epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-getnamedtimezoneprevioustransition -Optional get_named_time_zone_previous_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) +Optional get_named_time_zone_previous_transition(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) { auto epoch_milliseconds = big_floor(epoch_nanoseconds, NANOSECONDS_PER_MILLISECOND); auto time = UnixDateTime::from_milliseconds_since_epoch(clip_bigint_to_sane_time(epoch_milliseconds)); @@ -239,7 +241,7 @@ ThrowCompletionOr to_temporal_time_zone_identifier(VM& vm, StringView te } // 11.1.9 GetOffsetNanosecondsFor ( timeZone, epochNs ), https://tc39.es/proposal-temporal/#sec-temporal-getoffsetnanosecondsfor -i64 get_offset_nanoseconds_for(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) +i64 get_offset_nanoseconds_for(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) { // 1. Let parseResult be ! ParseTimeZoneIdentifier(timeZone). auto parse_result = parse_time_zone_identifier(time_zone); @@ -253,7 +255,7 @@ i64 get_offset_nanoseconds_for(StringView time_zone, Crypto::SignedBigInteger co } // 11.1.10 GetISODateTimeFor ( timeZone, epochNs ), https://tc39.es/proposal-temporal/#sec-temporal-getisodatetimefor -ISODateTime get_iso_date_time_for(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) +ISODateTime get_iso_date_time_for(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds) { // 1. Let offsetNanoseconds be GetOffsetNanosecondsFor(timeZone, epochNs). auto offset_nanoseconds = get_offset_nanoseconds_for(time_zone, epoch_nanoseconds); @@ -266,7 +268,7 @@ ISODateTime get_iso_date_time_for(StringView time_zone, Crypto::SignedBigInteger } // 11.1.11 GetEpochNanosecondsFor ( timeZone, isoDateTime, disambiguation ), https://tc39.es/proposal-temporal/#sec-temporal-getepochnanosecondsfor -ThrowCompletionOr get_epoch_nanoseconds_for(VM& vm, StringView time_zone, ISODateTime const& iso_date_time, Disambiguation disambiguation) +ThrowCompletionOr get_epoch_nanoseconds_for(VM& vm, String const& time_zone, ISODateTime const& iso_date_time, Disambiguation disambiguation) { // 1. Let possibleEpochNs be ? GetPossibleEpochNanoseconds(timeZone, isoDateTime). auto possible_epoch_ns = TRY(get_possible_epoch_nanoseconds(vm, time_zone, iso_date_time)); @@ -276,7 +278,7 @@ ThrowCompletionOr get_epoch_nanoseconds_for(VM& vm, St } // 11.1.12 DisambiguatePossibleEpochNanoseconds ( possibleEpochNs, timeZone, isoDateTime, disambiguation ), https://tc39.es/proposal-temporal/#sec-temporal-disambiguatepossibleepochnanoseconds -ThrowCompletionOr disambiguate_possible_epoch_nanoseconds(VM& vm, Vector possible_epoch_ns, StringView time_zone, ISODateTime const& iso_date_time, Disambiguation disambiguation) +ThrowCompletionOr disambiguate_possible_epoch_nanoseconds(VM& vm, Vector possible_epoch_ns, String const& time_zone, ISODateTime const& iso_date_time, Disambiguation disambiguation) { // 1. Let n be the number of elements in possibleEpochNs. auto n = possible_epoch_ns.size(); @@ -316,7 +318,7 @@ ThrowCompletionOr disambiguate_possible_epoch_nanoseco } // 11.1.13 GetPossibleEpochNanoseconds ( timeZone, isoDateTime ), https://tc39.es/proposal-temporal/#sec-temporal-getpossibleepochnanoseconds -ThrowCompletionOr> get_possible_epoch_nanoseconds(VM& vm, StringView time_zone, ISODateTime const& iso_date_time) +ThrowCompletionOr> get_possible_epoch_nanoseconds(VM& vm, String const& time_zone, ISODateTime const& iso_date_time) { Vector possible_epoch_nanoseconds; @@ -364,7 +366,7 @@ ThrowCompletionOr> get_possible_epoch_nanosecon } // 11.1.14 GetStartOfDay ( timeZone, isoDate ), https://tc39.es/proposal-temporal/#sec-temporal-getstartofday -ThrowCompletionOr get_start_of_day(VM& vm, StringView time_zone, ISODate iso_date) +ThrowCompletionOr get_start_of_day(VM& vm, String const& time_zone, ISODate iso_date) { // 1. Let isoDateTime be CombineISODateAndTimeRecord(isoDate, MidnightTimeRecord()). auto iso_date_time = combine_iso_date_and_time_record(iso_date, midnight_time_record()); @@ -420,7 +422,7 @@ bool time_zone_equals(StringView one, StringView two) } // 11.1.16 ParseTimeZoneIdentifier ( identifier ), https://tc39.es/proposal-temporal/#sec-parsetimezoneidentifier -ThrowCompletionOr parse_time_zone_identifier(VM& vm, StringView identifier) +ThrowCompletionOr parse_time_zone_identifier(VM& vm, String const& identifier) { // 1. Let parseResult be ParseText(StringToCodePoints(identifier), TimeZoneIdentifier). auto parse_result = parse_iso8601(Production::TimeZoneIdentifier, identifier); @@ -433,7 +435,7 @@ ThrowCompletionOr parse_time_zone_identifier(VM& vm, S } // 11.1.16 ParseTimeZoneIdentifier ( identifier ), https://tc39.es/proposal-temporal/#sec-parsetimezoneidentifier -ParsedTimeZoneIdentifier parse_time_zone_identifier(StringView identifier) +ParsedTimeZoneIdentifier parse_time_zone_identifier(String const& identifier) { // OPTIMIZATION: Some callers can assume that parsing will succeed. diff --git a/Libraries/LibJS/Runtime/Temporal/TimeZone.h b/Libraries/LibJS/Runtime/Temporal/TimeZone.h index 3dcc47e808..abe49033f6 100644 --- a/Libraries/LibJS/Runtime/Temporal/TimeZone.h +++ b/Libraries/LibJS/Runtime/Temporal/TimeZone.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2021-2023, Linus Groh - * Copyright (c) 2024, Tim Flynn + * Copyright (c) 2024-2026, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -17,23 +17,25 @@ namespace JS::Temporal { +extern String UTC_TIME_ZONE; + ISODateTime get_iso_parts_from_epoch(Crypto::SignedBigInteger const& epoch_nanoseconds); -Optional get_named_time_zone_next_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); -Optional get_named_time_zone_previous_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); +Optional get_named_time_zone_next_transition(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); +Optional get_named_time_zone_previous_transition(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); String format_offset_time_zone_identifier(i64 offset_minutes, Optional = {}); String format_utc_offset_nanoseconds(i64 offset_nanoseconds); String format_date_time_utc_offset_rounded(i64 offset_nanoseconds); ThrowCompletionOr to_temporal_time_zone_identifier(VM&, Value temporal_time_zone_like); -i64 get_offset_nanoseconds_for(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); -ISODateTime get_iso_date_time_for(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); +i64 get_offset_nanoseconds_for(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); +ISODateTime get_iso_date_time_for(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds); ThrowCompletionOr to_temporal_time_zone_identifier(VM&, StringView temporal_time_zone_like); -ThrowCompletionOr get_epoch_nanoseconds_for(VM&, StringView time_zone, ISODateTime const&, Disambiguation); -ThrowCompletionOr disambiguate_possible_epoch_nanoseconds(VM&, Vector possible_epoch_ns, StringView time_zone, ISODateTime const&, Disambiguation); -ThrowCompletionOr> get_possible_epoch_nanoseconds(VM&, StringView time_zone, ISODateTime const&); -ThrowCompletionOr get_start_of_day(VM&, StringView time_zone, ISODate); +ThrowCompletionOr get_epoch_nanoseconds_for(VM&, String const& time_zone, ISODateTime const&, Disambiguation); +ThrowCompletionOr disambiguate_possible_epoch_nanoseconds(VM&, Vector possible_epoch_ns, String const& time_zone, ISODateTime const&, Disambiguation); +ThrowCompletionOr> get_possible_epoch_nanoseconds(VM&, String const& time_zone, ISODateTime const&); +ThrowCompletionOr get_start_of_day(VM&, String const& time_zone, ISODate); bool time_zone_equals(StringView one, StringView two); -ThrowCompletionOr parse_time_zone_identifier(VM&, StringView identifier); -ParsedTimeZoneIdentifier parse_time_zone_identifier(StringView identifier); +ThrowCompletionOr parse_time_zone_identifier(VM&, String const& identifier); +ParsedTimeZoneIdentifier parse_time_zone_identifier(String const& identifier); ParsedTimeZoneIdentifier parse_time_zone_identifier(ParseResult const&); } diff --git a/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp b/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp index ab18766636..5bd42088cc 100644 --- a/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp +++ b/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp @@ -38,7 +38,7 @@ void ZonedDateTime::visit_edges(Cell::Visitor& visitor) } // 6.5.1 InterpretISODateTimeOffset ( isoDate, time, offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour ), https://tc39.es/proposal-temporal/#sec-temporal-interpretisodatetimeoffset -ThrowCompletionOr interpret_iso_date_time_offset(VM& vm, ISODate iso_date, Variant const& time_or_start_of_day, OffsetBehavior offset_behavior, double offset_nanoseconds, StringView time_zone, Disambiguation disambiguation, OffsetOption offset_option, MatchBehavior match_behavior) +ThrowCompletionOr interpret_iso_date_time_offset(VM& vm, ISODate iso_date, Variant const& time_or_start_of_day, OffsetBehavior offset_behavior, double offset_nanoseconds, String const& time_zone, Disambiguation disambiguation, OffsetOption offset_option, MatchBehavior match_behavior) { // 1. If time is START-OF-DAY, then if (time_or_start_of_day.has()) { @@ -393,7 +393,7 @@ String temporal_zoned_date_time_to_string(ZonedDateTime const& zoned_date_time, } // 6.5.5 AddZonedDateTime ( epochNanoseconds, timeZone, calendar, duration, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-addzoneddatetime -ThrowCompletionOr add_zoned_date_time(VM& vm, Crypto::SignedBigInteger const& epoch_nanoseconds, StringView time_zone, StringView calendar, InternalDuration const& duration, Overflow overflow) +ThrowCompletionOr add_zoned_date_time(VM& vm, Crypto::SignedBigInteger const& epoch_nanoseconds, String const& time_zone, StringView calendar, InternalDuration const& duration, Overflow overflow) { // 1. If DateDurationSign(duration.[[Date]]) = 0, return ? AddInstant(epochNanoseconds, duration.[[Time]]). if (date_duration_sign(duration.date) == 0) @@ -420,7 +420,7 @@ ThrowCompletionOr add_zoned_date_time(VM& vm, Crypto:: } // 6.5.6 DifferenceZonedDateTime ( ns1, ns2, timeZone, calendar, largestUnit ), https://tc39.es/proposal-temporal/#sec-temporal-differencezoneddatetime -ThrowCompletionOr difference_zoned_date_time(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit largest_unit) +ThrowCompletionOr difference_zoned_date_time(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit largest_unit) { // 1. If ns1 = ns2, return CombineDateAndTimeDuration(ZeroDateDuration(), 0). if (nanoseconds1 == nanoseconds2) @@ -503,7 +503,7 @@ ThrowCompletionOr difference_zoned_date_time(VM& vm, Crypto::S } // 6.5.7 DifferenceZonedDateTimeWithRounding ( ns1, ns2, timeZone, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-differencezoneddatetimewithrounding -ThrowCompletionOr difference_zoned_date_time_with_rounding(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit largest_unit, u64 rounding_increment, Unit smallest_unit, RoundingMode rounding_mode) +ThrowCompletionOr difference_zoned_date_time_with_rounding(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit largest_unit, u64 rounding_increment, Unit smallest_unit, RoundingMode rounding_mode) { // 1. If TemporalUnitCategory(largestUnit) is TIME, return DifferenceInstant(ns1, ns2, roundingIncrement, smallestUnit, roundingMode). if (temporal_unit_category(largest_unit) == UnitCategory::Time) @@ -524,7 +524,7 @@ ThrowCompletionOr difference_zoned_date_time_with_rounding(VM& } // 6.5.8 DifferenceZonedDateTimeWithTotal ( ns1, ns2, timeZone, calendar, unit ), https://tc39.es/proposal-temporal/#sec-temporal-differencezoneddatetimewithtotal -ThrowCompletionOr difference_zoned_date_time_with_total(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit unit) +ThrowCompletionOr difference_zoned_date_time_with_total(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit unit) { // 1. If TemporalUnitCategory(unit) is TIME, then if (temporal_unit_category(unit) == UnitCategory::Time) { diff --git a/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h b/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h index 45e1544554..ec398772e1 100644 --- a/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h +++ b/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2021-2023, Linus Groh - * Copyright (c) 2024, Tim Flynn + * Copyright (c) 2024-2026, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -48,14 +48,14 @@ enum class MatchBehavior { MatchMinutes, }; -ThrowCompletionOr interpret_iso_date_time_offset(VM&, ISODate, Variant const&, OffsetBehavior, double offset_nanoseconds, StringView time_zone, Disambiguation, OffsetOption, MatchBehavior); +ThrowCompletionOr interpret_iso_date_time_offset(VM&, ISODate, Variant const&, OffsetBehavior, double offset_nanoseconds, String const& time_zone, Disambiguation, OffsetOption, MatchBehavior); ThrowCompletionOr> to_temporal_zoned_date_time(VM&, Value item, Value options = js_undefined()); ThrowCompletionOr> create_temporal_zoned_date_time(VM&, BigInt const& epoch_nanoseconds, String time_zone, String calendar, GC::Ptr new_target = {}); String temporal_zoned_date_time_to_string(ZonedDateTime const&, SecondsStringPrecision::Precision, ShowCalendar, ShowTimeZoneName, ShowOffset, u64 increment = 1, Unit = Unit::Nanosecond, RoundingMode = RoundingMode::Trunc); -ThrowCompletionOr add_zoned_date_time(VM&, Crypto::SignedBigInteger const& epoch_nanoseconds, StringView time_zone, StringView calendar, InternalDuration const&, Overflow); -ThrowCompletionOr difference_zoned_date_time(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit largest_unit); -ThrowCompletionOr difference_zoned_date_time_with_rounding(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit largest_unit, u64 rounding_increment, Unit smallest_unit, RoundingMode); -ThrowCompletionOr difference_zoned_date_time_with_total(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit); +ThrowCompletionOr add_zoned_date_time(VM&, Crypto::SignedBigInteger const& epoch_nanoseconds, String const& time_zone, StringView calendar, InternalDuration const&, Overflow); +ThrowCompletionOr difference_zoned_date_time(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit largest_unit); +ThrowCompletionOr difference_zoned_date_time_with_rounding(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit largest_unit, u64 rounding_increment, Unit smallest_unit, RoundingMode); +ThrowCompletionOr difference_zoned_date_time_with_total(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit); ThrowCompletionOr> difference_temporal_zoned_date_time(VM&, DurationOperation, ZonedDateTime const&, Value other, Value options); ThrowCompletionOr> add_duration_to_zoned_date_time(VM&, ArithmeticOperation, ZonedDateTime const&, Value temporal_duration_like, Value options); diff --git a/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp b/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp index f6d0f73806..692e77af26 100644 --- a/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp +++ b/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2021-2023, Linus Groh * Copyright (c) 2021, Luke Wilde - * Copyright (c) 2024-2025, Tim Flynn + * Copyright (c) 2024-2026, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -69,7 +69,7 @@ ThrowCompletionOr> ZonedDateTimeConstructor::construct(FunctionO return vm.throw_completion(ErrorType::NotAString, time_zone_value); // 5. Let timeZoneParse be ? ParseTimeZoneIdentifier(timeZone). - auto time_zone_parse = TRY(parse_time_zone_identifier(vm, time_zone_value.as_string().utf8_string_view())); + auto time_zone_parse = TRY(parse_time_zone_identifier(vm, time_zone_value.as_string().utf8_string())); String time_zone;