summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Wilde <lukew@serenityos.org>2021-11-10 00:14:16 +0000
committerLinus Groh <mail@linusgroh.de>2021-11-10 12:56:56 +0000
commitdc72d416b259031155fdfad251c4fb53008b8189 (patch)
tree6d206328b29c8e4d1c5eccc5d52071a220304ee2
parent04253c32545b76f7d368545e7605e4f1c01bdd16 (diff)
downloadserenity-dc72d416b259031155fdfad251c4fb53008b8189.zip
LibJS: Implement the required AOs for ZonedDateTime stringifiers
-rw-r--r--Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp24
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp77
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h1
5 files changed, 105 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
index 6475163e0f..50e0f2800b 100644
--- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
+++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
@@ -436,6 +436,7 @@ namespace JS {
P(test) \
P(then) \
P(timeZone) \
+ P(timeZoneName) \
P(toDateString) \
P(toFixed) \
P(toGMTString) \
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp
index c501cb78a8..23b2715c6d 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp
@@ -248,6 +248,30 @@ ThrowCompletionOr<String> to_show_calendar_option(GlobalObject& global_object, O
return option.as_string().string();
}
+// 13.12 ToShowTimeZoneNameOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-toshowtimezonenameoption
+ThrowCompletionOr<String> to_show_time_zone_name_option(GlobalObject& global_object, Object const& normalized_options)
+{
+ auto& vm = global_object.vm();
+
+ // 1. Return ? GetOption(normalizedOptions, "timeZoneName", « String », « "auto", "never" », "auto").
+ auto option = TRY(get_option(global_object, normalized_options, vm.names.timeZoneName, { OptionType::String }, { "auto"sv, "never"sv }, js_string(vm, "auto"sv)));
+
+ VERIFY(option.is_string());
+ return option.as_string().string();
+}
+
+// 13.13 ToShowOffsetOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-toshowoffsetoption
+ThrowCompletionOr<String> to_show_offset_option(GlobalObject& global_object, Object const& normalized_options)
+{
+ auto& vm = global_object.vm();
+
+ // 1. Return ? GetOption(normalizedOptions, "offset", « String », « "auto", "never" », "auto").
+ auto option = TRY(get_option(global_object, normalized_options, vm.names.offset, { OptionType::String }, { "auto"sv, "never"sv }, js_string(vm, "auto"sv)));
+
+ VERIFY(option.is_string());
+ return option.as_string().string();
+}
+
// 13.14 ToTemporalRoundingIncrement ( normalizedOptions, dividend, inclusive ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalroundingincrement
ThrowCompletionOr<u64> to_temporal_rounding_increment(GlobalObject& global_object, Object const& normalized_options, Optional<double> dividend, bool inclusive)
{
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h
index ba8c80b80e..e8b5db0634 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h
@@ -99,6 +99,8 @@ ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject&, Object const
ThrowCompletionOr<String> to_temporal_rounding_mode(GlobalObject&, Object const& normalized_options, String const& fallback);
ThrowCompletionOr<String> to_temporal_offset(GlobalObject&, Object const& normalized_options, String const& fallback);
ThrowCompletionOr<String> to_show_calendar_option(GlobalObject&, Object const& normalized_options);
+ThrowCompletionOr<String> to_show_time_zone_name_option(GlobalObject&, Object const& normalized_options);
+ThrowCompletionOr<String> to_show_offset_option(GlobalObject&, Object const& normalized_options);
ThrowCompletionOr<u64> to_temporal_rounding_increment(GlobalObject&, Object const& normalized_options, Optional<double> dividend, bool inclusive);
ThrowCompletionOr<u64> to_temporal_date_time_rounding_increment(GlobalObject&, Object const& normalized_options, StringView smallest_unit);
ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObject&, Object const& normalized_options);
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp
index 5de69bed16..96c571edd2 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp
@@ -274,6 +274,83 @@ ThrowCompletionOr<ZonedDateTime*> create_temporal_zoned_date_time(GlobalObject&
return object;
}
+// 6.5.4 TemporalZonedDateTimeToString ( zonedDateTime, precision, showCalendar, showTimeZone, showOffset [ , increment, unit, roundingMode ] ), https://tc39.es/proposal-temporal/#sec-temporal-temporalzoneddatetimetostring
+ThrowCompletionOr<String> temporal_zoned_date_time_to_string(GlobalObject& global_object, ZonedDateTime& zoned_date_time, Variant<StringView, u8> const& precision, StringView show_calendar, StringView show_time_zone, StringView show_offset, Optional<u64> increment, Optional<StringView> unit, Optional<StringView> rounding_mode)
+{
+ // 1. Assert: Type(zonedDateTime) is Object and zonedDateTime has an [[InitializedTemporalZonedDateTime]] internal slot.
+
+ // 2. If increment is not present, set it to 1.
+ if (!increment.has_value())
+ increment = 1;
+
+ // 3. If unit is not present, set it to "nanosecond".
+ if (!unit.has_value())
+ unit = "nanosecond"sv;
+
+ // 4. If roundingMode is not present, set it to "trunc".
+ if (!rounding_mode.has_value())
+ rounding_mode = "trunc"sv;
+
+ // 5. Let ns be ! RoundTemporalInstant(zonedDateTime.[[Nanoseconds]], increment, unit, roundingMode).
+ auto* ns = round_temporal_instant(global_object, zoned_date_time.nanoseconds(), *increment, *unit, *rounding_mode);
+
+ // 6. Let timeZone be zonedDateTime.[[TimeZone]].
+ auto& time_zone = zoned_date_time.time_zone();
+
+ // 7. Let instant be ! CreateTemporalInstant(ns).
+ auto* instant = MUST(create_temporal_instant(global_object, *ns));
+
+ // 8. Let isoCalendar be ! GetISO8601Calendar().
+ auto* iso_calendar = get_iso8601_calendar(global_object);
+
+ // 9. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, isoCalendar).
+ auto* temporal_date_time = TRY(builtin_time_zone_get_plain_date_time_for(global_object, &time_zone, *instant, *iso_calendar));
+
+ // 10. Let dateTimeString be ? TemporalDateTimeToString(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], isoCalendar, precision, "never").
+ auto date_time_string = TRY(temporal_date_time_to_string(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), iso_calendar, precision, "never"sv));
+
+ String offset_string;
+
+ // 11. If showOffset is "never", then
+ if (show_offset == "never"sv) {
+ // a. Let offsetString be the empty String.
+ offset_string = String::empty();
+ }
+ // Else,
+ else {
+ // a. Let offsetNs be ? GetOffsetNanosecondsFor(timeZone, instant).
+ auto offset_ns = TRY(get_offset_nanoseconds_for(global_object, &time_zone, *instant));
+
+ // b. Let offsetString be ! FormatISOTimeZoneOffsetString(offsetNs).
+ offset_string = format_iso_time_zone_offset_string(offset_ns);
+ }
+
+ String time_zone_string;
+
+ // 13. If showTimeZone is "never", then
+ if (show_time_zone == "never"sv) {
+ // a. Let timeZoneString be the empty String.
+ time_zone_string = String::empty();
+ }
+ // 14. Else,
+ else {
+ // a. Let timeZoneID be ? ToString(timeZone).
+ auto time_zone_id = TRY(Value(&time_zone).to_string(global_object));
+
+ // b. Let timeZoneString be the string-concatenation of the code unit 0x005B (LEFT SQUARE BRACKET), timeZoneID, and the code unit 0x005D (RIGHT SQUARE BRACKET).
+ time_zone_string = String::formatted("[{}]", time_zone_id);
+ }
+
+ // 15. Let calendarID be ? ToString(zonedDateTime.[[Calendar]]).
+ auto calendar_id = TRY(Value(&zoned_date_time.calendar()).to_string(global_object));
+
+ // 16. Let calendarString be ! FormatCalendarAnnotation(calendarID, showCalendar).
+ auto calendar_string = format_calendar_annotation(calendar_id, show_calendar);
+
+ // 17. Return the string-concatenation of dateTimeString, offsetString, timeZoneString, and calendarString.
+ return String::formatted("{}{}{}{}", date_time_string, offset_string, time_zone_string, calendar_string);
+}
+
// 6.5.5 AddZonedDateTime ( epochNanoseconds, timeZone, calendar, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-addzoneddatetime
ThrowCompletionOr<BigInt*> add_zoned_date_time(GlobalObject& global_object, BigInt const& epoch_nanoseconds, Value time_zone, Object& calendar, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object* options)
{
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h
index ccc940411b..9dcd2a0e2a 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.h
@@ -54,6 +54,7 @@ enum class MatchBehavior {
ThrowCompletionOr<BigInt const*> interpret_iso_date_time_offset(GlobalObject&, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, OffsetBehavior offset_behavior, double offset_nanoseconds, Value time_zone, StringView disambiguation, StringView offset_option, MatchBehavior match_behavior);
ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject&, Value item, Object* options = nullptr);
ThrowCompletionOr<ZonedDateTime*> create_temporal_zoned_date_time(GlobalObject&, BigInt const& epoch_nanoseconds, Object& time_zone, Object& calendar, FunctionObject const* new_target = nullptr);
+ThrowCompletionOr<String> temporal_zoned_date_time_to_string(GlobalObject&, ZonedDateTime& zoned_date_time, Variant<StringView, u8> const& precision, StringView show_calendar, StringView show_time_zone, StringView show_offset, Optional<u64> increment = {}, Optional<StringView> unit = {}, Optional<StringView> rounding_mode = {});
ThrowCompletionOr<BigInt*> add_zoned_date_time(GlobalObject&, BigInt const& epoch_nanoseconds, Value time_zone, Object& calendar, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object* options = nullptr);
ThrowCompletionOr<NanosecondsToDaysResult> nanoseconds_to_days(GlobalObject&, BigInt const& nanoseconds, Value relative_to);