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.
This commit is contained in:
Timothy Flynn 2026-02-18 12:37:01 -05:00 committed by Jelle Raaijmakers
parent d065f6bf00
commit f9fa548d43
11 changed files with 58 additions and 56 deletions

View file

@ -1595,7 +1595,7 @@ ThrowCompletionOr<ParsedTimeZoneIdentifier> 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())

View file

@ -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<NudgeWindow> compute_nudge_window(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit unit, bool additional_shift)
ThrowCompletionOr<NudgeWindow> compute_nudge_window(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional<String const&> time_zone, StringView calendar, u64 increment, Unit unit, bool additional_shift)
{
DateDuration start_duration;
DateDuration end_duration;
@ -1004,7 +1004,7 @@ ThrowCompletionOr<NudgeWindow> 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<CalendarNudgeResult> 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<StringView> time_zone, StringView calendar, u64 increment, Unit unit, RoundingMode rounding_mode)
ThrowCompletionOr<CalendarNudgeResult> 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<String const&> 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<CalendarNudgeResult> 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<DurationNudgeResult> 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<DurationNudgeResult> 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<DurationNudgeResult> 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<InternalDuration> bubble_relative_duration(VM& vm, i8 sign, InternalDuration duration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit)
ThrowCompletionOr<InternalDuration> bubble_relative_duration(VM& vm, i8 sign, InternalDuration duration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const& iso_date_time, Optional<String const&> 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<InternalDuration> 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<InternalDuration> 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<StringView> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode rounding_mode)
ThrowCompletionOr<InternalDuration> 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<String const&> 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<InternalDuration> 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<Crypto::BigFraction> 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<StringView> time_zone, StringView calendar, Unit unit)
ThrowCompletionOr<Crypto::BigFraction> 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<String const&> 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)) {

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -146,13 +146,13 @@ i8 time_duration_sign(TimeDuration const&);
ThrowCompletionOr<double> date_duration_days(VM&, DateDuration const&, PlainDate const&);
ThrowCompletionOr<TimeDuration> round_time_duration(VM&, TimeDuration const&, Crypto::UnsignedBigInteger const& increment, Unit, RoundingMode);
Crypto::BigFraction total_time_duration(TimeDuration const&, Unit);
ThrowCompletionOr<NudgeWindow> compute_nudge_window(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit, bool additional_shift);
ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
ThrowCompletionOr<DurationNudgeResult> nudge_to_zoned_time(VM&, i8 sign, InternalDuration const&, ISODateTime const&, StringView time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
ThrowCompletionOr<NudgeWindow> compute_nudge_window(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, ISODateTime const& iso_date_time, Optional<String const&> time_zone, StringView calendar, u64 increment, Unit, bool additional_shift);
ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<String const&> time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
ThrowCompletionOr<DurationNudgeResult> nudge_to_zoned_time(VM&, i8 sign, InternalDuration const&, ISODateTime const&, String const& time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
ThrowCompletionOr<DurationNudgeResult> nudge_to_day_or_time(VM&, InternalDuration const&, Crypto::SignedBigInteger const& dest_epoch_ns, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
ThrowCompletionOr<InternalDuration> bubble_relative_duration(VM&, i8 sign, InternalDuration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit);
ThrowCompletionOr<InternalDuration> round_relative_duration(VM&, InternalDuration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
ThrowCompletionOr<Crypto::BigFraction> total_relative_duration(VM&, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit);
ThrowCompletionOr<InternalDuration> bubble_relative_duration(VM&, i8 sign, InternalDuration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const&, Optional<String const&> time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit);
ThrowCompletionOr<InternalDuration> round_relative_duration(VM&, InternalDuration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<String const&> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
ThrowCompletionOr<Crypto::BigFraction> total_relative_duration(VM&, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<String const&> time_zone, StringView calendar, Unit);
String temporal_duration_to_string(Duration const&, Precision);
ThrowCompletionOr<GC::Ref<Duration>> add_durations(VM&, ArithmeticOperation, Duration const&, Value);

View file

@ -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<StringView> time_zone, SecondsStringPrecision::Precision precision)
String temporal_instant_to_string(Instant const& instant, Optional<String const&> 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();

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -63,7 +63,7 @@ i8 compare_epoch_nanoseconds(Crypto::SignedBigInteger const& epoch_nanoseconds_o
ThrowCompletionOr<Crypto::SignedBigInteger> 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<StringView> time_zone, SecondsStringPrecision::Precision);
String temporal_instant_to_string(Instant const&, Optional<String const&> time_zone, SecondsStringPrecision::Precision);
ThrowCompletionOr<GC::Ref<Duration>> difference_temporal_instant(VM&, DurationOperation, Instant const&, Value other, Value options);
ThrowCompletionOr<GC::Ref<Instant>> add_duration_to_instant(VM&, ArithmeticOperation, Instant const&, Value temporal_duration_like);

View file

@ -276,14 +276,12 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::to_string)
if (auto const* unit = smallest_unit.get_pointer<Unit>(); unit && *unit == Unit::Hour)
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, temporal_unit_to_string(*unit), vm.names.smallestUnit);
String time_zone_buffer;
Optional<StringView> time_zone;
Optional<String> 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).

View file

@ -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<Crypto::SignedBigInteger> get_named_time_zone_next_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds)
Optional<Crypto::SignedBigInteger> 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<Crypto::SignedBigInteger> get_named_time_zone_next_transition(StringVie
}
// 11.1.4 GetNamedTimeZonePreviousTransition ( timeZoneIdentifier, epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-getnamedtimezoneprevioustransition
Optional<Crypto::SignedBigInteger> get_named_time_zone_previous_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds)
Optional<Crypto::SignedBigInteger> 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<String> 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<Crypto::SignedBigInteger> get_epoch_nanoseconds_for(VM& vm, StringView time_zone, ISODateTime const& iso_date_time, Disambiguation disambiguation)
ThrowCompletionOr<Crypto::SignedBigInteger> 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<Crypto::SignedBigInteger> get_epoch_nanoseconds_for(VM& vm, St
}
// 11.1.12 DisambiguatePossibleEpochNanoseconds ( possibleEpochNs, timeZone, isoDateTime, disambiguation ), https://tc39.es/proposal-temporal/#sec-temporal-disambiguatepossibleepochnanoseconds
ThrowCompletionOr<Crypto::SignedBigInteger> disambiguate_possible_epoch_nanoseconds(VM& vm, Vector<Crypto::SignedBigInteger> possible_epoch_ns, StringView time_zone, ISODateTime const& iso_date_time, Disambiguation disambiguation)
ThrowCompletionOr<Crypto::SignedBigInteger> disambiguate_possible_epoch_nanoseconds(VM& vm, Vector<Crypto::SignedBigInteger> 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<Crypto::SignedBigInteger> disambiguate_possible_epoch_nanoseco
}
// 11.1.13 GetPossibleEpochNanoseconds ( timeZone, isoDateTime ), https://tc39.es/proposal-temporal/#sec-temporal-getpossibleepochnanoseconds
ThrowCompletionOr<Vector<Crypto::SignedBigInteger>> get_possible_epoch_nanoseconds(VM& vm, StringView time_zone, ISODateTime const& iso_date_time)
ThrowCompletionOr<Vector<Crypto::SignedBigInteger>> get_possible_epoch_nanoseconds(VM& vm, String const& time_zone, ISODateTime const& iso_date_time)
{
Vector<Crypto::SignedBigInteger> possible_epoch_nanoseconds;
@ -364,7 +366,7 @@ ThrowCompletionOr<Vector<Crypto::SignedBigInteger>> get_possible_epoch_nanosecon
}
// 11.1.14 GetStartOfDay ( timeZone, isoDate ), https://tc39.es/proposal-temporal/#sec-temporal-getstartofday
ThrowCompletionOr<Crypto::SignedBigInteger> get_start_of_day(VM& vm, StringView time_zone, ISODate iso_date)
ThrowCompletionOr<Crypto::SignedBigInteger> 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<ParsedTimeZoneIdentifier> parse_time_zone_identifier(VM& vm, StringView identifier)
ThrowCompletionOr<ParsedTimeZoneIdentifier> 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<ParsedTimeZoneIdentifier> 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.

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2026, Tim Flynn <trflynn89@ladybird.org>
*
* 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<Crypto::SignedBigInteger> get_named_time_zone_next_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds);
Optional<Crypto::SignedBigInteger> get_named_time_zone_previous_transition(StringView time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds);
Optional<Crypto::SignedBigInteger> get_named_time_zone_next_transition(String const& time_zone, Crypto::SignedBigInteger const& epoch_nanoseconds);
Optional<Crypto::SignedBigInteger> 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<TimeStyle> = {});
String format_utc_offset_nanoseconds(i64 offset_nanoseconds);
String format_date_time_utc_offset_rounded(i64 offset_nanoseconds);
ThrowCompletionOr<String> 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<String> to_temporal_time_zone_identifier(VM&, StringView temporal_time_zone_like);
ThrowCompletionOr<Crypto::SignedBigInteger> get_epoch_nanoseconds_for(VM&, StringView time_zone, ISODateTime const&, Disambiguation);
ThrowCompletionOr<Crypto::SignedBigInteger> disambiguate_possible_epoch_nanoseconds(VM&, Vector<Crypto::SignedBigInteger> possible_epoch_ns, StringView time_zone, ISODateTime const&, Disambiguation);
ThrowCompletionOr<Vector<Crypto::SignedBigInteger>> get_possible_epoch_nanoseconds(VM&, StringView time_zone, ISODateTime const&);
ThrowCompletionOr<Crypto::SignedBigInteger> get_start_of_day(VM&, StringView time_zone, ISODate);
ThrowCompletionOr<Crypto::SignedBigInteger> get_epoch_nanoseconds_for(VM&, String const& time_zone, ISODateTime const&, Disambiguation);
ThrowCompletionOr<Crypto::SignedBigInteger> disambiguate_possible_epoch_nanoseconds(VM&, Vector<Crypto::SignedBigInteger> possible_epoch_ns, String const& time_zone, ISODateTime const&, Disambiguation);
ThrowCompletionOr<Vector<Crypto::SignedBigInteger>> get_possible_epoch_nanoseconds(VM&, String const& time_zone, ISODateTime const&);
ThrowCompletionOr<Crypto::SignedBigInteger> get_start_of_day(VM&, String const& time_zone, ISODate);
bool time_zone_equals(StringView one, StringView two);
ThrowCompletionOr<ParsedTimeZoneIdentifier> parse_time_zone_identifier(VM&, StringView identifier);
ParsedTimeZoneIdentifier parse_time_zone_identifier(StringView identifier);
ThrowCompletionOr<ParsedTimeZoneIdentifier> parse_time_zone_identifier(VM&, String const& identifier);
ParsedTimeZoneIdentifier parse_time_zone_identifier(String const& identifier);
ParsedTimeZoneIdentifier parse_time_zone_identifier(ParseResult const&);
}

View file

@ -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<Crypto::SignedBigInteger> interpret_iso_date_time_offset(VM& vm, ISODate iso_date, Variant<ParsedISODateTime::StartOfDay, Time> const& time_or_start_of_day, OffsetBehavior offset_behavior, double offset_nanoseconds, StringView time_zone, Disambiguation disambiguation, OffsetOption offset_option, MatchBehavior match_behavior)
ThrowCompletionOr<Crypto::SignedBigInteger> interpret_iso_date_time_offset(VM& vm, ISODate iso_date, Variant<ParsedISODateTime::StartOfDay, Time> 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<ParsedISODateTime::StartOfDay>()) {
@ -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<Crypto::SignedBigInteger> add_zoned_date_time(VM& vm, Crypto::SignedBigInteger const& epoch_nanoseconds, StringView time_zone, StringView calendar, InternalDuration const& duration, Overflow overflow)
ThrowCompletionOr<Crypto::SignedBigInteger> 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<Crypto::SignedBigInteger> 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<InternalDuration> difference_zoned_date_time(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit largest_unit)
ThrowCompletionOr<InternalDuration> 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<InternalDuration> 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<InternalDuration> 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<InternalDuration> 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<InternalDuration> 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<Crypto::BigFraction> difference_zoned_date_time_with_total(VM& vm, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit unit)
ThrowCompletionOr<Crypto::BigFraction> 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) {

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -48,14 +48,14 @@ enum class MatchBehavior {
MatchMinutes,
};
ThrowCompletionOr<Crypto::SignedBigInteger> interpret_iso_date_time_offset(VM&, ISODate, Variant<ParsedISODateTime::StartOfDay, Time> const&, OffsetBehavior, double offset_nanoseconds, StringView time_zone, Disambiguation, OffsetOption, MatchBehavior);
ThrowCompletionOr<Crypto::SignedBigInteger> interpret_iso_date_time_offset(VM&, ISODate, Variant<ParsedISODateTime::StartOfDay, Time> const&, OffsetBehavior, double offset_nanoseconds, String const& time_zone, Disambiguation, OffsetOption, MatchBehavior);
ThrowCompletionOr<GC::Ref<ZonedDateTime>> to_temporal_zoned_date_time(VM&, Value item, Value options = js_undefined());
ThrowCompletionOr<GC::Ref<ZonedDateTime>> create_temporal_zoned_date_time(VM&, BigInt const& epoch_nanoseconds, String time_zone, String calendar, GC::Ptr<FunctionObject> 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<Crypto::SignedBigInteger> add_zoned_date_time(VM&, Crypto::SignedBigInteger const& epoch_nanoseconds, StringView time_zone, StringView calendar, InternalDuration const&, Overflow);
ThrowCompletionOr<InternalDuration> difference_zoned_date_time(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit largest_unit);
ThrowCompletionOr<InternalDuration> 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<Crypto::BigFraction> difference_zoned_date_time_with_total(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, StringView time_zone, StringView calendar, Unit);
ThrowCompletionOr<Crypto::SignedBigInteger> add_zoned_date_time(VM&, Crypto::SignedBigInteger const& epoch_nanoseconds, String const& time_zone, StringView calendar, InternalDuration const&, Overflow);
ThrowCompletionOr<InternalDuration> difference_zoned_date_time(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit largest_unit);
ThrowCompletionOr<InternalDuration> 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<Crypto::BigFraction> difference_zoned_date_time_with_total(VM&, Crypto::SignedBigInteger const& nanoseconds1, Crypto::SignedBigInteger const& nanoseconds2, String const& time_zone, StringView calendar, Unit);
ThrowCompletionOr<GC::Ref<Duration>> difference_temporal_zoned_date_time(VM&, DurationOperation, ZonedDateTime const&, Value other, Value options);
ThrowCompletionOr<GC::Ref<ZonedDateTime>> add_duration_to_zoned_date_time(VM&, ArithmeticOperation, ZonedDateTime const&, Value temporal_duration_like, Value options);

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -69,7 +69,7 @@ ThrowCompletionOr<GC::Ref<Object>> ZonedDateTimeConstructor::construct(FunctionO
return vm.throw_completion<TypeError>(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;