1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 05:27:43 +00:00

LibJS: Consistently call observable Temporal AOs with undefined options

This is a normative change in the Temporal spec.

See: 6fa5b9d
This commit is contained in:
Linus Groh 2022-04-06 23:56:57 +01:00
parent 85327e6b5d
commit 151eb8606d
21 changed files with 226 additions and 261 deletions

View file

@ -191,25 +191,33 @@ ThrowCompletionOr<Variant<String, NumberType>> get_string_or_number_option(Globa
return value.as_string().string(); return value.as_string().string();
} }
// 13.5 ToTemporalOverflow ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloverflow // 13.5 ToTemporalOverflow ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloverflow
ThrowCompletionOr<String> to_temporal_overflow(GlobalObject& global_object, Object const& normalized_options) ThrowCompletionOr<String> to_temporal_overflow(GlobalObject& global_object, Object const* options)
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. Return ? GetOption(normalizedOptions, "overflow", « String », « "constrain", "reject" », "constrain"). // 1. If options is undefined, return "constrain".
auto option = TRY(get_option(global_object, normalized_options, vm.names.overflow, { OptionType::String }, { "constrain"sv, "reject"sv }, js_string(vm, "constrain"))); if (options == nullptr)
return "constrain"sv;
// 2. Return ? GetOption(options, "overflow", « String », « "constrain", "reject" », "constrain").
auto option = TRY(get_option(global_object, *options, vm.names.overflow, { OptionType::String }, { "constrain"sv, "reject"sv }, js_string(vm, "constrain")));
VERIFY(option.is_string()); VERIFY(option.is_string());
return option.as_string().string(); return option.as_string().string();
} }
// 13.6 ToTemporalDisambiguation ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation // 13.6 ToTemporalDisambiguation ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation
ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject& global_object, Object const& normalized_options) ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject& global_object, Object const* options)
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. Return ? GetOption(normalizedOptions, "disambiguation", « String », « "compatible", "earlier", "later", "reject" », "compatible"). // 1. If options is undefined, return "compatible".
auto option = TRY(get_option(global_object, normalized_options, vm.names.disambiguation, { OptionType::String }, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, js_string(vm, "compatible"))); if (options == nullptr)
return "compatible"sv;
// 2. Return ? GetOption(options, "disambiguation", « String », « "compatible", "earlier", "later", "reject" », "compatible").
auto option = TRY(get_option(global_object, *options, vm.names.disambiguation, { OptionType::String }, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, js_string(vm, "compatible")));
VERIFY(option.is_string()); VERIFY(option.is_string());
return option.as_string().string(); return option.as_string().string();
@ -242,13 +250,17 @@ StringView negate_temporal_rounding_mode(String const& rounding_mode)
return rounding_mode; return rounding_mode;
} }
// 13.9 ToTemporalOffset ( normalizedOptions, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloffset // 13.9 ToTemporalOffset ( options, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloffset
ThrowCompletionOr<String> to_temporal_offset(GlobalObject& global_object, Object const& normalized_options, String const& fallback) ThrowCompletionOr<String> to_temporal_offset(GlobalObject& global_object, Object const* options, String const& fallback)
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. Return ? GetOption(normalizedOptions, "offset", « String », « "prefer", "use", "ignore", "reject" », fallback). // 1. If options is undefined, return fallback.
auto option = TRY(get_option(global_object, normalized_options, vm.names.offset, { OptionType::String }, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, js_string(vm, fallback))); if (options == nullptr)
return fallback;
// 2. Return ? GetOption(options, "offset", « String », « "prefer", "use", "ignore", "reject" », fallback).
auto option = TRY(get_option(global_object, *options, vm.names.offset, { OptionType::String }, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, js_string(vm, fallback)));
VERIFY(option.is_string()); VERIFY(option.is_string());
return option.as_string().string(); return option.as_string().string();

View file

@ -102,11 +102,11 @@ ThrowCompletionOr<Object*> get_options_object(GlobalObject&, Value options);
ThrowCompletionOr<Value> get_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<OptionType> const& types, Vector<StringView> const& values, Value fallback); ThrowCompletionOr<Value> get_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<OptionType> const& types, Vector<StringView> const& values, Value fallback);
template<typename NumberType> template<typename NumberType>
ThrowCompletionOr<Variant<String, NumberType>> get_string_or_number_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<StringView> const& string_values, NumberType minimum, NumberType maximum, Value fallback); ThrowCompletionOr<Variant<String, NumberType>> get_string_or_number_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<StringView> const& string_values, NumberType minimum, NumberType maximum, Value fallback);
ThrowCompletionOr<String> to_temporal_overflow(GlobalObject&, Object const& normalized_options); ThrowCompletionOr<String> to_temporal_overflow(GlobalObject&, Object const* options);
ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject&, Object const& normalized_options); ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject&, Object const* options);
ThrowCompletionOr<String> to_temporal_rounding_mode(GlobalObject&, Object const& normalized_options, String const& fallback); ThrowCompletionOr<String> to_temporal_rounding_mode(GlobalObject&, Object const& normalized_options, String const& fallback);
StringView negate_temporal_rounding_mode(String const& rounding_mode); StringView negate_temporal_rounding_mode(String const& rounding_mode);
ThrowCompletionOr<String> to_temporal_offset(GlobalObject&, Object const& normalized_options, String const& fallback); ThrowCompletionOr<String> to_temporal_offset(GlobalObject&, Object const* options, String const& fallback);
ThrowCompletionOr<String> to_show_calendar_option(GlobalObject&, Object const& normalized_options); 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_time_zone_name_option(GlobalObject&, Object const& normalized_options);
ThrowCompletionOr<String> to_show_offset_option(GlobalObject&, Object const& normalized_options); ThrowCompletionOr<String> to_show_offset_option(GlobalObject&, Object const& normalized_options);

View file

@ -134,27 +134,29 @@ ThrowCompletionOr<Object*> calendar_merge_fields(GlobalObject& global_object, Ob
return &result.as_object(); return &result.as_object();
} }
// 12.1.7 CalendarDateAdd ( calendar, date, duration, options [ , dateAdd ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateadd // 12.1.7 CalendarDateAdd ( calendar, date, duration [ , options [ , dateAdd ] ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateadd
ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject& global_object, Object& calendar, Value date, Duration& duration, Object* options, FunctionObject* date_add) ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject& global_object, Object& calendar, Value date, Duration& duration, Object* options, FunctionObject* date_add)
{ {
// NOTE: `date` is a `Value` because we sometimes need to pass a PlainDate, sometimes a PlainDateTime, and sometimes undefined. // NOTE: `date` is a `Value` because we sometimes need to pass a PlainDate, sometimes a PlainDateTime, and sometimes undefined.
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. Assert: Type(calendar) is Object. // 1. Assert: Type(calendar) is Object.
// 2. If options is not present, set options to undefined.
// 3. Assert: Type(options) is Object or Undefined.
// 2. If dateAdd is not present, set dateAdd to ? GetMethod(calendar, "dateAdd"). // 4. If dateAdd is not present, set dateAdd to ? GetMethod(calendar, "dateAdd").
if (!date_add) if (!date_add)
date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd)); date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
// 3. Let addedDate be ? Call(dateAdd, calendar, « date, duration, options »). // 5. Let addedDate be ? Call(dateAdd, calendar, « date, duration, options »).
auto added_date = TRY(call(global_object, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined())); auto added_date = TRY(call(global_object, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined()));
// 4. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]). // 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]).
auto* added_date_object = TRY(added_date.to_object(global_object)); auto* added_date_object = TRY(added_date.to_object(global_object));
if (!is<PlainDate>(added_date_object)) if (!is<PlainDate>(added_date_object))
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate"); return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
// 5. Return addedDate. // 7. Return addedDate.
return static_cast<PlainDate*>(added_date_object); return static_cast<PlainDate*>(added_date_object);
} }
@ -456,23 +458,25 @@ ThrowCompletionOr<Object*> get_temporal_calendar_with_iso_default(GlobalObject&
return to_temporal_calendar_with_iso_default(global_object, calendar_like); return to_temporal_calendar_with_iso_default(global_object, calendar_like);
} }
// 12.1.24 DateFromFields ( calendar, fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-datefromfields // 12.1.24 DateFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-datefromfields
ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options) ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options)
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. Assert: Type(calendar) is Object. // 1. Assert: Type(calendar) is Object.
// 2. Assert: Type(fields) is Object. // 2. Assert: Type(fields) is Object.
// 3. If options is not present, set options to undefined.
// 4. Assert: Type(options) is Object or Undefined.
// 3. Let date be ? Invoke(calendar, "dateFromFields", « fields, options »). // 5. Let date be ? Invoke(calendar, "dateFromFields", « fields, options »).
auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, options ?: js_undefined())); auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, options ?: js_undefined()));
// 4. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]). // 6. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
auto* date_object = TRY(date.to_object(global_object)); auto* date_object = TRY(date.to_object(global_object));
if (!is<PlainDate>(date_object)) if (!is<PlainDate>(date_object))
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate"); return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
// 5. Return date. // 7. Return date.
return static_cast<PlainDate*>(date_object); return static_cast<PlainDate*>(date_object);
} }
@ -483,10 +487,8 @@ ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject& global_o
// 1. Assert: Type(calendar) is Object. // 1. Assert: Type(calendar) is Object.
// 2. Assert: Type(fields) is Object. // 2. Assert: Type(fields) is Object.
// 3. If options is not present, then // 3. If options is not present, set options to undefined.
// a. Set options to undefined. // 4. Assert: Type(options) is Object or Undefined.
// 4. Else,
// a. Assert: Type(options) is Object.
// 5. Let yearMonth be ? Invoke(calendar, "yearMonthFromFields", « fields, options »). // 5. Let yearMonth be ? Invoke(calendar, "yearMonthFromFields", « fields, options »).
auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined())); auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined()));
@ -507,10 +509,8 @@ ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject& global_obj
// 1. Assert: Type(calendar) is Object. // 1. Assert: Type(calendar) is Object.
// 2. Assert: Type(fields) is Object. // 2. Assert: Type(fields) is Object.
// 3. If options is not present, then // 3. If options is not present, set options to undefined.
// a. Set options to undefined. // 4. Assert: Type(options) is Object or Undefined.
// 4. Else,
// a. Assert: Type(options) is Object.
// 5. Let monthDay be ? Invoke(calendar, "monthDayFromFields", « fields, options »). // 5. Let monthDay be ? Invoke(calendar, "monthDayFromFields", « fields, options »).
auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined())); auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined()));
@ -794,7 +794,7 @@ ThrowCompletionOr<ISODate> iso_date_from_fields(GlobalObject& global_object, Obj
// 1. Assert: Type(fields) is Object. // 1. Assert: Type(fields) is Object.
// 2. Let overflow be ? ToTemporalOverflow(options). // 2. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(global_object, options)); auto overflow = TRY(to_temporal_overflow(global_object, &options));
// 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»). // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»).
auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day", "month", "monthCode", "year" }, {})); auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day", "month", "monthCode", "year" }, {}));
@ -828,7 +828,7 @@ ThrowCompletionOr<ISOYearMonth> iso_year_month_from_fields(GlobalObject& global_
// 1. Assert: Type(fields) is Object. // 1. Assert: Type(fields) is Object.
// 2. Let overflow be ? ToTemporalOverflow(options). // 2. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(global_object, options)); auto overflow = TRY(to_temporal_overflow(global_object, &options));
// 3. Set fields to ? PrepareTemporalFields(fields, « "month", "monthCode", "year" », «»). // 3. Set fields to ? PrepareTemporalFields(fields, « "month", "monthCode", "year" », «»).
auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "month"sv, "monthCode"sv, "year"sv }, {})); auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "month"sv, "monthCode"sv, "year"sv }, {}));
@ -858,7 +858,7 @@ ThrowCompletionOr<ISOMonthDay> iso_month_day_from_fields(GlobalObject& global_ob
// 1. Assert: Type(fields) is Object. // 1. Assert: Type(fields) is Object.
// 2. Let overflow be ? ToTemporalOverflow(options). // 2. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(global_object, options)); auto overflow = TRY(to_temporal_overflow(global_object, &options));
// 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»). // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»).
auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day"sv, "month"sv, "monthCode"sv, "year"sv }, {})); auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day"sv, "month"sv, "monthCode"sv, "year"sv }, {}));

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -36,7 +36,7 @@ ThrowCompletionOr<Calendar*> get_builtin_calendar(GlobalObject&, String const& i
Calendar* get_iso8601_calendar(GlobalObject&); Calendar* get_iso8601_calendar(GlobalObject&);
ThrowCompletionOr<Vector<String>> calendar_fields(GlobalObject&, Object& calendar, Vector<StringView> const& field_names); ThrowCompletionOr<Vector<String>> calendar_fields(GlobalObject&, Object& calendar, Vector<StringView> const& field_names);
ThrowCompletionOr<Object*> calendar_merge_fields(GlobalObject&, Object& calendar, Object& fields, Object& additional_fields); ThrowCompletionOr<Object*> calendar_merge_fields(GlobalObject&, Object& calendar, Object& fields, Object& additional_fields);
ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject&, Object& calendar, Value date, Duration&, Object* options, FunctionObject* date_add = nullptr); ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject&, Object& calendar, Value date, Duration&, Object* options = nullptr, FunctionObject* date_add = nullptr);
ThrowCompletionOr<Duration*> calendar_date_until(GlobalObject&, Object& calendar, Value one, Value two, Object& options, FunctionObject* date_until = nullptr); ThrowCompletionOr<Duration*> calendar_date_until(GlobalObject&, Object& calendar, Value one, Value two, Object& options, FunctionObject* date_until = nullptr);
ThrowCompletionOr<double> calendar_year(GlobalObject&, Object& calendar, Object& date_like); ThrowCompletionOr<double> calendar_year(GlobalObject&, Object& calendar, Object& date_like);
ThrowCompletionOr<double> calendar_month(GlobalObject&, Object& calendar, Object& date_like); ThrowCompletionOr<double> calendar_month(GlobalObject&, Object& calendar, Object& date_like);
@ -57,7 +57,7 @@ ThrowCompletionOr<Object*> to_temporal_calendar_with_iso_default(GlobalObject&,
ThrowCompletionOr<Object*> get_temporal_calendar_with_iso_default(GlobalObject&, Object&); ThrowCompletionOr<Object*> get_temporal_calendar_with_iso_default(GlobalObject&, Object&);
ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr); ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr); ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options = nullptr); ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
String format_calendar_annotation(StringView id, StringView show_calendar); String format_calendar_annotation(StringView id, StringView show_calendar);
ThrowCompletionOr<bool> calendar_equals(GlobalObject&, Object& one, Object& two); ThrowCompletionOr<bool> calendar_equals(GlobalObject&, Object& one, Object& two);
ThrowCompletionOr<Object*> consolidate_calendars(GlobalObject&, Object& one, Object& two); ThrowCompletionOr<Object*> consolidate_calendars(GlobalObject&, Object& one, Object& two);

View file

@ -172,7 +172,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::date_add)
auto* options = TRY(get_options_object(global_object, vm.argument(2))); auto* options = TRY(get_options_object(global_object, vm.argument(2)));
// 7. Let overflow be ? ToTemporalOverflow(options). // 7. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(global_object, *options)); auto overflow = TRY(to_temporal_overflow(global_object, options));
// 8. Let balanceResult be ! BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day"). // 8. Let balanceResult be ! BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day").
// FIXME: Narrowing conversion from 'double' to 'i64' // FIXME: Narrowing conversion from 'double' to 'i64'

View file

@ -623,31 +623,28 @@ ThrowCompletionOr<DateDurationRecord> unbalance_duration_relative(GlobalObject&
// d. Repeat, while years ≠ 0, // d. Repeat, while years ≠ 0,
while (years != 0) { while (years != 0) {
// i. Let addOptions be OrdinaryObjectCreate(null). // i. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd).
auto* add_options = Object::create(global_object, nullptr); auto* new_relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *one_year, nullptr, date_add));
// ii. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd). // ii. Let untilOptions be OrdinaryObjectCreate(null).
auto* new_relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *one_year, add_options, date_add));
// iii. Let untilOptions be OrdinaryObjectCreate(null).
auto* until_options = Object::create(global_object, nullptr); auto* until_options = Object::create(global_object, nullptr);
// iv. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). // iii. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv))); MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
// v. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). // iv. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
auto* until_result = TRY(calendar_date_until(global_object, *calendar, relative_to, new_relative_to, *until_options, date_until)); auto* until_result = TRY(calendar_date_until(global_object, *calendar, relative_to, new_relative_to, *until_options, date_until));
// vi. Let oneYearMonths be untilResult.[[Months]]. // v. Let oneYearMonths be untilResult.[[Months]].
auto one_year_months = until_result->months(); auto one_year_months = until_result->months();
// vii. Set relativeTo to newRelativeTo. // vi. Set relativeTo to newRelativeTo.
relative_to = new_relative_to; relative_to = new_relative_to;
// viii. Set years to years sign. // vii. Set years to years sign.
years -= sign; years -= sign;
// ix. Set months to months + oneYearMonths. // viii. Set months to months + oneYearMonths.
months += one_year_months; months += one_year_months;
} }
} }
@ -844,28 +841,25 @@ ThrowCompletionOr<DateDurationRecord> balance_duration_relative(GlobalObject& gl
// i. Let dateAdd be ? GetMethod(calendar, "dateAdd"). // i. Let dateAdd be ? GetMethod(calendar, "dateAdd").
auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd)); auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
// j. Let addOptions be OrdinaryObjectCreate(null). // j. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd).
auto* add_options = Object::create(global_object, nullptr); auto* new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, nullptr, date_add));
// k. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd). // k. Let dateUntil be ? GetMethod(calendar, "dateUntil").
auto* new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, add_options, date_add));
// l. Let dateUntil be ? GetMethod(calendar, "dateUntil").
auto* date_until = TRY(Value(&calendar).get_method(global_object, vm.names.dateUntil)); auto* date_until = TRY(Value(&calendar).get_method(global_object, vm.names.dateUntil));
// m. Let untilOptions be OrdinaryObjectCreate(null). // l. Let untilOptions be OrdinaryObjectCreate(null).
auto* until_options = Object::create(global_object, nullptr); auto* until_options = Object::create(global_object, nullptr);
// n. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). // m. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv))); MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
// o. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). // n. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
auto* until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until)); auto* until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until));
// p. Let oneYearMonths be untilResult.[[Months]]. // o. Let oneYearMonths be untilResult.[[Months]].
auto one_year_months = until_result->months(); auto one_year_months = until_result->months();
// q. Repeat, while abs(months) ≥ abs(oneYearMonths), // p. Repeat, while abs(months) ≥ abs(oneYearMonths),
while (fabs(months) >= fabs(one_year_months)) { while (fabs(months) >= fabs(one_year_months)) {
// i. Set months to months oneYearMonths. // i. Set months to months oneYearMonths.
months -= one_year_months; months -= one_year_months;
@ -876,22 +870,19 @@ ThrowCompletionOr<DateDurationRecord> balance_duration_relative(GlobalObject& gl
// iii. Set relativeTo to newRelativeTo. // iii. Set relativeTo to newRelativeTo.
relative_to = new_relative_to; relative_to = new_relative_to;
// iv. Set addOptions to OrdinaryObjectCreate(null). // iv. Set newRelativeTo to ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd).
add_options = Object::create(global_object, nullptr); new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, nullptr, date_add));
// v. Set newRelativeTo to ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd). // v. Set untilOptions to OrdinaryObjectCreate(null).
new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, add_options, date_add));
// vi. Set untilOptions to OrdinaryObjectCreate(null).
until_options = Object::create(global_object, nullptr); until_options = Object::create(global_object, nullptr);
// vii. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). // vi. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv))); MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
// viii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). // vii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until)); until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until));
// ix. Set oneYearMonths to untilResult.[[Months]]. // viii. Set oneYearMonths to untilResult.[[Months]].
one_year_months = until_result->months(); one_year_months = until_result->months();
} }
} }
@ -1009,35 +1000,29 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
// d. Let dateAdd be ? GetMethod(calendar, "dateAdd"). // d. Let dateAdd be ? GetMethod(calendar, "dateAdd").
auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd)); auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
// e. Let firstAddOptions be OrdinaryObjectCreate(null). // e. Let intermediate be ? CalendarDateAdd(calendar, relativeTo, dateDuration1, undefined, dateAdd).
auto* first_add_options = Object::create(global_object, nullptr); auto* intermediate = TRY(calendar_date_add(global_object, calendar, &relative_to, *date_duration1, nullptr, date_add));
// f. Let intermediate be ? CalendarDateAdd(calendar, relativeTo, dateDuration1, firstAddOptions, dateAdd). // f. Let end be ? CalendarDateAdd(calendar, intermediate, dateDuration2, undefined, dateAdd).
auto* intermediate = TRY(calendar_date_add(global_object, calendar, &relative_to, *date_duration1, first_add_options, date_add)); auto* end = TRY(calendar_date_add(global_object, calendar, intermediate, *date_duration2, nullptr, date_add));
// g. Let secondAddOptions be OrdinaryObjectCreate(null). // g. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
auto* second_add_options = Object::create(global_object, nullptr);
// h. Let end be ? CalendarDateAdd(calendar, intermediate, dateDuration2, secondAddOptions, dateAdd).
auto* end = TRY(calendar_date_add(global_object, calendar, intermediate, *date_duration2, second_add_options, date_add));
// i. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit); auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit);
// j. Let differenceOptions be OrdinaryObjectCreate(null). // h. Let differenceOptions be OrdinaryObjectCreate(null).
auto* difference_options = Object::create(global_object, nullptr); auto* difference_options = Object::create(global_object, nullptr);
// k. Perform ! CreateDataPropertyOrThrow(differenceOptions, "largestUnit", dateLargestUnit). // i. Perform ! CreateDataPropertyOrThrow(differenceOptions, "largestUnit", dateLargestUnit).
MUST(difference_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, date_largest_unit))); MUST(difference_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, date_largest_unit)));
// l. Let dateDifference be ? CalendarDateUntil(calendar, relativeTo, end, differenceOptions). // j. Let dateDifference be ? CalendarDateUntil(calendar, relativeTo, end, differenceOptions).
auto* date_difference = TRY(calendar_date_until(global_object, calendar, &relative_to, end, *difference_options)); auto* date_difference = TRY(calendar_date_until(global_object, calendar, &relative_to, end, *difference_options));
// m. Let result be ! BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit). // k. Let result be ! BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
// FIXME: Narrowing conversion from 'double' to 'i64' // FIXME: Narrowing conversion from 'double' to 'i64'
auto result = MUST(balance_duration(global_object, date_difference->days(), hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger::create_from(nanoseconds1 + nanoseconds2), largest_unit)); auto result = MUST(balance_duration(global_object, date_difference->days(), hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger::create_from(nanoseconds1 + nanoseconds2), largest_unit));
// n. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]). // l. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
return create_duration_record(global_object, date_difference->years(), date_difference->months(), date_difference->weeks(), result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds); return create_duration_record(global_object, date_difference->years(), date_difference->months(), date_difference->weeks(), result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds);
} }
@ -1075,16 +1060,13 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
// 7.5.23 MoveRelativeDate ( calendar, relativeTo, duration ), https://tc39.es/proposal-temporal/#sec-temporal-moverelativedate // 7.5.23 MoveRelativeDate ( calendar, relativeTo, duration ), https://tc39.es/proposal-temporal/#sec-temporal-moverelativedate
ThrowCompletionOr<MoveRelativeDateResult> move_relative_date(GlobalObject& global_object, Object& calendar, PlainDate& relative_to, Duration& duration) ThrowCompletionOr<MoveRelativeDateResult> move_relative_date(GlobalObject& global_object, Object& calendar, PlainDate& relative_to, Duration& duration)
{ {
// 1. Let options be OrdinaryObjectCreate(null). // 1. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options).
auto* options = Object::create(global_object, nullptr); auto* new_date = TRY(calendar_date_add(global_object, calendar, &relative_to, duration));
// 2. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options). // 2. Let days be ! DaysUntil(relativeTo, newDate).
auto* new_date = TRY(calendar_date_add(global_object, calendar, &relative_to, duration, options));
// 3. Let days be ! DaysUntil(relativeTo, newDate).
auto days = days_until(global_object, relative_to, *new_date); auto days = days_until(global_object, relative_to, *new_date);
// 4. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }. // 3. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }.
return MoveRelativeDateResult { .relative_to = make_handle(new_date), .days = days }; return MoveRelativeDateResult { .relative_to = make_handle(new_date), .days = days };
} }
@ -1199,94 +1181,82 @@ ThrowCompletionOr<RoundedDuration> round_duration(GlobalObject& global_object, d
// b. Let dateAdd be ? GetMethod(calendar, "dateAdd"). // b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd)); auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd));
// c. Let firstAddOptions be OrdinaryObjectCreate(null). // c. Let yearsLater be ? CalendarDateAdd(calendar, relativeTo, yearsDuration, undefined, dateAdd).
auto* first_add_options = Object::create(global_object, nullptr); auto* years_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, nullptr, date_add));
// d. Let yearsLater be ? CalendarDateAdd(calendar, relativeTo, yearsDuration, firstAddOptions, dateAdd). // d. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
auto* years_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, first_add_options, date_add));
// e. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0)); auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0));
// f. Let secondAddOptions be OrdinaryObjectCreate(null). // e. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd).
auto* second_add_options = Object::create(global_object, nullptr); auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, nullptr, date_add));
// g. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, secondAddOptions, dateAdd). // f. Let monthsWeeksInDays be ? DaysUntil(yearsLater, yearsMonthsWeeksLater).
auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, second_add_options, date_add));
// h. Let monthsWeeksInDays be ? DaysUntil(yearsLater, yearsMonthsWeeksLater).
auto months_weeks_in_days = days_until(global_object, *years_later, *years_months_weeks_later); auto months_weeks_in_days = days_until(global_object, *years_later, *years_months_weeks_later);
// i. Set relativeTo to yearsLater. // g. Set relativeTo to yearsLater.
relative_to = years_later; relative_to = years_later;
// j. Let days be days + monthsWeeksInDays. // h. Let days be days + monthsWeeksInDays.
days += months_weeks_in_days; days += months_weeks_in_days;
// k. Let daysDuration be ? CreateTemporalDuration(0, 0, 0, days, 0, 0, 0, 0, 0, 0). // i. Let daysDuration be ? CreateTemporalDuration(0, 0, 0, days, 0, 0, 0, 0, 0, 0).
auto* days_duration = TRY(create_temporal_duration(global_object, 0, 0, 0, days, 0, 0, 0, 0, 0, 0)); auto* days_duration = TRY(create_temporal_duration(global_object, 0, 0, 0, days, 0, 0, 0, 0, 0, 0));
// l. Let thirdAddOptions be OrdinaryObjectCreate(null). // j. Let daysLater be ? CalendarDateAdd(calendar, relativeTo, daysDuration, undefined, dateAdd).
auto* third_add_options = Object::create(global_object, nullptr); auto* days_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *days_duration, nullptr, date_add));
// m. Let daysLater be ? CalendarDateAdd(calendar, relativeTo, daysDuration, thirdAddOptions, dateAdd). // k. Let untilOptions be OrdinaryObjectCreate(null).
auto* days_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *days_duration, third_add_options, date_add));
// n. Let untilOptions be OrdinaryObjectCreate(null).
auto* until_options = Object::create(global_object, nullptr); auto* until_options = Object::create(global_object, nullptr);
// o. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "year"). // l. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "year").
MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "year"sv))); MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "year"sv)));
// p. Let timePassed be ? CalendarDateUntil(calendar, relativeTo, daysLater, untilOptions). // m. Let timePassed be ? CalendarDateUntil(calendar, relativeTo, daysLater, untilOptions).
auto* time_passed = TRY(calendar_date_until(global_object, *calendar, relative_to, days_later, *until_options)); auto* time_passed = TRY(calendar_date_until(global_object, *calendar, relative_to, days_later, *until_options));
// q. Let yearsPassed be timePassed.[[Years]]. // n. Let yearsPassed be timePassed.[[Years]].
auto years_passed = time_passed->years(); auto years_passed = time_passed->years();
// r. Set years to years + yearsPassed. // o. Set years to years + yearsPassed.
years += years_passed; years += years_passed;
// s. Let oldRelativeTo be relativeTo. // p. Let oldRelativeTo be relativeTo.
auto* old_relative_to = relative_to; auto* old_relative_to = relative_to;
// t. Let yearsDuration be ! CreateTemporalDuration(yearsPassed, 0, 0, 0, 0, 0, 0, 0, 0, 0). // q. Let yearsDuration be ! CreateTemporalDuration(yearsPassed, 0, 0, 0, 0, 0, 0, 0, 0, 0).
years_duration = MUST(create_temporal_duration(global_object, years_passed, 0, 0, 0, 0, 0, 0, 0, 0, 0)); years_duration = MUST(create_temporal_duration(global_object, years_passed, 0, 0, 0, 0, 0, 0, 0, 0, 0));
// u. Let fourthAddOptions be OrdinaryObjectCreate(null). // r. Set relativeTo to ? CalendarDateAdd(calendar, relativeTo, yearsDuration, undefined, dateAdd).
auto* fourth_add_options = Object::create(global_object, nullptr); relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, nullptr, date_add));
// v. Set relativeTo to ? CalendarDateAdd(calendar, relativeTo, yearsDuration, fourthAddOptions, dateAdd). // s. Let daysPassed be ? DaysUntil(oldRelativeTo, relativeTo).
relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, fourth_add_options, date_add));
// w. Let daysPassed be ? DaysUntil(oldRelativeTo, relativeTo).
auto days_passed = days_until(global_object, *old_relative_to, *relative_to); auto days_passed = days_until(global_object, *old_relative_to, *relative_to);
// x. Set days to days - daysPassed. // t. Set days to days - daysPassed.
days -= days_passed; days -= days_passed;
// y. If days < 0, let sign be 1; else, let sign be 1. // u. If days < 0, let sign be 1; else, let sign be 1.
auto sign = days < 0 ? -1 : 1; auto sign = days < 0 ? -1 : 1;
// z. Let oneYear be ! CreateTemporalDuration(sign, 0, 0, 0, 0, 0, 0, 0, 0, 0). // v. Let oneYear be ! CreateTemporalDuration(sign, 0, 0, 0, 0, 0, 0, 0, 0, 0).
auto* one_year = MUST(create_temporal_duration(global_object, sign, 0, 0, 0, 0, 0, 0, 0, 0, 0)); auto* one_year = MUST(create_temporal_duration(global_object, sign, 0, 0, 0, 0, 0, 0, 0, 0, 0));
// aa. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneYear). // w. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneYear).
auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_year)); auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_year));
// ab. Let oneYearDays be moveResult.[[Days]]. // x. Let oneYearDays be moveResult.[[Days]].
auto one_year_days = move_result.days; auto one_year_days = move_result.days;
// ac. Let fractionalYears be years + days / abs(oneYearDays). // y. Let fractionalYears be years + days / abs(oneYearDays).
auto fractional_years = years + days / fabs(one_year_days); auto fractional_years = years + days / fabs(one_year_days);
// ad. Set years to ! RoundNumberToIncrement(fractionalYears, increment, roundingMode). // z. Set years to ! RoundNumberToIncrement(fractionalYears, increment, roundingMode).
years = (double)round_number_to_increment(fractional_years, increment, rounding_mode); years = (double)round_number_to_increment(fractional_years, increment, rounding_mode);
// ae. Set remainder to fractionalYears - years. // aa. Set remainder to fractionalYears - years.
remainder = fractional_years - years; remainder = fractional_years - years;
// af. Set months, weeks, and days to 0. // ab. Set months, weeks, and days to 0.
months = 0; months = 0;
weeks = 0; weeks = 0;
days = 0; days = 0;
@ -1301,46 +1271,40 @@ ThrowCompletionOr<RoundedDuration> round_duration(GlobalObject& global_object, d
// b. Let dateAdd be ? GetMethod(calendar, "dateAdd"). // b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd)); auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd));
// c. Let firstAddOptions be OrdinaryObjectCreate(null). // c. Let yearsMonthsLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonths, undefined, dateAdd).
auto* first_add_options = Object::create(global_object, nullptr); auto* years_months_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months, nullptr, date_add));
// d. Let yearsMonthsLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonths, firstAddOptions, dateAdd). // d. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
auto* years_months_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months, first_add_options, date_add));
// e. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0)); auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0));
// f. Let secondAddOptions be OrdinaryObjectCreate(null). // e. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd).
auto* seconds_add_options = Object::create(global_object, nullptr); auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, nullptr, date_add));
// g. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, secondAddOptions, dateAdd). // f. Let weeksInDays be ? DaysUntil(yearsMonthsLater, yearsMonthsWeeksLater).
auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, seconds_add_options, date_add));
// h. Let weeksInDays be ? DaysUntil(yearsMonthsLater, yearsMonthsWeeksLater).
auto weeks_in_days = days_until(global_object, *years_months_later, *years_months_weeks_later); auto weeks_in_days = days_until(global_object, *years_months_later, *years_months_weeks_later);
// i. Set relativeTo to yearsMonthsLater. // g. Set relativeTo to yearsMonthsLater.
relative_to = years_months_later; relative_to = years_months_later;
// j. Let days be days + weeksInDays. // h. Let days be days + weeksInDays.
days += weeks_in_days; days += weeks_in_days;
// k. If days < 0, let sign be 1; else, let sign be 1. // i. If days < 0, let sign be 1; else, let sign be 1.
auto sign = days < 0 ? -1 : 1; auto sign = days < 0 ? -1 : 1;
// l. Let oneMonth be ! CreateTemporalDuration(0, sign, 0, 0, 0, 0, 0, 0, 0, 0). // j. Let oneMonth be ! CreateTemporalDuration(0, sign, 0, 0, 0, 0, 0, 0, 0, 0).
auto* one_month = MUST(create_temporal_duration(global_object, 0, sign, 0, 0, 0, 0, 0, 0, 0, 0)); auto* one_month = MUST(create_temporal_duration(global_object, 0, sign, 0, 0, 0, 0, 0, 0, 0, 0));
// m. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneMonth). // k. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneMonth).
auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_month)); auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_month));
// n. Set relativeTo to moveResult.[[RelativeTo]]. // l. Set relativeTo to moveResult.[[RelativeTo]].
relative_to = move_result.relative_to.cell(); relative_to = move_result.relative_to.cell();
// o. Let oneMonthDays be moveResult.[[Days]]. // m. Let oneMonthDays be moveResult.[[Days]].
auto one_month_days = move_result.days; auto one_month_days = move_result.days;
// p. Repeat, while abs(days) ≥ abs(oneMonthDays), // n. Repeat, while abs(days) ≥ abs(oneMonthDays),
while (fabs(days) >= fabs(one_month_days)) { while (fabs(days) >= fabs(one_month_days)) {
// i. Set months to months + sign. // i. Set months to months + sign.
months += sign; months += sign;
@ -1358,16 +1322,16 @@ ThrowCompletionOr<RoundedDuration> round_duration(GlobalObject& global_object, d
one_month_days = move_result.days; one_month_days = move_result.days;
} }
// q. Let fractionalMonths be months + days / abs(oneMonthDays). // o. Let fractionalMonths be months + days / abs(oneMonthDays).
auto fractional_months = months + days / fabs(one_month_days); auto fractional_months = months + days / fabs(one_month_days);
// r. Set months to ! RoundNumberToIncrement(fractionalMonths, increment, roundingMode). // p. Set months to ! RoundNumberToIncrement(fractionalMonths, increment, roundingMode).
months = (double)round_number_to_increment(fractional_months, increment, rounding_mode); months = (double)round_number_to_increment(fractional_months, increment, rounding_mode);
// s. Set remainder to fractionalMonths - months. // q. Set remainder to fractionalMonths - months.
remainder = fractional_months - months; remainder = fractional_months - months;
// t. Set weeks and days to 0. // r. Set weeks and days to 0.
weeks = 0; weeks = 0;
days = 0; days = 0;
} }

View file

@ -73,11 +73,8 @@ ThrowCompletionOr<PlainDate*> to_temporal_date(GlobalObject& global_object, Valu
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. If options is not present, set options to OrdinaryObjectCreate(null). // 1. If options is not present, set options to undefined.
if (!options) // 2. Assert: Type(options) is Object or Undefined.
options = Object::create(global_object, nullptr);
// 2. Assert: Type(options) is Object.
// 3. If Type(item) is Object, then // 3. If Type(item) is Object, then
if (item.is_object()) { if (item.is_object()) {
@ -123,7 +120,7 @@ ThrowCompletionOr<PlainDate*> to_temporal_date(GlobalObject& global_object, Valu
} }
// 4. Perform ? ToTemporalOverflow(options). // 4. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// 5. Let string be ? ToString(item). // 5. Let string be ? ToString(item).
auto string = TRY(item.to_string(global_object)); auto string = TRY(item.to_string(global_object));

View file

@ -84,7 +84,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateConstructor::from)
if (item.is_object() && is<PlainDate>(item.as_object())) { if (item.is_object() && is<PlainDate>(item.as_object())) {
auto& plain_date_item = static_cast<PlainDate&>(item.as_object()); auto& plain_date_item = static_cast<PlainDate&>(item.as_object());
// a. Perform ? ToTemporalOverflow(options). // a. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// b. Return ? CreateTemporalDate(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[Calendar]]). // b. Return ? CreateTemporalDate(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[Calendar]]).
return TRY(create_temporal_date(global_object, plain_date_item.iso_year(), plain_date_item.iso_month(), plain_date_item.iso_day(), plain_date_item.calendar())); return TRY(create_temporal_date(global_object, plain_date_item.iso_year(), plain_date_item.iso_month(), plain_date_item.iso_day(), plain_date_item.calendar()));

View file

@ -108,7 +108,7 @@ ThrowCompletionOr<ISODateTime> interpret_temporal_date_time_fields(GlobalObject&
auto unregulated_time_result = TRY(to_temporal_time_record(global_object, fields)); auto unregulated_time_result = TRY(to_temporal_time_record(global_object, fields));
// 2. Let overflow be ? ToTemporalOverflow(options). // 2. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(global_object, options)); auto overflow = TRY(to_temporal_overflow(global_object, &options));
// 3. Let temporalDate be ? DateFromFields(calendar, fields, options). // 3. Let temporalDate be ? DateFromFields(calendar, fields, options).
auto* temporal_date = TRY(date_from_fields(global_object, calendar, fields, &options)); auto* temporal_date = TRY(date_from_fields(global_object, calendar, fields, &options));
@ -135,14 +135,13 @@ ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(GlobalObject& global_obj
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. If options is not present, set options to OrdinaryObjectCreate(null). // 1. If options is not present, set options to undefined.
if (!options) // 2. Assert: Type(options) is Object or Undefined.
options = Object::create(global_object, nullptr);
Object* calendar; Object* calendar;
ISODateTime result; ISODateTime result;
// 2. If Type(item) is Object, then // 3. If Type(item) is Object, then
if (item.is_object()) { if (item.is_object()) {
auto& item_object = item.as_object(); auto& item_object = item.as_object();
@ -183,10 +182,10 @@ ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(GlobalObject& global_obj
// g. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options). // g. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options).
result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options)); result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options));
} }
// 3. Else, // 4. Else,
else { else {
// a. Perform ? ToTemporalOverflow(options). // a. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// b. Let string be ? ToString(item). // b. Let string be ? ToString(item).
auto string = TRY(item.to_string(global_object)); auto string = TRY(item.to_string(global_object));
@ -204,7 +203,7 @@ ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(GlobalObject& global_obj
calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, *result.calendar) : js_undefined())); calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, *result.calendar) : js_undefined()));
} }
// 4. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], calendar). // 5. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], calendar).
return create_temporal_date_time(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, *calendar); return create_temporal_date_time(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, *calendar);
} }
@ -353,23 +352,26 @@ ISODateTime round_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute,
// 5.5.11 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime // 5.5.11 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime
ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_object, i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2, Object& calendar, StringView largest_unit, Object* options) ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_object, i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2, Object& calendar, StringView largest_unit, Object* options)
{ {
// 1. If options is not present, set options to OrdinaryObjectCreate(null). // 1. If options is not present, set options to undefined.
// 2. Assert: Type(options) is Object or Undefined.
// FIXME: `options` is being passed to MergeLargestUnitOption unconditionally, which expects it to not be undefined (spec issue: https://github.com/tc39/proposal-temporal/issues/2132).
if (!options) if (!options)
options = Object::create(global_object, nullptr); options = Object::create(global_object, nullptr);
// 2. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2). // 3. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2).
auto time_difference = difference_time(hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2); auto time_difference = difference_time(hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2);
// 3. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]). // 4. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]).
auto time_sign = duration_sign(0, 0, 0, time_difference.days, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, time_difference.nanoseconds); auto time_sign = duration_sign(0, 0, 0, time_difference.days, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, time_difference.nanoseconds);
// 4. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1). // 5. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1).
auto date_sign = compare_iso_date(year2, month2, day2, year1, month1, day1); auto date_sign = compare_iso_date(year2, month2, day2, year1, month1, day1);
// 5. Let adjustedDate be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]). // 6. Let adjustedDate be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]).
auto adjusted_date = balance_iso_date(year1, month1, day1 + time_difference.days); auto adjusted_date = balance_iso_date(year1, month1, day1 + time_difference.days);
// 6. If timeSign is -dateSign, then // 7. If timeSign is -dateSign, then
if (time_sign == -date_sign) { if (time_sign == -date_sign) {
// a. Set adjustedDate to ! BalanceISODate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]] - timeSign). // a. Set adjustedDate to ! BalanceISODate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]] - timeSign).
adjusted_date = balance_iso_date(adjusted_date.year, adjusted_date.month, adjusted_date.day - time_sign); adjusted_date = balance_iso_date(adjusted_date.year, adjusted_date.month, adjusted_date.day - time_sign);
@ -378,25 +380,25 @@ ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_
time_difference = TRY(balance_duration(global_object, -time_sign, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit)); time_difference = TRY(balance_duration(global_object, -time_sign, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit));
} }
// 7. Let date1 be ? CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]], calendar). // 8. Let date1 be ? CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]], calendar).
auto* date1 = TRY(create_temporal_date(global_object, adjusted_date.year, adjusted_date.month, adjusted_date.day, calendar)); auto* date1 = TRY(create_temporal_date(global_object, adjusted_date.year, adjusted_date.month, adjusted_date.day, calendar));
// 8. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar). // 9. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar).
auto* date2 = TRY(create_temporal_date(global_object, year2, month2, day2, calendar)); auto* date2 = TRY(create_temporal_date(global_object, year2, month2, day2, calendar));
// 9. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit). // 10. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit); auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit);
// 10. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit). // 11. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit).
auto* until_options = TRY(merge_largest_unit_option(global_object, *options, date_largest_unit)); auto* until_options = TRY(merge_largest_unit_option(global_object, *options, date_largest_unit));
// 11. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions). // 12. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
auto* date_difference = TRY(calendar_date_until(global_object, calendar, date1, date2, *until_options)); auto* date_difference = TRY(calendar_date_until(global_object, calendar, date1, date2, *until_options));
// 12. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit). // 13. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
auto balance_result = TRY(balance_duration(global_object, date_difference->days(), time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit)); auto balance_result = TRY(balance_duration(global_object, date_difference->days(), time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit));
// 13. Return ! CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]]). // 14. Return ! CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]]).
return create_duration_record(date_difference->years(), date_difference->months(), date_difference->weeks(), balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds); return create_duration_record(date_difference->years(), date_difference->months(), date_difference->weeks(), balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -105,7 +105,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimeConstructor::from)
auto& plain_date_time = static_cast<PlainDateTime&>(item.as_object()); auto& plain_date_time = static_cast<PlainDateTime&>(item.as_object());
// a. Perform ? ToTemporalOverflow(options). // a. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// b. Return ? CreateTemporalDateTime(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[ISOHour]], item.[[ISOMinute]], item.[[ISOSecond]], item.[[ISOMillisecond]], item.[[ISOMicrosecond]], item.[[ISONanosecond]], item.[[Calendar]]). // b. Return ? CreateTemporalDateTime(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[ISOHour]], item.[[ISOMinute]], item.[[ISOSecond]], item.[[ISOMillisecond]], item.[[ISOMicrosecond]], item.[[ISONanosecond]], item.[[Calendar]]).
return TRY(create_temporal_date_time(global_object, plain_date_time.iso_year(), plain_date_time.iso_month(), plain_date_time.iso_day(), plain_date_time.iso_hour(), plain_date_time.iso_minute(), plain_date_time.iso_second(), plain_date_time.iso_millisecond(), plain_date_time.iso_microsecond(), plain_date_time.iso_nanosecond(), plain_date_time.calendar())); return TRY(create_temporal_date_time(global_object, plain_date_time.iso_year(), plain_date_time.iso_month(), plain_date_time.iso_day(), plain_date_time.iso_hour(), plain_date_time.iso_minute(), plain_date_time.iso_second(), plain_date_time.iso_millisecond(), plain_date_time.iso_microsecond(), plain_date_time.iso_nanosecond(), plain_date_time.calendar()));

View file

@ -766,7 +766,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_zoned_date_time)
auto* options = TRY(get_options_object(global_object, vm.argument(1))); auto* options = TRY(get_options_object(global_object, vm.argument(1)));
// 5. Let disambiguation be ? ToTemporalDisambiguation(options). // 5. Let disambiguation be ? ToTemporalDisambiguation(options).
auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
// 6. Let instant be ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation). // 6. Let instant be ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation).
auto* instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation)); auto* instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation));

View file

@ -38,14 +38,13 @@ ThrowCompletionOr<PlainMonthDay*> to_temporal_month_day(GlobalObject& global_obj
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. If options is not present, set options to OrdinaryObjectCreate(null). // 1. If options is not present, set options to undefined.
if (!options) // 2. Assert: Type(options) is Object or Undefined.
options = Object::create(global_object, nullptr);
// 2. Let referenceISOYear be 1972 (the first leap year after the Unix epoch). // 3. Let referenceISOYear be 1972 (the first leap year after the Unix epoch).
i32 reference_iso_year = 1972; i32 reference_iso_year = 1972;
// 3. If Type(item) is Object, then // 4. If Type(item) is Object, then
if (item.is_object()) { if (item.is_object()) {
auto& item_object = item.as_object(); auto& item_object = item.as_object();
@ -118,32 +117,30 @@ ThrowCompletionOr<PlainMonthDay*> to_temporal_month_day(GlobalObject& global_obj
return month_day_from_fields(global_object, *calendar, *fields, options); return month_day_from_fields(global_object, *calendar, *fields, options);
} }
// 4. Perform ? ToTemporalOverflow(options). // 5. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// 5. Let string be ? ToString(item). // 6. Let string be ? ToString(item).
auto string = TRY(item.to_string(global_object)); auto string = TRY(item.to_string(global_object));
// 6. Let result be ? ParseTemporalMonthDayString(string). // 7. Let result be ? ParseTemporalMonthDayString(string).
auto result = TRY(parse_temporal_month_day_string(global_object, string)); auto result = TRY(parse_temporal_month_day_string(global_object, string));
// 7. Let calendar be ? ToTemporalCalendarWithISODefault(result.[[Calendar]]). // 8. Let calendar be ? ToTemporalCalendarWithISODefault(result.[[Calendar]]).
auto* calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, move(*result.calendar)) : js_undefined())); auto* calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, move(*result.calendar)) : js_undefined()));
// 8. If result.[[Year]] is undefined, then // 9. If result.[[Year]] is undefined, then
if (!result.year.has_value()) { if (!result.year.has_value()) {
// a. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear). // a. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear).
return TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year)); return TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year));
} }
// 9. Set result to ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear). // 10. Set result to ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear).
auto* plain_month_day = TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year)); auto* plain_month_day = TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year));
// 10. Let canonicalMonthDayOptions be OrdinaryObjectCreate(null). // 11. NOTE: The following operation is called without options, in order for the calendar to store a canonical value in the [[ISOYear]] internal slot of the result.
auto* canonical_month_day_options = Object::create(global_object, nullptr); // 12. Return ? MonthDayFromFields(calendar, result).
return TRY(month_day_from_fields(global_object, *calendar, *plain_month_day));
// 11. Return ? MonthDayFromFields(calendar, result, canonicalMonthDayOptions).
return TRY(month_day_from_fields(global_object, *calendar, *plain_month_day, canonical_month_day_options));
} }
// 10.5.2 CreateTemporalMonthDay ( isoMonth, isoDay, calendar, referenceISOYear [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporalmonthday // 10.5.2 CreateTemporalMonthDay ( isoMonth, isoDay, calendar, referenceISOYear [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporalmonthday

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -93,7 +93,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainMonthDayConstructor::from)
// 2. If Type(item) is Object and item has an [[InitializedTemporalMonthDay]] internal slot, then // 2. If Type(item) is Object and item has an [[InitializedTemporalMonthDay]] internal slot, then
if (item.is_object() && is<PlainMonthDay>(item.as_object())) { if (item.is_object() && is<PlainMonthDay>(item.as_object())) {
// a. Perform ? ToTemporalOverflow(options). // a. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
auto& plain_month_day_object = static_cast<PlainMonthDay&>(item.as_object()); auto& plain_month_day_object = static_cast<PlainMonthDay&>(item.as_object());

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -85,7 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimeConstructor::from)
auto* options = TRY(get_options_object(global_object, vm.argument(1))); auto* options = TRY(get_options_object(global_object, vm.argument(1)));
// 2. Let overflow be ? ToTemporalOverflow(options). // 2. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(global_object, *options)); auto overflow = TRY(to_temporal_overflow(global_object, options));
auto item = vm.argument(0); auto item = vm.argument(0);

View file

@ -207,7 +207,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::with)
auto* options = TRY(get_options_object(global_object, vm.argument(1))); auto* options = TRY(get_options_object(global_object, vm.argument(1)));
// 7. Let overflow be ? ToTemporalOverflow(options). // 7. Let overflow be ? ToTemporalOverflow(options).
auto overflow = TRY(to_temporal_overflow(global_object, *options)); auto overflow = TRY(to_temporal_overflow(global_object, options));
// 8. If partialTime.[[Hour]] is not undefined, then // 8. If partialTime.[[Hour]] is not undefined, then
// a. Let hour be partialTime.[[Hour]]. // a. Let hour be partialTime.[[Hour]].

View file

@ -35,11 +35,8 @@ ThrowCompletionOr<PlainYearMonth*> to_temporal_year_month(GlobalObject& global_o
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. If options is not present, set options to OrdinaryObjectCreate(null). // 1. If options is not present, set options to undefined.
if (!options) // 2. Assert: Type(options) is Object or Undefined.
options = Object::create(global_object, nullptr);
// 2. Assert: Type(options) is Object.
// 3. If Type(item) is Object, then // 3. If Type(item) is Object, then
if (item.is_object()) { if (item.is_object()) {
@ -65,7 +62,7 @@ ThrowCompletionOr<PlainYearMonth*> to_temporal_year_month(GlobalObject& global_o
} }
// 4. Perform ? ToTemporalOverflow(options). // 4. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// 5. Let string be ? ToString(item). // 5. Let string be ? ToString(item).
auto string = TRY(item.to_string(global_object)); auto string = TRY(item.to_string(global_object));
@ -79,11 +76,9 @@ ThrowCompletionOr<PlainYearMonth*> to_temporal_year_month(GlobalObject& global_o
// 8. Set result to ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[Day]]). // 8. Set result to ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[Day]]).
auto* creation_result = TRY(create_temporal_year_month(global_object, result.year, result.month, *calendar, result.day)); auto* creation_result = TRY(create_temporal_year_month(global_object, result.year, result.month, *calendar, result.day));
// 9. Let canonicalYearMonthOptions be OrdinaryObjectCreate(null). // 9. NOTE: The following operation is called without options, in order for the calendar to store a canonical value in the [[ISODay]] internal slot of the result.
auto* canonical_year_month_options = Object::create(global_object, nullptr); // 10. Return ? YearMonthFromFields(calendar, result).
return year_month_from_fields(global_object, *calendar, *creation_result);
// 10. Return ? YearMonthFromFields(calendar, result, canonicalYearMonthOptions).
return year_month_from_fields(global_object, *calendar, *creation_result, canonical_year_month_options);
} }
// 9.5.2 RegulateISOYearMonth ( year, month, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-regulateisoyearmonth // 9.5.2 RegulateISOYearMonth ( year, month, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-regulateisoyearmonth

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org> * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -95,7 +95,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainYearMonthConstructor::from)
// 2. If Type(item) is Object and item has an [[InitializedTemporalYearMonth]] internal slot, then // 2. If Type(item) is Object and item has an [[InitializedTemporalYearMonth]] internal slot, then
if (item.is_object() && is<PlainYearMonth>(item.as_object())) { if (item.is_object() && is<PlainYearMonth>(item.as_object())) {
// a. Perform ? ToTemporalOverflow(options). // a. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
auto& plain_year_month_object = static_cast<PlainYearMonth&>(item.as_object()); auto& plain_year_month_object = static_cast<PlainYearMonth&>(item.as_object());

View file

@ -119,7 +119,7 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::get_instant_for)
auto* options = TRY(get_options_object(global_object, vm.argument(1))); auto* options = TRY(get_options_object(global_object, vm.argument(1)));
// 5. Let disambiguation be ? ToTemporalDisambiguation(options). // 5. Let disambiguation be ? ToTemporalDisambiguation(options).
auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
// 6. Return ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation). // 6. Return ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation).
return TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation)); return TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation));

View file

@ -118,14 +118,13 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. If options is not present, set options to OrdinaryObjectCreate(null). // 1. If options is not present, set options to undefined.
if (!options) // 2. Assert: Type(options) is Object or Undefined.
options = Object::create(global_object, nullptr);
// 2. Let offsetBehaviour be option. // 3. Let offsetBehaviour be option.
auto offset_behavior = OffsetBehavior::Option; auto offset_behavior = OffsetBehavior::Option;
// 3. Let matchBehaviour be match exactly. // 4. Let matchBehaviour be match exactly.
auto match_behavior = MatchBehavior::MatchExactly; auto match_behavior = MatchBehavior::MatchExactly;
Object* calendar = nullptr; Object* calendar = nullptr;
@ -133,7 +132,7 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
Optional<String> offset_string; Optional<String> offset_string;
ISODateTime result; ISODateTime result;
// 4. If Type(item) is Object, then // 5. If Type(item) is Object, then
if (item.is_object()) { if (item.is_object()) {
auto& item_object = item.as_object(); auto& item_object = item.as_object();
@ -181,10 +180,10 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
// l. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options). // l. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options).
result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options)); result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options));
} }
// 5. Else, // 6. Else,
else { else {
// a. Perform ? ToTemporalOverflow(options). // a. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// b. Let string be ? ToString(item). // b. Let string be ? ToString(item).
auto string = TRY(item.to_string(global_object)); auto string = TRY(item.to_string(global_object));
@ -241,25 +240,25 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
result = move(parsed_result.date_time); result = move(parsed_result.date_time);
} }
// 6. Let offsetNanoseconds be 0. // 7. Let offsetNanoseconds be 0.
double offset_nanoseconds = 0; double offset_nanoseconds = 0;
// 7. If offsetBehaviour is option, then // 8. If offsetBehaviour is option, then
if (offset_behavior == OffsetBehavior::Option) { if (offset_behavior == OffsetBehavior::Option) {
// a. Set offsetNanoseconds to ? ParseTimeZoneOffsetString(offsetString). // a. Set offsetNanoseconds to ? ParseTimeZoneOffsetString(offsetString).
offset_nanoseconds = TRY(parse_time_zone_offset_string(global_object, *offset_string)); offset_nanoseconds = TRY(parse_time_zone_offset_string(global_object, *offset_string));
} }
// 8. Let disambiguation be ? ToTemporalDisambiguation(options). // 9. Let disambiguation be ? ToTemporalDisambiguation(options).
auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
// 9. Let offsetOption be ? ToTemporalOffset(options, "reject"). // 10. Let offsetOption be ? ToTemporalOffset(options, "reject").
auto offset_option = TRY(to_temporal_offset(global_object, *options, "reject")); auto offset_option = TRY(to_temporal_offset(global_object, options, "reject"));
// 10. Let epochNanoseconds be ? InterpretISODateTimeOffset(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour). // 11. Let epochNanoseconds be ? InterpretISODateTimeOffset(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour).
auto* epoch_nanoseconds = TRY(interpret_iso_date_time_offset(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, offset_behavior, offset_nanoseconds, time_zone, disambiguation, offset_option, match_behavior)); auto* epoch_nanoseconds = TRY(interpret_iso_date_time_offset(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, offset_behavior, offset_nanoseconds, time_zone, disambiguation, offset_option, match_behavior));
// 11. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). // 12. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar).
return MUST(create_temporal_zoned_date_time(global_object, *epoch_nanoseconds, *time_zone, *calendar)); return MUST(create_temporal_zoned_date_time(global_object, *epoch_nanoseconds, *time_zone, *calendar));
} }
@ -367,38 +366,37 @@ ThrowCompletionOr<String> temporal_zoned_date_time_to_string(GlobalObject& globa
// 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 // 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) 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)
{ {
// 1. If options is not present, set options to OrdinaryObjectCreate(null). // 1. If options is not present, set options to undefined.
if (!options) // 2. Assert: Type(options) is Object or Undefined.
options = Object::create(global_object, nullptr);
// 2. If all of years, months, weeks, and days are 0, then // 3. If all of years, months, weeks, and days are 0, then
if (years == 0 && months == 0 && weeks == 0 && days == 0) { if (years == 0 && months == 0 && weeks == 0 && days == 0) {
// a. Return ! AddInstant(epochNanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds). // a. Return ! AddInstant(epochNanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
return MUST(add_instant(global_object, epoch_nanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds)); return MUST(add_instant(global_object, epoch_nanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
} }
// 3. Let instant be ! CreateTemporalInstant(epochNanoseconds). // 4. Let instant be ! CreateTemporalInstant(epochNanoseconds).
auto* instant = MUST(create_temporal_instant(global_object, epoch_nanoseconds)); auto* instant = MUST(create_temporal_instant(global_object, epoch_nanoseconds));
// 4. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar). // 5. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar).
auto* temporal_date_time = TRY(builtin_time_zone_get_plain_date_time_for(global_object, time_zone, *instant, calendar)); auto* temporal_date_time = TRY(builtin_time_zone_get_plain_date_time_for(global_object, time_zone, *instant, calendar));
// 5. Let datePart be ? CreateTemporalDate(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], calendar). // 6. Let datePart be ? CreateTemporalDate(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], calendar).
auto* date_part = TRY(create_temporal_date(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), calendar)); auto* date_part = TRY(create_temporal_date(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), calendar));
// 6. Let dateDuration be ! CreateTemporalDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0). // 7. Let dateDuration be ! CreateTemporalDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0).
auto* date_duration = MUST(create_temporal_duration(global_object, years, months, weeks, days, 0, 0, 0, 0, 0, 0)); auto* date_duration = MUST(create_temporal_duration(global_object, years, months, weeks, days, 0, 0, 0, 0, 0, 0));
// 7. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options). // 8. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options).
auto* added_date = TRY(calendar_date_add(global_object, calendar, date_part, *date_duration, options)); auto* added_date = TRY(calendar_date_add(global_object, calendar, date_part, *date_duration, options));
// 8. Let intermediateDateTime be ? CreateTemporalDateTime(addedDate.[[ISOYear]], addedDate.[[ISOMonth]], addedDate.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], calendar). // 9. Let intermediateDateTime be ? CreateTemporalDateTime(addedDate.[[ISOYear]], addedDate.[[ISOMonth]], addedDate.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], calendar).
auto* intermediate_date_time = TRY(create_temporal_date_time(global_object, added_date->iso_year(), added_date->iso_month(), added_date->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(), calendar)); auto* intermediate_date_time = TRY(create_temporal_date_time(global_object, added_date->iso_year(), added_date->iso_month(), added_date->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(), calendar));
// 9. Let intermediateInstant be ? BuiltinTimeZoneGetInstantFor(timeZone, intermediateDateTime, "compatible"). // 10. Let intermediateInstant be ? BuiltinTimeZoneGetInstantFor(timeZone, intermediateDateTime, "compatible").
auto* intermediate_instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *intermediate_date_time, "compatible"sv)); auto* intermediate_instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *intermediate_date_time, "compatible"sv));
// 10. Return ! AddInstant(intermediateInstant.[[Nanoseconds]], hours, minutes, seconds, milliseconds, microseconds, nanoseconds). // 11. Return ! AddInstant(intermediateInstant.[[Nanoseconds]], hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
return MUST(add_instant(global_object, intermediate_instant->nanoseconds(), hours, minutes, seconds, milliseconds, microseconds, nanoseconds)); return MUST(add_instant(global_object, intermediate_instant->nanoseconds(), hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org> * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -83,13 +83,13 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimeConstructor::from)
auto& item_object = static_cast<ZonedDateTime&>(item.as_object()); auto& item_object = static_cast<ZonedDateTime&>(item.as_object());
// a. Perform ? ToTemporalOverflow(options). // a. Perform ? ToTemporalOverflow(options).
(void)TRY(to_temporal_overflow(global_object, *options)); (void)TRY(to_temporal_overflow(global_object, options));
// b. Perform ? ToTemporalDisambiguation(options). // b. Perform ? ToTemporalDisambiguation(options).
(void)TRY(to_temporal_disambiguation(global_object, *options)); (void)TRY(to_temporal_disambiguation(global_object, options));
// c. Perform ? ToTemporalOffset(options, "reject"). // c. Perform ? ToTemporalOffset(options, "reject").
(void)TRY(to_temporal_offset(global_object, *options, "reject")); (void)TRY(to_temporal_offset(global_object, options, "reject"));
// d. Return ! CreateTemporalZonedDateTime(item.[[Nanoseconds]], item.[[TimeZone]], item.[[Calendar]]). // d. Return ! CreateTemporalZonedDateTime(item.[[Nanoseconds]], item.[[TimeZone]], item.[[Calendar]]).
return MUST(create_temporal_zoned_date_time(global_object, item_object.nanoseconds(), item_object.time_zone(), item_object.calendar())); return MUST(create_temporal_zoned_date_time(global_object, item_object.nanoseconds(), item_object.time_zone(), item_object.calendar()));

View file

@ -751,10 +751,10 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with)
auto* options = TRY(get_options_object(global_object, vm.argument(1))); auto* options = TRY(get_options_object(global_object, vm.argument(1)));
// 10. Let disambiguation be ? ToTemporalDisambiguation(options). // 10. Let disambiguation be ? ToTemporalDisambiguation(options).
auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options)); auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
// 11. Let offset be ? ToTemporalOffset(options, "prefer"). // 11. Let offset be ? ToTemporalOffset(options, "prefer").
auto offset = TRY(to_temporal_offset(global_object, *options, "prefer"sv)); auto offset = TRY(to_temporal_offset(global_object, options, "prefer"sv));
// 12. Let timeZone be zonedDateTime.[[TimeZone]]. // 12. Let timeZone be zonedDateTime.[[TimeZone]].
auto& time_zone = zoned_date_time->time_zone(); auto& time_zone = zoned_date_time->time_zone();