mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-08 20:32:56 +03:00
LibJS: Simplify Temporal unit AOs
This is an editorial change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/1b3d018
This commit is contained in:
parent
b9beb2b120
commit
4c77575ec5
Notes:
sideshowbarker
2024-07-17 10:21:14 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/4c77575ec5 Pull-request: https://github.com/SerenityOS/serenity/pull/14233 Reviewed-by: https://github.com/Hendiadyoin1
@ -389,8 +389,12 @@ ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObje
|
|||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
|
||||||
// Let smallestUnit be ? ToSmallestTemporalUnit(normalizedOptions, « "year", "month", "week", "day", "hour" », undefined).
|
// 1. Let smallestUnit be ? GetTemporalUnit(normalizedOptions, "smallestUnit", time, undefined).
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, normalized_options, { "year"sv, "month"sv, "week"sv, "day"sv, "hour"sv }, {}));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, normalized_options, vm.names.smallestUnit, UnitGroup::Time, Optional<StringView> {}));
|
||||||
|
|
||||||
|
// 2. If smallestUnit is "hour", throw a RangeError exception.
|
||||||
|
if (smallest_unit == "hour"sv)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, *smallest_unit, "smallestUnit"sv);
|
||||||
|
|
||||||
// 2. If smallestUnit is "minute", then
|
// 2. If smallestUnit is "minute", then
|
||||||
if (smallest_unit == "minute"sv) {
|
if (smallest_unit == "minute"sv) {
|
||||||
@ -462,121 +466,117 @@ ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObje
|
|||||||
return SecondsStringPrecision { .precision = digits, .unit = "nanosecond"sv, .increment = (u32)pow(10, 9 - digits) };
|
return SecondsStringPrecision { .precision = digits, .unit = "nanosecond"sv, .increment = (u32)pow(10, 9 - digits) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tc39.es/proposal-temporal/#table-temporal-singular-and-plural-units
|
struct TemporalUnit {
|
||||||
static HashMap<StringView, StringView> plural_to_singular_units = {
|
StringView singular;
|
||||||
{ "years"sv, "year"sv },
|
StringView plural;
|
||||||
{ "months"sv, "month"sv },
|
UnitGroup category;
|
||||||
{ "weeks"sv, "week"sv },
|
|
||||||
{ "days"sv, "day"sv },
|
|
||||||
{ "hours"sv, "hour"sv },
|
|
||||||
{ "minutes"sv, "minute"sv },
|
|
||||||
{ "seconds"sv, "second"sv },
|
|
||||||
{ "milliseconds"sv, "millisecond"sv },
|
|
||||||
{ "microseconds"sv, "microsecond"sv },
|
|
||||||
{ "nanoseconds"sv, "nanosecond"sv }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 13.16 ToLargestTemporalUnit ( normalizedOptions, disallowedUnits, fallback [ , autoValue ] ), https://tc39.es/proposal-temporal/#sec-temporal-tolargesttemporalunit
|
// https://tc39.es/proposal-temporal/#table-temporal-units
|
||||||
ThrowCompletionOr<Optional<String>> to_largest_temporal_unit(GlobalObject& global_object, Object const& normalized_options, Vector<StringView> const& disallowed_units, Optional<String> fallback, Optional<String> auto_value)
|
static Vector<TemporalUnit> temporal_units = {
|
||||||
|
{ "year"sv, "years"sv, UnitGroup::Date },
|
||||||
|
{ "month"sv, "months"sv, UnitGroup::Date },
|
||||||
|
{ "week"sv, "weeks"sv, UnitGroup::Date },
|
||||||
|
{ "day"sv, "days"sv, UnitGroup::Date },
|
||||||
|
{ "hour"sv, "hours"sv, UnitGroup::Time },
|
||||||
|
{ "minute"sv, "minutes"sv, UnitGroup::Time },
|
||||||
|
{ "second"sv, "seconds"sv, UnitGroup::Time },
|
||||||
|
{ "millisecond"sv, "milliseconds"sv, UnitGroup::Time },
|
||||||
|
{ "microsecond"sv, "microseconds"sv, UnitGroup::Time },
|
||||||
|
{ "nanosecond"sv, "nanoseconds"sv, UnitGroup::Time }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 13.16 GetTemporalUnit ( normalizedOptions, key, unitGroup, default [ , extraValues ] ), https://tc39.es/proposal-temporal/#sec-temporal-gettemporalunit
|
||||||
|
ThrowCompletionOr<Optional<String>> get_temporal_unit(GlobalObject& global_object, Object const& normalized_options, PropertyKey const& key, UnitGroup unit_group, Variant<TemporalUnitRequired, Optional<StringView>> const& default_, Vector<StringView> const& extra_values)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
|
||||||
// 1. Assert: disallowedUnits does not contain fallback.
|
// 1. Let singularNames be a new empty List.
|
||||||
// 2. Assert: disallowedUnits does not contain "auto".
|
Vector<StringView> singular_names;
|
||||||
// 3. Assert: autoValue is not present or fallback is "auto".
|
|
||||||
VERIFY(!auto_value.has_value() || fallback == "auto"sv);
|
|
||||||
// 4. Assert: autoValue is not present or disallowedUnits does not contain autoValue.
|
|
||||||
|
|
||||||
// 5. Let largestUnit be ? GetOption(normalizedOptions, "largestUnit", « String », « "auto", "year", "years", "month", "months", "week", "weeks", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds", "millisecond", "milliseconds", "microsecond", "microseconds", "nanosecond", "nanoseconds" », fallback).
|
// 2. For each row of Table 13, except the header row, in table order, do
|
||||||
auto largest_unit_value = TRY(get_option(global_object, normalized_options, vm.names.largestUnit, { OptionType::String }, { "auto"sv, "year"sv, "years"sv, "month"sv, "months"sv, "week"sv, "weeks"sv, "day"sv, "days"sv, "hour"sv, "hours"sv, "minute"sv, "minutes"sv, "second"sv, "seconds"sv, "millisecond"sv, "milliseconds"sv, "microsecond"sv, "microseconds"sv, "nanosecond"sv, "nanoseconds"sv }, fallback.has_value() ? js_string(vm, *fallback) : js_undefined()));
|
for (auto const& row : temporal_units) {
|
||||||
|
// a. Let unit be the value in the Singular column of the row.
|
||||||
|
auto unit = row.singular;
|
||||||
|
|
||||||
// OPTIMIZATION: We skip the following string-only checks for the fallback to tidy up the code a bit
|
// b. If the Category column of the row is date and unitGroup is date or datetime, append unit to singularNames.
|
||||||
if (largest_unit_value.is_undefined())
|
if (row.category == UnitGroup::Date && (unit_group == UnitGroup::Date || unit_group == UnitGroup::DateTime))
|
||||||
return Optional<String> {};
|
singular_names.append(unit);
|
||||||
VERIFY(largest_unit_value.is_string());
|
// c. Else if the Category column of the row is time and unitGroup is time or datetime, append unit to singularNames.
|
||||||
auto largest_unit = largest_unit_value.as_string().string();
|
else if (row.category == UnitGroup::Time && (unit_group == UnitGroup::Time || unit_group == UnitGroup::DateTime))
|
||||||
|
singular_names.append(unit);
|
||||||
// 6. If largestUnit is "auto" and autoValue is present, then
|
|
||||||
if (largest_unit == "auto"sv && auto_value.has_value()) {
|
|
||||||
// a. Return autoValue.
|
|
||||||
return *auto_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. If largestUnit is in the Plural column of Table 12, then
|
// 3. If extraValues is present, then
|
||||||
if (auto singular_unit = plural_to_singular_units.get(largest_unit); singular_unit.has_value()) {
|
if (!extra_values.is_empty()) {
|
||||||
// a. Set largestUnit to the corresponding Singular value of the same row.
|
// a. Set singularNames to the list-concatenation of singularNames and extraValues.
|
||||||
largest_unit = singular_unit.value();
|
singular_names.extend(extra_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. If disallowedUnits contains largestUnit, then
|
Value default_value;
|
||||||
if (disallowed_units.contains_slow(largest_unit)) {
|
|
||||||
// a. Throw a RangeError exception.
|
// 4. If default is required, then
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, largest_unit, vm.names.largestUnit.as_string());
|
if (default_.has<TemporalUnitRequired>()) {
|
||||||
|
// a. Let defaultValue be undefined.
|
||||||
|
default_value = js_undefined();
|
||||||
|
}
|
||||||
|
// 5. Else,
|
||||||
|
else {
|
||||||
|
auto default_string = default_.get<Optional<StringView>>();
|
||||||
|
|
||||||
|
// a. Let defaultValue be default.
|
||||||
|
default_value = default_string.has_value() ? js_string(vm, *default_string) : js_undefined();
|
||||||
|
|
||||||
|
// b. If defaultValue is not undefined and singularNames does not contain defaultValue, then
|
||||||
|
if (default_string.has_value() && !singular_names.contains_slow(*default_string)) {
|
||||||
|
// i. Append defaultValue to singularNames.
|
||||||
|
singular_names.append(*default_string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Return largestUnit.
|
// 6. Let allowedValues be a copy of singularNames.
|
||||||
return largest_unit;
|
auto allowed_values = singular_names;
|
||||||
|
|
||||||
|
// 7. For each element singularName of singularNames, do
|
||||||
|
for (auto const& singular_name : singular_names) {
|
||||||
|
for (auto const& row : temporal_units) {
|
||||||
|
// a. If singularName is listed in the Singular column of Table 13, then
|
||||||
|
if (singular_name == row.singular) {
|
||||||
|
// i. Let pluralName be the value in the Plural column of the corresponding row.
|
||||||
|
auto plural_name = row.plural;
|
||||||
|
|
||||||
|
// ii. Append pluralName to allowedValues.
|
||||||
|
allowed_values.append(plural_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. NOTE: For each singular Temporal unit name that is contained within allowedValues, the corresponding plural name is also contained within it.
|
||||||
|
|
||||||
|
// 9. Let value be ? GetOption(normalizedOptions, key, « String », allowedValues, defaultValue).
|
||||||
|
auto option_value = TRY(get_option(global_object, normalized_options, key, { OptionType::String }, allowed_values, default_value));
|
||||||
|
|
||||||
|
// 10. If value is undefined and default is required, throw a RangeError exception.
|
||||||
|
if (option_value.is_undefined() && default_.has<TemporalUnitRequired>())
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::IsUndefined, String::formatted("{} option value", key.as_string()));
|
||||||
|
|
||||||
|
Optional<String> value = option_value.is_undefined()
|
||||||
|
? Optional<String> {}
|
||||||
|
: option_value.as_string().string();
|
||||||
|
|
||||||
|
// 11. If value is listed in the Plural column of Table 13, then
|
||||||
|
for (auto const& row : temporal_units) {
|
||||||
|
if (row.plural == value) {
|
||||||
|
// a. Set value to the value in the Singular column of the corresponding row.
|
||||||
|
value = row.singular;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12. Return value.
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.17 ToSmallestTemporalUnit ( normalizedOptions, disallowedUnits, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-tosmallesttemporalunit
|
// 13.17 ToRelativeTemporalObject ( options ), https://tc39.es/proposal-temporal/#sec-temporal-torelativetemporalobject
|
||||||
ThrowCompletionOr<Optional<String>> to_smallest_temporal_unit(GlobalObject& global_object, Object const& normalized_options, Vector<StringView> const& disallowed_units, Optional<String> fallback)
|
|
||||||
{
|
|
||||||
auto& vm = global_object.vm();
|
|
||||||
|
|
||||||
// 1. Assert: disallowedUnits does not contain fallback.
|
|
||||||
|
|
||||||
// 2. Let smallestUnit be ? GetOption(normalizedOptions, "smallestUnit", « String », « "year", "years", "month", "months", "week", "weeks", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds", "millisecond", "milliseconds", "microsecond", "microseconds", "nanosecond", "nanoseconds" », fallback).
|
|
||||||
auto smallest_unit_value = TRY(get_option(global_object, normalized_options, vm.names.smallestUnit, { OptionType::String }, { "year"sv, "years"sv, "month"sv, "months"sv, "week"sv, "weeks"sv, "day"sv, "days"sv, "hour"sv, "hours"sv, "minute"sv, "minutes"sv, "second"sv, "seconds"sv, "millisecond"sv, "milliseconds"sv, "microsecond"sv, "microseconds"sv, "nanosecond"sv, "nanoseconds"sv }, fallback.has_value() ? js_string(vm, *fallback) : js_undefined()));
|
|
||||||
|
|
||||||
// OPTIMIZATION: We skip the following string-only checks for the fallback to tidy up the code a bit
|
|
||||||
if (smallest_unit_value.is_undefined())
|
|
||||||
return Optional<String> {};
|
|
||||||
VERIFY(smallest_unit_value.is_string());
|
|
||||||
auto smallest_unit = smallest_unit_value.as_string().string();
|
|
||||||
|
|
||||||
// 3. If smallestUnit is in the Plural column of Table 12, then
|
|
||||||
if (auto singular_unit = plural_to_singular_units.get(smallest_unit); singular_unit.has_value()) {
|
|
||||||
// a. Set smallestUnit to the corresponding Singular value of the same row.
|
|
||||||
smallest_unit = singular_unit.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. If disallowedUnits contains smallestUnit, then
|
|
||||||
if (disallowed_units.contains_slow(smallest_unit)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, smallest_unit, vm.names.smallestUnit.as_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Return smallestUnit.
|
|
||||||
return smallest_unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 13.18 ToTemporalDurationTotalUnit ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldurationtotalunit
|
|
||||||
ThrowCompletionOr<String> to_temporal_duration_total_unit(GlobalObject& global_object, Object const& normalized_options)
|
|
||||||
{
|
|
||||||
auto& vm = global_object.vm();
|
|
||||||
|
|
||||||
// 1. Let unit be ? GetOption(normalizedOptions, "unit", « String », « "year", "years", "month", "months", "week", "weeks", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds", "millisecond", "milliseconds", "microsecond", "microseconds", "nanosecond", "nanoseconds" », undefined).
|
|
||||||
auto unit_value = TRY(get_option(global_object, normalized_options, vm.names.unit, { OptionType::String }, { "year"sv, "years"sv, "month"sv, "months"sv, "week"sv, "weeks"sv, "day"sv, "days"sv, "hour"sv, "hours"sv, "minute"sv, "minutes"sv, "second"sv, "seconds"sv, "millisecond"sv, "milliseconds"sv, "microsecond"sv, "microseconds"sv, "nanosecond"sv, "nanoseconds"sv }, js_undefined()));
|
|
||||||
|
|
||||||
// 2. If unit is undefined, then
|
|
||||||
if (unit_value.is_undefined()) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IsUndefined, "unit option value"sv);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto unit = unit_value.as_string().string();
|
|
||||||
|
|
||||||
// 3. If unit is in the Plural column of Table 12, then
|
|
||||||
if (auto singular_unit = plural_to_singular_units.get(unit); singular_unit.has_value()) {
|
|
||||||
// a. Set unit to the corresponding Singular value of the same row.
|
|
||||||
unit = *singular_unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Return unit.
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 13.20 ToRelativeTemporalObject ( options ), https://tc39.es/proposal-temporal/#sec-temporal-torelativetemporalobject
|
|
||||||
ThrowCompletionOr<Value> to_relative_temporal_object(GlobalObject& global_object, Object const& options)
|
ThrowCompletionOr<Value> to_relative_temporal_object(GlobalObject& global_object, Object const& options)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -746,95 +746,28 @@ ThrowCompletionOr<Value> to_relative_temporal_object(GlobalObject& global_object
|
|||||||
return TRY(create_temporal_date(global_object, result.year, result.month, result.day, *calendar));
|
return TRY(create_temporal_date(global_object, result.year, result.month, result.day, *calendar));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.21 ValidateTemporalUnitRange ( largestUnit, smallestUnit ), https://tc39.es/proposal-temporal/#sec-temporal-validatetemporalunitrange
|
// 13.18 LargerOfTwoTemporalUnits ( u1, u2 ), https://tc39.es/proposal-temporal/#sec-temporal-largeroftwotemporalunits
|
||||||
ThrowCompletionOr<void> validate_temporal_unit_range(GlobalObject& global_object, StringView largest_unit, StringView smallest_unit)
|
|
||||||
{
|
|
||||||
auto& vm = global_object.vm();
|
|
||||||
|
|
||||||
// 1. If smallestUnit is "year" and largestUnit is not "year", then
|
|
||||||
if (smallest_unit == "year"sv && largest_unit != "year"sv) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 2. If smallestUnit is "month" and largestUnit is not "year" or "month", then
|
|
||||||
if (smallest_unit == "month"sv && !largest_unit.is_one_of("year"sv, "month"sv)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 3. If smallestUnit is "week" and largestUnit is not one of "year", "month", or "week", then
|
|
||||||
if (smallest_unit == "week"sv && !largest_unit.is_one_of("year"sv, "month"sv, "week"sv)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 4. If smallestUnit is "day" and largestUnit is not one of "year", "month", "week", or "day", then
|
|
||||||
if (smallest_unit == "day"sv && !largest_unit.is_one_of("year"sv, "month"sv, "week"sv, "day"sv)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 5. If smallestUnit is "hour" and largestUnit is not one of "year", "month", "week", "day", or "hour", then
|
|
||||||
if (smallest_unit == "hour"sv && !largest_unit.is_one_of("year"sv, "month"sv, "week"sv, "day"sv, "hour"sv)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 6. If smallestUnit is "minute" and largestUnit is "second", "millisecond", "microsecond", or "nanosecond", then
|
|
||||||
if (smallest_unit == "minute"sv && largest_unit.is_one_of("second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 7. If smallestUnit is "second" and largestUnit is "millisecond", "microsecond", or "nanosecond", then
|
|
||||||
if (smallest_unit == "second"sv && largest_unit.is_one_of("millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 8. If smallestUnit is "millisecond" and largestUnit is "microsecond" or "nanosecond", then
|
|
||||||
if (smallest_unit == "millisecond"sv && largest_unit.is_one_of("microsecond"sv, "nanosecond"sv)) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
// 9. If smallestUnit is "microsecond" and largestUnit is "nanosecond", then
|
|
||||||
if (smallest_unit == "microsecond"sv && largest_unit == "nanosecond"sv) {
|
|
||||||
// a. Throw a RangeError exception.
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, smallest_unit, largest_unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 13.22 LargerOfTwoTemporalUnits ( u1, u2 ), https://tc39.es/proposal-temporal/#sec-temporal-largeroftwotemporalunits
|
|
||||||
StringView larger_of_two_temporal_units(StringView unit1, StringView unit2)
|
StringView larger_of_two_temporal_units(StringView unit1, StringView unit2)
|
||||||
{
|
{
|
||||||
// 1. If either u1 or u2 is "year", return "year".
|
// 1. Assert: Both u1 and u2 are listed in the Singular column of Table 13.
|
||||||
if (unit1 == "year"sv || unit2 == "year"sv)
|
|
||||||
return "year"sv;
|
// 2. For each row of Table 13, except the header row, in table order, do
|
||||||
// 2. If either u1 or u2 is "month", return "month".
|
for (auto const& row : temporal_units) {
|
||||||
if (unit1 == "month"sv || unit2 == "month"sv)
|
// a. Let unit be the value in the Singular column of the row.
|
||||||
return "month"sv;
|
auto unit = row.singular;
|
||||||
// 3. If either u1 or u2 is "week", return "week".
|
|
||||||
if (unit1 == "week"sv || unit2 == "week"sv)
|
// b. If SameValue(u1, unit) is true, return unit.
|
||||||
return "week"sv;
|
if (unit1 == unit)
|
||||||
// 4. If either u1 or u2 is "day", return "day".
|
return unit;
|
||||||
if (unit1 == "day"sv || unit2 == "day"sv)
|
|
||||||
return "day"sv;
|
// c. If SameValue(u2, unit) is true, return unit.
|
||||||
// 5. If either u1 or u2 is "hour", return "hour".
|
if (unit2 == unit)
|
||||||
if (unit1 == "hour"sv || unit2 == "hour"sv)
|
return unit;
|
||||||
return "hour"sv;
|
}
|
||||||
// 6. If either u1 or u2 is "minute", return "minute".
|
VERIFY_NOT_REACHED();
|
||||||
if (unit1 == "minute"sv || unit2 == "minute"sv)
|
|
||||||
return "minute"sv;
|
|
||||||
// 7. If either u1 or u2 is "second", return "second".
|
|
||||||
if (unit1 == "second"sv || unit2 == "second"sv)
|
|
||||||
return "second"sv;
|
|
||||||
// 8. If either u1 or u2 is "millisecond", return "millisecond".
|
|
||||||
if (unit1 == "millisecond"sv || unit2 == "millisecond"sv)
|
|
||||||
return "millisecond"sv;
|
|
||||||
// 9. If either u1 or u2 is "microsecond", return "microsecond".
|
|
||||||
if (unit1 == "microsecond"sv || unit2 == "microsecond"sv)
|
|
||||||
return "microsecond"sv;
|
|
||||||
// 10. Return "nanosecond".
|
|
||||||
return "nanosecond"sv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.23 MergeLargestUnitOption ( options, largestUnit ), https://tc39.es/proposal-temporal/#sec-temporal-mergelargestunitoption
|
// 13.19 MergeLargestUnitOption ( options, largestUnit ), https://tc39.es/proposal-temporal/#sec-temporal-mergelargestunitoption
|
||||||
ThrowCompletionOr<Object*> merge_largest_unit_option(GlobalObject& global_object, Object const* options, String largest_unit)
|
ThrowCompletionOr<Object*> merge_largest_unit_option(GlobalObject& global_object, Object const* options, String largest_unit)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -867,7 +800,7 @@ ThrowCompletionOr<Object*> merge_largest_unit_option(GlobalObject& global_object
|
|||||||
return merged;
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.24 MaximumTemporalDurationRoundingIncrement ( unit ), https://tc39.es/proposal-temporal/#sec-temporal-maximumtemporaldurationroundingincrement
|
// 13.20 MaximumTemporalDurationRoundingIncrement ( unit ), https://tc39.es/proposal-temporal/#sec-temporal-maximumtemporaldurationroundingincrement
|
||||||
Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit)
|
Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit)
|
||||||
{
|
{
|
||||||
// 1. If unit is "year", "month", "week", or "day", then
|
// 1. If unit is "year", "month", "week", or "day", then
|
||||||
@ -895,7 +828,7 @@ Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit)
|
|||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.25 RejectObjectWithCalendarOrTimeZone ( object ), https://tc39.es/proposal-temporal/#sec-temporal-rejectobjectwithcalendarortimezone
|
// 13.21 RejectObjectWithCalendarOrTimeZone ( object ), https://tc39.es/proposal-temporal/#sec-temporal-rejectobjectwithcalendarortimezone
|
||||||
ThrowCompletionOr<void> reject_object_with_calendar_or_time_zone(GlobalObject& global_object, Object& object)
|
ThrowCompletionOr<void> reject_object_with_calendar_or_time_zone(GlobalObject& global_object, Object& object)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -929,7 +862,7 @@ ThrowCompletionOr<void> reject_object_with_calendar_or_time_zone(GlobalObject& g
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.26 FormatSecondsStringPart ( second, millisecond, microsecond, nanosecond, precision ), https://tc39.es/proposal-temporal/#sec-temporal-formatsecondsstringpart
|
// 13.22 FormatSecondsStringPart ( second, millisecond, microsecond, nanosecond, precision ), https://tc39.es/proposal-temporal/#sec-temporal-formatsecondsstringpart
|
||||||
String format_seconds_string_part(u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Variant<StringView, u8> const& precision)
|
String format_seconds_string_part(u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Variant<StringView, u8> const& precision)
|
||||||
{
|
{
|
||||||
// 1. Assert: second, millisecond, microsecond and nanosecond are integers.
|
// 1. Assert: second, millisecond, microsecond and nanosecond are integers.
|
||||||
@ -979,7 +912,7 @@ String format_seconds_string_part(u8 second, u16 millisecond, u16 microsecond, u
|
|||||||
return String::formatted("{}.{}", seconds_string, fraction_string);
|
return String::formatted("{}.{}", seconds_string, fraction_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.28 GetUnsignedRoundingMode ( roundingMode, isNegative ), https://tc39.es/proposal-temporal/#sec-temporal-getunsignedroundingmode
|
// 13.24 GetUnsignedRoundingMode ( roundingMode, isNegative ), https://tc39.es/proposal-temporal/#sec-temporal-getunsignedroundingmode
|
||||||
UnsignedRoundingMode get_unsigned_rounding_mode(StringView rounding_mode, bool is_negative)
|
UnsignedRoundingMode get_unsigned_rounding_mode(StringView rounding_mode, bool is_negative)
|
||||||
{
|
{
|
||||||
// 1. If isNegative is true, return the specification type in the third column of Table 14 where the first column is roundingMode and the second column is "negative".
|
// 1. If isNegative is true, return the specification type in the third column of Table 14 where the first column is roundingMode and the second column is "negative".
|
||||||
@ -1033,7 +966,7 @@ UnsignedRoundingMode get_unsigned_rounding_mode(StringView rounding_mode, bool i
|
|||||||
// it uses mathematical values which can be arbitrarily (but not infinitely) large.
|
// it uses mathematical values which can be arbitrarily (but not infinitely) large.
|
||||||
// Incidentally V8's Temporal implementation does the same :^)
|
// Incidentally V8's Temporal implementation does the same :^)
|
||||||
|
|
||||||
// 13.29 ApplyUnsignedRoundingMode ( x, r1, r2, unsignedRoundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-applyunsignedroundingmode
|
// 13.25 ApplyUnsignedRoundingMode ( x, r1, r2, unsignedRoundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-applyunsignedroundingmode
|
||||||
double apply_unsigned_rounding_mode(double x, double r1, double r2, Optional<UnsignedRoundingMode> const& unsigned_rounding_mode)
|
double apply_unsigned_rounding_mode(double x, double r1, double r2, Optional<UnsignedRoundingMode> const& unsigned_rounding_mode)
|
||||||
{
|
{
|
||||||
// 1. If x is equal to r1, return r1.
|
// 1. If x is equal to r1, return r1.
|
||||||
@ -1093,7 +1026,7 @@ double apply_unsigned_rounding_mode(double x, double r1, double r2, Optional<Uns
|
|||||||
return r2;
|
return r2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.29 ApplyUnsignedRoundingMode ( x, r1, r2, unsignedRoundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-applyunsignedroundingmode
|
// 13.25 ApplyUnsignedRoundingMode ( x, r1, r2, unsignedRoundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-applyunsignedroundingmode
|
||||||
Crypto::SignedBigInteger apply_unsigned_rounding_mode(Crypto::SignedDivisionResult const& x, Crypto::SignedBigInteger const& r1, Crypto::SignedBigInteger const& r2, Optional<UnsignedRoundingMode> const& unsigned_rounding_mode, Crypto::UnsignedBigInteger const& increment)
|
Crypto::SignedBigInteger apply_unsigned_rounding_mode(Crypto::SignedDivisionResult const& x, Crypto::SignedBigInteger const& r1, Crypto::SignedBigInteger const& r2, Optional<UnsignedRoundingMode> const& unsigned_rounding_mode, Crypto::UnsignedBigInteger const& increment)
|
||||||
{
|
{
|
||||||
// 1. If x is equal to r1, return r1.
|
// 1. If x is equal to r1, return r1.
|
||||||
@ -1153,7 +1086,7 @@ Crypto::SignedBigInteger apply_unsigned_rounding_mode(Crypto::SignedDivisionResu
|
|||||||
return r2;
|
return r2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.30 RoundNumberToIncrement ( x, increment, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundnumbertoincrement
|
// 13.26 RoundNumberToIncrement ( x, increment, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundnumbertoincrement
|
||||||
double round_number_to_increment(double x, u64 increment, StringView rounding_mode)
|
double round_number_to_increment(double x, u64 increment, StringView rounding_mode)
|
||||||
{
|
{
|
||||||
VERIFY(rounding_mode == "ceil"sv || rounding_mode == "floor"sv || rounding_mode == "trunc"sv || rounding_mode == "halfExpand"sv);
|
VERIFY(rounding_mode == "ceil"sv || rounding_mode == "floor"sv || rounding_mode == "trunc"sv || rounding_mode == "halfExpand"sv);
|
||||||
@ -1199,7 +1132,7 @@ double round_number_to_increment(double x, u64 increment, StringView rounding_mo
|
|||||||
return rounded * static_cast<double>(increment);
|
return rounded * static_cast<double>(increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.30 RoundNumberToIncrement ( x, increment, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundnumbertoincrement
|
// 13.26 RoundNumberToIncrement ( x, increment, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundnumbertoincrement
|
||||||
Crypto::SignedBigInteger round_number_to_increment(Crypto::SignedBigInteger const& x, u64 increment, StringView rounding_mode)
|
Crypto::SignedBigInteger round_number_to_increment(Crypto::SignedBigInteger const& x, u64 increment, StringView rounding_mode)
|
||||||
{
|
{
|
||||||
VERIFY(rounding_mode == "ceil"sv || rounding_mode == "floor"sv || rounding_mode == "trunc"sv || rounding_mode == "halfExpand"sv);
|
VERIFY(rounding_mode == "ceil"sv || rounding_mode == "floor"sv || rounding_mode == "trunc"sv || rounding_mode == "halfExpand"sv);
|
||||||
@ -1254,7 +1187,7 @@ Crypto::SignedBigInteger round_number_to_increment(Crypto::SignedBigInteger cons
|
|||||||
return rounded.multiplied_by(increment_big_int);
|
return rounded.multiplied_by(increment_big_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.32 ParseISODateTime ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parseisodatetime
|
// 13.28 ParseISODateTime ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parseisodatetime
|
||||||
ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object, ParseResult const& parse_result)
|
ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object, ParseResult const& parse_result)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1401,7 +1334,7 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
|
|||||||
return ISODateTime { .year = year_mv, .month = month_mv, .day = day_mv, .hour = hour_mv, .minute = minute_mv, .second = second_mv, .millisecond = millisecond_mv, .microsecond = microsecond_mv, .nanosecond = nanosecond_mv, .calendar = move(calendar_val) };
|
return ISODateTime { .year = year_mv, .month = month_mv, .day = day_mv, .hour = hour_mv, .minute = minute_mv, .second = second_mv, .millisecond = millisecond_mv, .microsecond = microsecond_mv, .nanosecond = nanosecond_mv, .calendar = move(calendar_val) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.33 ParseTemporalInstantString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalinstantstring
|
// 13.29 ParseTemporalInstantString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalinstantstring
|
||||||
ThrowCompletionOr<TemporalInstant> parse_temporal_instant_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalInstant> parse_temporal_instant_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1433,7 +1366,7 @@ ThrowCompletionOr<TemporalInstant> parse_temporal_instant_string(GlobalObject& g
|
|||||||
return TemporalInstant { .year = result.year, .month = result.month, .day = result.day, .hour = result.hour, .minute = result.minute, .second = result.second, .millisecond = result.millisecond, .microsecond = result.microsecond, .nanosecond = result.nanosecond, .time_zone_offset = move(offset_string) };
|
return TemporalInstant { .year = result.year, .month = result.month, .day = result.day, .hour = result.hour, .minute = result.minute, .second = result.second, .millisecond = result.millisecond, .microsecond = result.microsecond, .nanosecond = result.nanosecond, .time_zone_offset = move(offset_string) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.34 ParseTemporalZonedDateTimeString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalzoneddatetimestring
|
// 13.30 ParseTemporalZonedDateTimeString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalzoneddatetimestring
|
||||||
ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_zoned_date_time_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_zoned_date_time_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1455,7 +1388,7 @@ ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_zoned_date_time_string(G
|
|||||||
return TemporalZonedDateTime { .date_time = move(result), .time_zone = move(time_zone_result) };
|
return TemporalZonedDateTime { .date_time = move(result), .time_zone = move(time_zone_result) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.35 ParseTemporalCalendarString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalcalendarstring
|
// 13.31 ParseTemporalCalendarString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalcalendarstring
|
||||||
ThrowCompletionOr<String> parse_temporal_calendar_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<String> parse_temporal_calendar_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1480,7 +1413,7 @@ ThrowCompletionOr<String> parse_temporal_calendar_string(GlobalObject& global_ob
|
|||||||
return id.value();
|
return id.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.36 ParseTemporalDateString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaldatestring
|
// 13.32 ParseTemporalDateString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaldatestring
|
||||||
ThrowCompletionOr<TemporalDate> parse_temporal_date_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalDate> parse_temporal_date_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
// 1. Let parts be ? ParseTemporalDateTimeString(isoString).
|
// 1. Let parts be ? ParseTemporalDateTimeString(isoString).
|
||||||
@ -1490,7 +1423,7 @@ ThrowCompletionOr<TemporalDate> parse_temporal_date_string(GlobalObject& global_
|
|||||||
return TemporalDate { .year = parts.year, .month = parts.month, .day = parts.day, .calendar = move(parts.calendar) };
|
return TemporalDate { .year = parts.year, .month = parts.month, .day = parts.day, .calendar = move(parts.calendar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.37 ParseTemporalDateTimeString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaldatetimestring
|
// 13.33 ParseTemporalDateTimeString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaldatetimestring
|
||||||
ThrowCompletionOr<ISODateTime> parse_temporal_date_time_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<ISODateTime> parse_temporal_date_time_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1510,7 +1443,7 @@ ThrowCompletionOr<ISODateTime> parse_temporal_date_time_string(GlobalObject& glo
|
|||||||
return parse_iso_date_time(global_object, *parse_result);
|
return parse_iso_date_time(global_object, *parse_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.38 ParseTemporalDurationString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaldurationstring
|
// 13.34 ParseTemporalDurationString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaldurationstring
|
||||||
ThrowCompletionOr<DurationRecord> parse_temporal_duration_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<DurationRecord> parse_temporal_duration_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1650,7 +1583,7 @@ ThrowCompletionOr<DurationRecord> parse_temporal_duration_string(GlobalObject& g
|
|||||||
return create_duration_record(global_object, years * factor, months * factor, weeks * factor, days * factor, hours * factor, floor(minutes) * factor, floor(seconds) * factor, floor(milliseconds) * factor, floor(microseconds) * factor, floor(nanoseconds) * factor);
|
return create_duration_record(global_object, years * factor, months * factor, weeks * factor, days * factor, hours * factor, floor(minutes) * factor, floor(seconds) * factor, floor(milliseconds) * factor, floor(microseconds) * factor, floor(nanoseconds) * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.39 ParseTemporalMonthDayString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalmonthdaystring
|
// 13.35 ParseTemporalMonthDayString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalmonthdaystring
|
||||||
ThrowCompletionOr<TemporalMonthDay> parse_temporal_month_day_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalMonthDay> parse_temporal_month_day_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1682,7 +1615,7 @@ ThrowCompletionOr<TemporalMonthDay> parse_temporal_month_day_string(GlobalObject
|
|||||||
return TemporalMonthDay { .year = year, .month = result.month, .day = result.day, .calendar = move(result.calendar) };
|
return TemporalMonthDay { .year = year, .month = result.month, .day = result.day, .calendar = move(result.calendar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.40 ParseTemporalRelativeToString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalrelativetostring
|
// 13.36 ParseTemporalRelativeToString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalrelativetostring
|
||||||
ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_relative_to_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_relative_to_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1727,7 +1660,7 @@ ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_relative_to_string(Globa
|
|||||||
return TemporalZonedDateTime { .date_time = move(result), .time_zone = { .z = z, .offset_string = move(offset_string), .name = move(time_zone) } };
|
return TemporalZonedDateTime { .date_time = move(result), .time_zone = { .z = z, .offset_string = move(offset_string), .name = move(time_zone) } };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.41 ParseTemporalTimeString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaltimestring
|
// 13.37 ParseTemporalTimeString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaltimestring
|
||||||
ThrowCompletionOr<TemporalTime> parse_temporal_time_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalTime> parse_temporal_time_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1750,7 +1683,7 @@ ThrowCompletionOr<TemporalTime> parse_temporal_time_string(GlobalObject& global_
|
|||||||
return TemporalTime { .hour = result.hour, .minute = result.minute, .second = result.second, .millisecond = result.millisecond, .microsecond = result.microsecond, .nanosecond = result.nanosecond, .calendar = move(result.calendar) };
|
return TemporalTime { .hour = result.hour, .minute = result.minute, .second = result.second, .millisecond = result.millisecond, .microsecond = result.microsecond, .nanosecond = result.nanosecond, .calendar = move(result.calendar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.42 ParseTemporalTimeZoneString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaltimezonestring
|
// 13.38 ParseTemporalTimeZoneString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaltimezonestring
|
||||||
ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1789,7 +1722,7 @@ ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject
|
|||||||
return TemporalTimeZone { .z = false, .offset_string = Optional<String>(move(offset_string)), .name = Optional<String>(move(name)) };
|
return TemporalTimeZone { .z = false, .offset_string = Optional<String>(move(offset_string)), .name = Optional<String>(move(name)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.43 ParseTemporalYearMonthString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalyearmonthstring
|
// 13.39 ParseTemporalYearMonthString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalyearmonthstring
|
||||||
ThrowCompletionOr<TemporalYearMonth> parse_temporal_year_month_string(GlobalObject& global_object, String const& iso_string)
|
ThrowCompletionOr<TemporalYearMonth> parse_temporal_year_month_string(GlobalObject& global_object, String const& iso_string)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1812,7 +1745,7 @@ ThrowCompletionOr<TemporalYearMonth> parse_temporal_year_month_string(GlobalObje
|
|||||||
return TemporalYearMonth { .year = result.year, .month = result.month, .day = result.day, .calendar = move(result.calendar) };
|
return TemporalYearMonth { .year = result.year, .month = result.month, .day = result.day, .calendar = move(result.calendar) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.44 ToPositiveInteger ( argument ), https://tc39.es/proposal-temporal/#sec-temporal-topositiveinteger
|
// 13.40 ToPositiveInteger ( argument ), https://tc39.es/proposal-temporal/#sec-temporal-topositiveinteger
|
||||||
ThrowCompletionOr<double> to_positive_integer(GlobalObject& global_object, Value argument)
|
ThrowCompletionOr<double> to_positive_integer(GlobalObject& global_object, Value argument)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1830,7 +1763,7 @@ ThrowCompletionOr<double> to_positive_integer(GlobalObject& global_object, Value
|
|||||||
return integer;
|
return integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.47 PrepareTemporalFields ( fields, fieldNames, requiredFields ), https://tc39.es/proposal-temporal/#sec-temporal-preparetemporalfields
|
// 13.43 PrepareTemporalFields ( fields, fieldNames, requiredFields ), https://tc39.es/proposal-temporal/#sec-temporal-preparetemporalfields
|
||||||
ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject& global_object, Object const& fields, Vector<String> const& field_names, Vector<StringView> const& required_fields)
|
ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject& global_object, Object const& fields, Vector<String> const& field_names, Vector<StringView> const& required_fields)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1879,7 +1812,7 @@ ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject& global_object,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.48 PreparePartialTemporalFields ( fields, fieldNames ), https://tc39.es/proposal-temporal/#sec-temporal-preparepartialtemporalfields
|
// 13.44 PreparePartialTemporalFields ( fields, fieldNames ), https://tc39.es/proposal-temporal/#sec-temporal-preparepartialtemporalfields
|
||||||
ThrowCompletionOr<Object*> prepare_partial_temporal_fields(GlobalObject& global_object, Object const& fields, Vector<String> const& field_names)
|
ThrowCompletionOr<Object*> prepare_partial_temporal_fields(GlobalObject& global_object, Object const& fields, Vector<String> const& field_names)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
@ -1924,5 +1857,4 @@ ThrowCompletionOr<Object*> prepare_partial_temporal_fields(GlobalObject& global_
|
|||||||
// 5. Return result.
|
// 5. Return result.
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,12 @@ enum class OptionType {
|
|||||||
Number
|
Number
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class UnitGroup {
|
||||||
|
Date,
|
||||||
|
Time,
|
||||||
|
DateTime,
|
||||||
|
};
|
||||||
|
|
||||||
struct ISODateTime {
|
struct ISODateTime {
|
||||||
i32 year;
|
i32 year;
|
||||||
u8 month;
|
u8 month;
|
||||||
@ -115,6 +121,8 @@ struct SecondsStringPrecision {
|
|||||||
u32 increment;
|
u32 increment;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TemporalUnitRequired { };
|
||||||
|
|
||||||
ThrowCompletionOr<MarkedVector<Value>> iterable_to_list_of_type(GlobalObject&, Value items, Vector<OptionType> const& element_types);
|
ThrowCompletionOr<MarkedVector<Value>> iterable_to_list_of_type(GlobalObject&, Value items, Vector<OptionType> const& element_types);
|
||||||
ThrowCompletionOr<Object*> get_options_object(GlobalObject&, Value options);
|
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);
|
||||||
@ -131,11 +139,8 @@ ThrowCompletionOr<String> to_show_offset_option(GlobalObject&, Object const& nor
|
|||||||
ThrowCompletionOr<u64> to_temporal_rounding_increment(GlobalObject&, Object const& normalized_options, Optional<double> dividend, bool inclusive);
|
ThrowCompletionOr<u64> to_temporal_rounding_increment(GlobalObject&, Object const& normalized_options, Optional<double> dividend, bool inclusive);
|
||||||
ThrowCompletionOr<u64> to_temporal_date_time_rounding_increment(GlobalObject&, Object const& normalized_options, StringView smallest_unit);
|
ThrowCompletionOr<u64> to_temporal_date_time_rounding_increment(GlobalObject&, Object const& normalized_options, StringView smallest_unit);
|
||||||
ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObject&, Object const& normalized_options);
|
ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObject&, Object const& normalized_options);
|
||||||
ThrowCompletionOr<Optional<String>> to_largest_temporal_unit(GlobalObject&, Object const& normalized_options, Vector<StringView> const& disallowed_units, Optional<String> fallback, Optional<String> auto_value = {});
|
ThrowCompletionOr<Optional<String>> get_temporal_unit(GlobalObject&, Object const& normalized_options, PropertyKey const&, UnitGroup, Variant<TemporalUnitRequired, Optional<StringView>> const& default_, Vector<StringView> const& extra_values = {});
|
||||||
ThrowCompletionOr<Optional<String>> to_smallest_temporal_unit(GlobalObject&, Object const& normalized_options, Vector<StringView> const& disallowed_units, Optional<String> fallback);
|
|
||||||
ThrowCompletionOr<String> to_temporal_duration_total_unit(GlobalObject& global_object, Object const& normalized_options);
|
|
||||||
ThrowCompletionOr<Value> to_relative_temporal_object(GlobalObject&, Object const& options);
|
ThrowCompletionOr<Value> to_relative_temporal_object(GlobalObject&, Object const& options);
|
||||||
ThrowCompletionOr<void> validate_temporal_unit_range(GlobalObject&, StringView largest_unit, StringView smallest_unit);
|
|
||||||
StringView larger_of_two_temporal_units(StringView, StringView);
|
StringView larger_of_two_temporal_units(StringView, StringView);
|
||||||
ThrowCompletionOr<Object*> merge_largest_unit_option(GlobalObject&, Object const* options, String largest_unit);
|
ThrowCompletionOr<Object*> merge_largest_unit_option(GlobalObject&, Object const* options, String largest_unit);
|
||||||
Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit);
|
Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit);
|
||||||
@ -164,7 +169,7 @@ ThrowCompletionOr<double> to_positive_integer(GlobalObject&, Value argument);
|
|||||||
ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject&, Object const& fields, Vector<String> const& field_names, Vector<StringView> const& required_fields);
|
ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject&, Object const& fields, Vector<String> const& field_names, Vector<StringView> const& required_fields);
|
||||||
ThrowCompletionOr<Object*> prepare_partial_temporal_fields(GlobalObject&, Object const& fields, Vector<String> const& field_names);
|
ThrowCompletionOr<Object*> prepare_partial_temporal_fields(GlobalObject&, Object const& fields, Vector<String> const& field_names);
|
||||||
|
|
||||||
// 13.45 ToIntegerThrowOnInfinity ( argument ), https://tc39.es/proposal-temporal/#sec-temporal-tointegerthrowoninfinity
|
// 13.41 ToIntegerThrowOnInfinity ( argument ), https://tc39.es/proposal-temporal/#sec-temporal-tointegerthrowoninfinity
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
ThrowCompletionOr<double> to_integer_throw_on_infinity(GlobalObject& global_object, Value argument, ErrorType error_type, Args... args)
|
ThrowCompletionOr<double> to_integer_throw_on_infinity(GlobalObject& global_object, Value argument, ErrorType error_type, Args... args)
|
||||||
{
|
{
|
||||||
@ -183,7 +188,7 @@ ThrowCompletionOr<double> to_integer_throw_on_infinity(GlobalObject& global_obje
|
|||||||
return integer;
|
return integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.46 ToIntegerWithoutRounding ( argument ), https://tc39.es/proposal-temporal/#sec-temporal-tointegerwithoutrounding
|
// 13.42 ToIntegerWithoutRounding ( argument ), https://tc39.es/proposal-temporal/#sec-temporal-tointegerwithoutrounding
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
ThrowCompletionOr<double> to_integer_without_rounding(GlobalObject& global_object, Value argument, ErrorType error_type, Args... args)
|
ThrowCompletionOr<double> to_integer_without_rounding(GlobalObject& global_object, Value argument, ErrorType error_type, Args... args)
|
||||||
{
|
{
|
||||||
|
@ -205,13 +205,17 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::date_until)
|
|||||||
// 6. Set options to ? GetOptionsObject(options).
|
// 6. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, vm.argument(2)));
|
auto const* options = TRY(get_options_object(global_object, vm.argument(2)));
|
||||||
|
|
||||||
// 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day").
|
// 7. Let largestUnit be ? GetTemporalUnit(options, "largestUnit", date, "auto").
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, { "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv }, "auto"sv, "day"sv));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.largestUnit, UnitGroup::Date, { "auto"sv }));
|
||||||
|
|
||||||
// 8. Let result be DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit).
|
// 8. If largestUnit is "auto", set largestUnit to "day".
|
||||||
|
if (largest_unit == "auto")
|
||||||
|
largest_unit = "day"sv;
|
||||||
|
|
||||||
|
// 9. Let result be DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit).
|
||||||
auto result = difference_iso_date(global_object, one->iso_year(), one->iso_month(), one->iso_day(), two->iso_year(), two->iso_month(), two->iso_day(), *largest_unit);
|
auto result = difference_iso_date(global_object, one->iso_year(), one->iso_month(), one->iso_day(), two->iso_year(), two->iso_month(), two->iso_day(), *largest_unit);
|
||||||
|
|
||||||
// 9. Return ! CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0).
|
// 10. Return ! CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0).
|
||||||
return MUST(create_temporal_duration(global_object, result.years, result.months, result.weeks, result.days, 0, 0, 0, 0, 0, 0));
|
return MUST(create_temporal_duration(global_object, result.years, result.months, result.weeks, result.days, 0, 0, 0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,8 +356,8 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::round)
|
|||||||
// 7. Let largestUnitPresent be true.
|
// 7. Let largestUnitPresent be true.
|
||||||
bool largest_unit_present = true;
|
bool largest_unit_present = true;
|
||||||
|
|
||||||
// 8. Let smallestUnit be ? ToSmallestTemporalUnit(roundTo, « », undefined).
|
// 8. Let smallestUnit be ? GetTemporalUnit(roundTo, "smallestUnit", datetime, undefined).
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, *round_to, {}, {}));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *round_to, vm.names.smallestUnit, UnitGroup::DateTime, Optional<StringView> {}));
|
||||||
|
|
||||||
// 9. If smallestUnit is undefined, then
|
// 9. If smallestUnit is undefined, then
|
||||||
if (!smallest_unit.has_value()) {
|
if (!smallest_unit.has_value()) {
|
||||||
@ -374,8 +374,8 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::round)
|
|||||||
// 11. Set defaultLargestUnit to ! LargerOfTwoTemporalUnits(defaultLargestUnit, smallestUnit).
|
// 11. Set defaultLargestUnit to ! LargerOfTwoTemporalUnits(defaultLargestUnit, smallestUnit).
|
||||||
default_largest_unit = larger_of_two_temporal_units(default_largest_unit, *smallest_unit);
|
default_largest_unit = larger_of_two_temporal_units(default_largest_unit, *smallest_unit);
|
||||||
|
|
||||||
// 12. Let largestUnit be ? ToLargestTemporalUnit(roundTo, « », undefined).
|
// 12. Let largestUnit be ? GetTemporalUnit(roundTo, "largestUnit", datetime, undefined, « "auto" »).
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *round_to, {}, {}));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *round_to, vm.names.largestUnit, UnitGroup::DateTime, Optional<StringView> {}, { "auto"sv }));
|
||||||
|
|
||||||
// 13. If largestUnit is undefined, then
|
// 13. If largestUnit is undefined, then
|
||||||
if (!largest_unit.has_value()) {
|
if (!largest_unit.has_value()) {
|
||||||
@ -397,8 +397,9 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::round)
|
|||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingUnits);
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingUnits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit).
|
// 16. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
TRY(validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit));
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
// 17. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
// 17. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"sv));
|
||||||
@ -473,11 +474,11 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::total)
|
|||||||
// 6. Let relativeTo be ? ToRelativeTemporalObject(totalOf).
|
// 6. Let relativeTo be ? ToRelativeTemporalObject(totalOf).
|
||||||
auto relative_to = TRY(to_relative_temporal_object(global_object, *total_of));
|
auto relative_to = TRY(to_relative_temporal_object(global_object, *total_of));
|
||||||
|
|
||||||
// 7. Let unit be ? ToTemporalDurationTotalUnit(totalOf).
|
// 7. Let unit be ? GetTemporalUnit(totalOf, "unit", datetime, required).
|
||||||
auto unit = TRY(to_temporal_duration_total_unit(global_object, *total_of));
|
auto unit = TRY(get_temporal_unit(global_object, *total_of, vm.names.unit, UnitGroup::DateTime, TemporalUnitRequired {}));
|
||||||
|
|
||||||
// 8. Let unbalanceResult be ? UnbalanceDurationRelative(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], unit, relativeTo).
|
// 8. Let unbalanceResult be ? UnbalanceDurationRelative(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], unit, relativeTo).
|
||||||
auto unbalance_result = TRY(unbalance_duration_relative(global_object, duration->years(), duration->months(), duration->weeks(), duration->days(), unit, relative_to));
|
auto unbalance_result = TRY(unbalance_duration_relative(global_object, duration->years(), duration->months(), duration->weeks(), duration->days(), *unit, relative_to));
|
||||||
|
|
||||||
// 9. Let intermediate be undefined.
|
// 9. Let intermediate be undefined.
|
||||||
ZonedDateTime* intermediate = nullptr;
|
ZonedDateTime* intermediate = nullptr;
|
||||||
@ -489,10 +490,10 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::total)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 11. Let balanceResult be ? BalanceDuration(unbalanceResult.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], unit, intermediate).
|
// 11. Let balanceResult be ? BalanceDuration(unbalanceResult.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], unit, intermediate).
|
||||||
auto balance_result = TRY(balance_duration(global_object, unbalance_result.days, duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger::create_from(duration->nanoseconds()), unit, intermediate));
|
auto balance_result = TRY(balance_duration(global_object, unbalance_result.days, duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger::create_from(duration->nanoseconds()), *unit, intermediate));
|
||||||
|
|
||||||
// 12. Let roundRecord be ? RoundDuration(unbalanceResult.[[Years]], unbalanceResult.[[Months]], unbalanceResult.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]], 1, unit, "trunc", relativeTo).
|
// 12. Let roundRecord be ? RoundDuration(unbalanceResult.[[Years]], unbalanceResult.[[Months]], unbalanceResult.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]], 1, unit, "trunc", relativeTo).
|
||||||
auto round_record = TRY(round_duration(global_object, unbalance_result.years, unbalance_result.months, unbalance_result.weeks, balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds, 1, unit, "trunc"sv, relative_to.is_object() ? &relative_to.as_object() : nullptr));
|
auto round_record = TRY(round_duration(global_object, unbalance_result.years, unbalance_result.months, unbalance_result.weeks, balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds, 1, *unit, "trunc"sv, relative_to.is_object() ? &relative_to.as_object() : nullptr));
|
||||||
|
|
||||||
// 13. Let roundResult be roundRecord.[[DurationRecord]].
|
// 13. Let roundResult be roundRecord.[[DurationRecord]].
|
||||||
auto& round_result = round_record.duration_record;
|
auto& round_result = round_record.duration_record;
|
||||||
|
@ -286,6 +286,8 @@ ThrowCompletionOr<String> temporal_instant_to_string(GlobalObject& global_object
|
|||||||
// 8.5.10 DifferenceTemporalInstant ( operation, instant, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalinstant
|
// 8.5.10 DifferenceTemporalInstant ( operation, instant, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalinstant
|
||||||
ThrowCompletionOr<Duration*> difference_temporal_instant(GlobalObject& global_object, DifferenceOperation operation, Instant const& instant, Value other_value, Value options_value)
|
ThrowCompletionOr<Duration*> difference_temporal_instant(GlobalObject& global_object, DifferenceOperation operation, Instant const& instant, Value other_value, Value options_value)
|
||||||
{
|
{
|
||||||
|
auto& vm = global_object.vm();
|
||||||
|
|
||||||
// 1. If operation is since, let sign be -1. Otherwise, let sign be 1.
|
// 1. If operation is since, let sign be -1. Otherwise, let sign be 1.
|
||||||
i8 sign = operation == DifferenceOperation::Since ? -1 : 1;
|
i8 sign = operation == DifferenceOperation::Since ? -1 : 1;
|
||||||
|
|
||||||
@ -295,42 +297,47 @@ ThrowCompletionOr<Duration*> difference_temporal_instant(GlobalObject& global_ob
|
|||||||
// 3. Set options to ? GetOptionsObject(options).
|
// 3. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, options_value));
|
auto const* options = TRY(get_options_object(global_object, options_value));
|
||||||
|
|
||||||
// 4. Let smallestUnit be ? ToSmallestTemporalUnit(options, « "year", "month", "week", "day" », "nanosecond").
|
// 4. Let smallestUnit be ? GetTemporalUnit(options, "smallestUnit", time, "nanosecond").
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, *options, { "year"sv, "month"sv, "week"sv, "day"sv }, "nanosecond"sv));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.smallestUnit, UnitGroup::Time, { "nanosecond"sv }));
|
||||||
|
|
||||||
// 5. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("second", smallestUnit).
|
// 5. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("second", smallestUnit).
|
||||||
auto default_largest_unit = larger_of_two_temporal_units("second"sv, *smallest_unit);
|
auto default_largest_unit = larger_of_two_temporal_units("second"sv, *smallest_unit);
|
||||||
|
|
||||||
// 6. Let largestUnit be ? ToLargestTemporalUnit(options, « "year", "month", "week", "day" », "auto", defaultLargestUnit).
|
// 6. Let largestUnit be ? GetTemporalUnit(options, "largestUnit", time, "auto").
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, { "year"sv, "month"sv, "week"sv, "day"sv }, "auto"sv, default_largest_unit));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.largestUnit, UnitGroup::Time, { "auto"sv }));
|
||||||
|
|
||||||
// 7. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit).
|
// 7. If largestUnit is "auto", set largestUnit to defaultLargestUnit.
|
||||||
TRY(validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit));
|
if (largest_unit == "auto"sv)
|
||||||
|
largest_unit = default_largest_unit;
|
||||||
|
|
||||||
// 8. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 8. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
|
// 9. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
|
||||||
// 9. If operation is since, then
|
// 10. If operation is since, then
|
||||||
if (operation == DifferenceOperation::Since) {
|
if (operation == DifferenceOperation::Since) {
|
||||||
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
||||||
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
// 11. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
||||||
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
||||||
|
|
||||||
// 11. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
// 12. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
||||||
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, *maximum, false));
|
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, *maximum, false));
|
||||||
|
|
||||||
// 12. Let roundedNs be ! DifferenceInstant(instant.[[Nanoseconds]], other.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode).
|
// 13. Let roundedNs be ! DifferenceInstant(instant.[[Nanoseconds]], other.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode).
|
||||||
auto* rounded_ns = difference_instant(global_object, instant.nanoseconds(), other->nanoseconds(), rounding_increment, *smallest_unit, rounding_mode);
|
auto* rounded_ns = difference_instant(global_object, instant.nanoseconds(), other->nanoseconds(), rounding_increment, *smallest_unit, rounding_mode);
|
||||||
|
|
||||||
// 13. Assert: The following steps cannot fail due to overflow in the Number domain because abs(roundedNs) ≤ 2 × nsMaxInstant.
|
// 14. Assert: The following steps cannot fail due to overflow in the Number domain because abs(roundedNs) ≤ 2 × nsMaxInstant.
|
||||||
|
|
||||||
// 14. Let result be ! BalanceDuration(0, 0, 0, 0, 0, 0, roundedNs, largestUnit).
|
// 15. Let result be ! BalanceDuration(0, 0, 0, 0, 0, 0, roundedNs, largestUnit).
|
||||||
auto result = MUST(balance_duration(global_object, 0, 0, 0, 0, 0, 0, rounded_ns->big_integer(), *largest_unit));
|
auto result = MUST(balance_duration(global_object, 0, 0, 0, 0, 0, 0, rounded_ns->big_integer(), *largest_unit));
|
||||||
|
|
||||||
// 15. Return ! CreateTemporalDuration(0, 0, 0, 0, sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
// 16. Return ! CreateTemporalDuration(0, 0, 0, 0, sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
||||||
return MUST(create_temporal_duration(global_object, 0, 0, 0, 0, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
return MUST(create_temporal_duration(global_object, 0, 0, 0, 0, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,8 +203,8 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::round)
|
|||||||
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Let smallestUnit be ? ToSmallestTemporalUnit(roundTo, « "year", "month", "week", "day" », undefined).
|
// 6. Let smallestUnit be ? GetTemporalUnit(roundTo, "smallestUnit", time, required).
|
||||||
auto smallest_unit_value = TRY(to_smallest_temporal_unit(global_object, *round_to, { "year"sv, "month"sv, "week"sv, "day"sv }, {}));
|
auto smallest_unit_value = TRY(get_temporal_unit(global_object, *round_to, vm.names.smallestUnit, UnitGroup::Time, TemporalUnitRequired {}));
|
||||||
|
|
||||||
// 6. If smallestUnit is undefined, throw a RangeError exception.
|
// 6. If smallestUnit is undefined, throw a RangeError exception.
|
||||||
if (!smallest_unit_value.has_value())
|
if (!smallest_unit_value.has_value())
|
||||||
|
@ -510,20 +510,22 @@ ThrowCompletionOr<Duration*> difference_temporal_plain_date(GlobalObject& global
|
|||||||
// 4. Set options to ? GetOptionsObject(options).
|
// 4. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, options_value));
|
auto const* options = TRY(get_options_object(global_object, options_value));
|
||||||
|
|
||||||
// 5. Let disallowedUnits be « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" ».
|
// 5. Let smallestUnit be ? GetTemporalUnit(options, "smallestUnit", date, "day").
|
||||||
auto disallowed_units = Vector<StringView> { "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv };
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.smallestUnit, UnitGroup::Date, { "day"sv }));
|
||||||
|
|
||||||
// 6. Let smallestUnit be ? ToSmallestTemporalUnit(options, disallowedUnits, "day").
|
// 6. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("day", smallestUnit).
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, *options, disallowed_units, "day"sv));
|
|
||||||
|
|
||||||
// 7. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("day", smallestUnit).
|
|
||||||
auto default_largest_unit = larger_of_two_temporal_units("day"sv, *smallest_unit);
|
auto default_largest_unit = larger_of_two_temporal_units("day"sv, *smallest_unit);
|
||||||
|
|
||||||
// 8. Let largestUnit be ? ToLargestTemporalUnit(options, disallowedUnits, "auto", defaultLargestUnit).
|
// 7. Let largestUnit be ? GetTemporalUnit(options, "largestUnit", date, "auto").
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, disallowed_units, "auto"sv, default_largest_unit));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.largestUnit, UnitGroup::Date, { "auto"sv }));
|
||||||
|
|
||||||
// 9. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit).
|
// 8. If largestUnit is "auto", set largestUnit to defaultLargestUnit.
|
||||||
TRY(validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit));
|
if (largest_unit == "auto"sv)
|
||||||
|
largest_unit = default_largest_unit;
|
||||||
|
|
||||||
|
// 9. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
// 10. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 10. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
@ -409,46 +409,51 @@ ThrowCompletionOr<Duration*> difference_temporal_plain_date_time(GlobalObject& g
|
|||||||
// 4. Set options to ? GetOptionsObject(options).
|
// 4. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, options_value));
|
auto const* options = TRY(get_options_object(global_object, options_value));
|
||||||
|
|
||||||
// 5. Let smallestUnit be ? ToSmallestTemporalUnit(options, « », "nanosecond").
|
// 5. Let smallestUnit be ? GetTemporalUnit(options, "smallestUnit", datetime, "nanosecond").
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, *options, {}, "nanosecond"sv));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.smallestUnit, UnitGroup::DateTime, { "nanosecond"sv }));
|
||||||
|
|
||||||
// 6. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("day", smallestUnit).
|
// 6. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("day", smallestUnit).
|
||||||
auto default_largest_unit = larger_of_two_temporal_units("day"sv, *smallest_unit);
|
auto default_largest_unit = larger_of_two_temporal_units("day"sv, *smallest_unit);
|
||||||
|
|
||||||
// 7. Let largestUnit be ? ToLargestTemporalUnit(options, « », "auto", defaultLargestUnit).
|
// 7. Let largestUnit be ? GetTemporalUnit(options, "largestUnit", datetime, "auto").
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, {}, "auto"sv, default_largest_unit));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.largestUnit, UnitGroup::DateTime, { "auto"sv }));
|
||||||
|
|
||||||
// 8. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit).
|
// 8. If largestUnit is "auto", set largestUnit to defaultLargestUnit.
|
||||||
TRY(validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit));
|
if (largest_unit == "auto"sv)
|
||||||
|
largest_unit = default_largest_unit;
|
||||||
|
|
||||||
// 9. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 9. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
|
// 10. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
|
||||||
// 10. If operation is since, then
|
// 11. If operation is since, then
|
||||||
if (operation == DifferenceOperation::Since) {
|
if (operation == DifferenceOperation::Since) {
|
||||||
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
||||||
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
// 12. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
||||||
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
||||||
|
|
||||||
// 12. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
// 13. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
||||||
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, Optional<double>(maximum), false));
|
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, Optional<double>(maximum), false));
|
||||||
|
|
||||||
// 13. Let diff be ? DifferenceISODateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], other.[[ISOYear]], other.[[ISOMonth]], other.[[ISODay]], other.[[ISOHour]], other.[[ISOMinute]], other.[[ISOSecond]], other.[[ISOMillisecond]], other.[[ISOMicrosecond]], other.[[ISONanosecond]], dateTime.[[Calendar]], largestUnit, options).
|
// 14. Let diff be ? DifferenceISODateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], other.[[ISOYear]], other.[[ISOMonth]], other.[[ISODay]], other.[[ISOHour]], other.[[ISOMinute]], other.[[ISOSecond]], other.[[ISOMillisecond]], other.[[ISOMicrosecond]], other.[[ISONanosecond]], dateTime.[[Calendar]], largestUnit, options).
|
||||||
auto diff = TRY(difference_iso_date_time(global_object, date_time.iso_year(), date_time.iso_month(), date_time.iso_day(), date_time.iso_hour(), date_time.iso_minute(), date_time.iso_second(), date_time.iso_millisecond(), date_time.iso_microsecond(), date_time.iso_nanosecond(), other->iso_year(), other->iso_month(), other->iso_day(), other->iso_hour(), other->iso_minute(), other->iso_second(), other->iso_millisecond(), other->iso_microsecond(), other->iso_nanosecond(), date_time.calendar(), *largest_unit, options));
|
auto diff = TRY(difference_iso_date_time(global_object, date_time.iso_year(), date_time.iso_month(), date_time.iso_day(), date_time.iso_hour(), date_time.iso_minute(), date_time.iso_second(), date_time.iso_millisecond(), date_time.iso_microsecond(), date_time.iso_nanosecond(), other->iso_year(), other->iso_month(), other->iso_day(), other->iso_hour(), other->iso_minute(), other->iso_second(), other->iso_millisecond(), other->iso_microsecond(), other->iso_nanosecond(), date_time.calendar(), *largest_unit, options));
|
||||||
|
|
||||||
// 14. Let relativeTo be ! CreateTemporalDate(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[Calendar]]).
|
// 15. Let relativeTo be ! CreateTemporalDate(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[Calendar]]).
|
||||||
auto* relative_to = MUST(create_temporal_date(global_object, date_time.iso_year(), date_time.iso_month(), date_time.iso_day(), date_time.calendar()));
|
auto* relative_to = MUST(create_temporal_date(global_object, date_time.iso_year(), date_time.iso_month(), date_time.iso_day(), date_time.calendar()));
|
||||||
|
|
||||||
// 15. Let roundResult be (? RoundDuration(diff.[[Years]], diff.[[Months]], diff.[[Weeks]], diff.[[Days]], diff.[[Hours]], diff.[[Minutes]], diff.[[Seconds]], diff.[[Milliseconds]], diff.[[Microseconds]], diff.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode, relativeTo)).[[DurationRecord]].
|
// 16. Let roundResult be (? RoundDuration(diff.[[Years]], diff.[[Months]], diff.[[Weeks]], diff.[[Days]], diff.[[Hours]], diff.[[Minutes]], diff.[[Seconds]], diff.[[Milliseconds]], diff.[[Microseconds]], diff.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode, relativeTo)).[[DurationRecord]].
|
||||||
auto round_result = TRY(round_duration(global_object, diff.years, diff.months, diff.weeks, diff.days, diff.hours, diff.minutes, diff.seconds, diff.milliseconds, diff.microseconds, diff.nanoseconds, rounding_increment, *smallest_unit, rounding_mode, relative_to)).duration_record;
|
auto round_result = TRY(round_duration(global_object, diff.years, diff.months, diff.weeks, diff.days, diff.hours, diff.minutes, diff.seconds, diff.milliseconds, diff.microseconds, diff.nanoseconds, rounding_increment, *smallest_unit, rounding_mode, relative_to)).duration_record;
|
||||||
|
|
||||||
// 16. Let result be ? BalanceDuration(roundResult.[[Days]], roundResult.[[Hours]], roundResult.[[Minutes]], roundResult.[[Seconds]], roundResult.[[Milliseconds]], roundResult.[[Microseconds]], roundResult.[[Nanoseconds]], largestUnit).
|
// 17. Let result be ? BalanceDuration(roundResult.[[Days]], roundResult.[[Hours]], roundResult.[[Minutes]], roundResult.[[Seconds]], roundResult.[[Milliseconds]], roundResult.[[Microseconds]], roundResult.[[Nanoseconds]], largestUnit).
|
||||||
auto result = MUST(balance_duration(global_object, round_result.days, round_result.hours, round_result.minutes, round_result.seconds, round_result.milliseconds, round_result.microseconds, Crypto::SignedBigInteger::create_from((i64)round_result.nanoseconds), *largest_unit));
|
auto result = MUST(balance_duration(global_object, round_result.days, round_result.hours, round_result.minutes, round_result.seconds, round_result.milliseconds, round_result.microseconds, Crypto::SignedBigInteger::create_from((i64)round_result.nanoseconds), *largest_unit));
|
||||||
|
|
||||||
// 17. Return ! CreateTemporalDuration(sign × roundResult.[[Years]], sign × roundResult.[[Months]], sign × roundResult.[[Weeks]], sign × result.[[Days]], sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
// 18. Return ! CreateTemporalDuration(sign × roundResult.[[Years]], sign × roundResult.[[Months]], sign × roundResult.[[Weeks]], sign × result.[[Days]], sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
||||||
return MUST(create_temporal_duration(global_object, sign * round_result.years, sign * round_result.months, sign * round_result.weeks, sign * result.days, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
return MUST(create_temporal_duration(global_object, sign * round_result.years, sign * round_result.months, sign * round_result.weeks, sign * result.days, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,26 +545,19 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::round)
|
|||||||
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Let smallestUnit be ? ToSmallestTemporalUnit(roundTo, « "year", "month", "week" », undefined).
|
// 6. Let smallestUnit be ? GetTemporalUnit(roundTo, "smallestUnit", time, required, « "day" »).
|
||||||
auto smallest_unit_value = TRY(to_smallest_temporal_unit(global_object, *round_to, { "year"sv, "month"sv, "week"sv }, {}));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *round_to, vm.names.smallestUnit, UnitGroup::Time, TemporalUnitRequired {}, { "day"sv }));
|
||||||
|
|
||||||
// 7. If smallestUnit is undefined, throw a RangeError exception.
|
// 7. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
||||||
if (!smallest_unit_value.has_value())
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, vm.names.undefined.as_string(), "smallestUnit");
|
|
||||||
|
|
||||||
// NOTE: At this point smallest_unit_value can only be a string
|
|
||||||
auto& smallest_unit = *smallest_unit_value;
|
|
||||||
|
|
||||||
// 8. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"));
|
||||||
|
|
||||||
// 9. Let roundingIncrement be ? ToTemporalDateTimeRoundingIncrement(roundTo, smallestUnit).
|
// 8. Let roundingIncrement be ? ToTemporalDateTimeRoundingIncrement(roundTo, smallestUnit).
|
||||||
auto rounding_increment = TRY(to_temporal_date_time_rounding_increment(global_object, *round_to, smallest_unit));
|
auto rounding_increment = TRY(to_temporal_date_time_rounding_increment(global_object, *round_to, *smallest_unit));
|
||||||
|
|
||||||
// 10. Let result be ! RoundISODateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode).
|
// 9. Let result be ! RoundISODateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode).
|
||||||
auto result = round_iso_date_time(date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond(), rounding_increment, smallest_unit, rounding_mode);
|
auto result = round_iso_date_time(date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond(), rounding_increment, *smallest_unit, rounding_mode);
|
||||||
|
|
||||||
// 11. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], dateTime.[[Calendar]]).
|
// 10. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], dateTime.[[Calendar]]).
|
||||||
return TRY(create_temporal_date_time(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, date_time->calendar()));
|
return TRY(create_temporal_date_time(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, date_time->calendar()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,6 +622,8 @@ DaysAndTime round_time(u8 hour, u8 minute, u8 second, u16 millisecond, u16 micro
|
|||||||
// 4.5.14 DifferenceTemporalPlainTime ( operation, temporalTime, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalplaintime
|
// 4.5.14 DifferenceTemporalPlainTime ( operation, temporalTime, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalplaintime
|
||||||
ThrowCompletionOr<Duration*> difference_temporal_plain_time(GlobalObject& global_object, DifferenceOperation operation, PlainTime const& temporal_time, Value other_value, Value options_value)
|
ThrowCompletionOr<Duration*> difference_temporal_plain_time(GlobalObject& global_object, DifferenceOperation operation, PlainTime const& temporal_time, Value other_value, Value options_value)
|
||||||
{
|
{
|
||||||
|
auto& vm = global_object.vm();
|
||||||
|
|
||||||
// 1. If operation is since, let sign be -1. Otherwise, let sign be 1.
|
// 1. If operation is since, let sign be -1. Otherwise, let sign be 1.
|
||||||
i8 sign = operation == DifferenceOperation::Since ? -1 : 1;
|
i8 sign = operation == DifferenceOperation::Since ? -1 : 1;
|
||||||
|
|
||||||
@ -631,40 +633,45 @@ ThrowCompletionOr<Duration*> difference_temporal_plain_time(GlobalObject& global
|
|||||||
// 3. Set options to ? GetOptionsObject(options).
|
// 3. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, options_value));
|
auto const* options = TRY(get_options_object(global_object, options_value));
|
||||||
|
|
||||||
// 4. Let smallestUnit be ? ToSmallestTemporalUnit(options, « "year", "month", "week", "day" », "nanosecond").
|
// 4. Let smallestUnit be ? GetTemporalUnit(options, "smallestUnit", time, "nanosecond").
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, *options, { "year"sv, "month"sv, "week"sv, "day"sv }, "nanosecond"sv));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.smallestUnit, UnitGroup::Time, { "nanosecond"sv }));
|
||||||
|
|
||||||
// 5. Let largestUnit be ? ToLargestTemporalUnit(options, « "year", "month", "week", "day" », "auto", "hour").
|
// 5. Let largestUnit be ? GetTemporalUnit(options, "largestUnit", time, "auto").
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, { "year"sv, "month"sv, "week"sv, "day"sv }, "auto"sv, "hour"sv));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.largestUnit, UnitGroup::Time, { "auto"sv }));
|
||||||
|
|
||||||
// 6. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit).
|
// 6. If largestUnit is "auto", set largestUnit to "hour".
|
||||||
TRY(validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit));
|
if (largest_unit == "auto"sv)
|
||||||
|
largest_unit = "hour"sv;
|
||||||
|
|
||||||
// 7. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 7. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
|
// 8. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
|
||||||
// 8. If operation is since, then
|
// 9. If operation is since, then
|
||||||
if (operation == DifferenceOperation::Since) {
|
if (operation == DifferenceOperation::Since) {
|
||||||
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
||||||
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
// 10. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
||||||
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
||||||
|
|
||||||
// 10. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
// 11. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
||||||
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, Optional<double>(maximum), false));
|
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, Optional<double>(maximum), false));
|
||||||
|
|
||||||
// 11. Let result be ! DifferenceTime(temporalTime.[[ISOHour]], temporalTime.[[ISOMinute]], temporalTime.[[ISOSecond]], temporalTime.[[ISOMillisecond]], temporalTime.[[ISOMicrosecond]], temporalTime.[[ISONanosecond]], other.[[ISOHour]], other.[[ISOMinute]], other.[[ISOSecond]], other.[[ISOMillisecond]], other.[[ISOMicrosecond]], other.[[ISONanosecond]]).
|
// 12. Let result be ! DifferenceTime(temporalTime.[[ISOHour]], temporalTime.[[ISOMinute]], temporalTime.[[ISOSecond]], temporalTime.[[ISOMillisecond]], temporalTime.[[ISOMicrosecond]], temporalTime.[[ISONanosecond]], other.[[ISOHour]], other.[[ISOMinute]], other.[[ISOSecond]], other.[[ISOMillisecond]], other.[[ISOMicrosecond]], other.[[ISONanosecond]]).
|
||||||
auto result = difference_time(temporal_time.iso_hour(), temporal_time.iso_minute(), temporal_time.iso_second(), temporal_time.iso_millisecond(), temporal_time.iso_microsecond(), temporal_time.iso_nanosecond(), other->iso_hour(), other->iso_minute(), other->iso_second(), other->iso_millisecond(), other->iso_microsecond(), other->iso_nanosecond());
|
auto result = difference_time(temporal_time.iso_hour(), temporal_time.iso_minute(), temporal_time.iso_second(), temporal_time.iso_millisecond(), temporal_time.iso_microsecond(), temporal_time.iso_nanosecond(), other->iso_hour(), other->iso_minute(), other->iso_second(), other->iso_millisecond(), other->iso_microsecond(), other->iso_nanosecond());
|
||||||
|
|
||||||
// 12. Set result to (? RoundDuration(0, 0, 0, 0, result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode)).[[DurationRecord]].
|
// 13. Set result to (? RoundDuration(0, 0, 0, 0, result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode)).[[DurationRecord]].
|
||||||
auto rounded_result = TRY(round_duration(global_object, 0, 0, 0, 0, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds, rounding_increment, *smallest_unit, rounding_mode)).duration_record;
|
auto rounded_result = TRY(round_duration(global_object, 0, 0, 0, 0, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds, rounding_increment, *smallest_unit, rounding_mode)).duration_record;
|
||||||
|
|
||||||
// 13. Set result to ? BalanceDuration(0, result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]], largestUnit).
|
// 14. Set result to ? BalanceDuration(0, result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]], largestUnit).
|
||||||
result = MUST(balance_duration(global_object, 0, rounded_result.hours, rounded_result.minutes, rounded_result.seconds, rounded_result.milliseconds, rounded_result.microseconds, Crypto::SignedBigInteger { (i32)rounded_result.nanoseconds }, *largest_unit));
|
result = MUST(balance_duration(global_object, 0, rounded_result.hours, rounded_result.minutes, rounded_result.seconds, rounded_result.milliseconds, rounded_result.microseconds, Crypto::SignedBigInteger { (i32)rounded_result.nanoseconds }, *largest_unit));
|
||||||
|
|
||||||
// 14. Return ! CreateTemporalDuration(0, 0, 0, 0, sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
// 15. Return ! CreateTemporalDuration(0, 0, 0, 0, sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
||||||
return MUST(create_temporal_duration(global_object, 0, 0, 0, 0, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
return MUST(create_temporal_duration(global_object, 0, 0, 0, 0, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,44 +293,37 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::round)
|
|||||||
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Let smallestUnit be ? ToSmallestTemporalUnit(roundTo, « "year", "month", "week", "day" », undefined).
|
// 6. Let smallestUnit be ? GetTemporalUnit(roundTo, "smallestUnit", time, required).
|
||||||
auto smallest_unit_value = TRY(to_smallest_temporal_unit(global_object, *round_to, { "year"sv, "month"sv, "week"sv, "day"sv }, {}));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *round_to, vm.names.smallestUnit, UnitGroup::Time, TemporalUnitRequired {}));
|
||||||
|
|
||||||
// 7. If smallestUnit is undefined, throw a RangeError exception.
|
// 7. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
||||||
if (!smallest_unit_value.has_value())
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, vm.names.undefined.as_string(), "smallestUnit");
|
|
||||||
|
|
||||||
// NOTE: At this point smallest_unit_value can only be a string
|
|
||||||
auto& smallest_unit = *smallest_unit_value;
|
|
||||||
|
|
||||||
// 8. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"));
|
||||||
|
|
||||||
double maximum;
|
double maximum;
|
||||||
|
|
||||||
// 9. If smallestUnit is "hour", then
|
// 8. If smallestUnit is "hour", then
|
||||||
if (smallest_unit == "hour"sv) {
|
if (smallest_unit == "hour"sv) {
|
||||||
// a. Let maximum be 24.
|
// a. Let maximum be 24.
|
||||||
maximum = 24;
|
maximum = 24;
|
||||||
}
|
}
|
||||||
// 10. Else if smallestUnit is "minute" or "second", then
|
// 9. Else if smallestUnit is "minute" or "second", then
|
||||||
else if (smallest_unit == "minute"sv || smallest_unit == "second"sv) {
|
else if (smallest_unit == "minute"sv || smallest_unit == "second"sv) {
|
||||||
// a. Let maximum be 60.
|
// a. Let maximum be 60.
|
||||||
maximum = 60;
|
maximum = 60;
|
||||||
}
|
}
|
||||||
// 11. Else,
|
// 10. Else,
|
||||||
else {
|
else {
|
||||||
// a. Let maximum be 1000.
|
// a. Let maximum be 1000.
|
||||||
maximum = 1000;
|
maximum = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. Let roundingIncrement be ? ToTemporalRoundingIncrement(roundTo, maximum, false).
|
// 11. Let roundingIncrement be ? ToTemporalRoundingIncrement(roundTo, maximum, false).
|
||||||
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *round_to, maximum, false));
|
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *round_to, maximum, false));
|
||||||
|
|
||||||
// 13. Let result be ! RoundTime(temporalTime.[[ISOHour]], temporalTime.[[ISOMinute]], temporalTime.[[ISOSecond]], temporalTime.[[ISOMillisecond]], temporalTime.[[ISOMicrosecond]], temporalTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode).
|
// 12. Let result be ! RoundTime(temporalTime.[[ISOHour]], temporalTime.[[ISOMinute]], temporalTime.[[ISOSecond]], temporalTime.[[ISOMillisecond]], temporalTime.[[ISOMicrosecond]], temporalTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode).
|
||||||
auto result = round_time(temporal_time->iso_hour(), temporal_time->iso_minute(), temporal_time->iso_second(), temporal_time->iso_millisecond(), temporal_time->iso_microsecond(), temporal_time->iso_nanosecond(), rounding_increment, smallest_unit, rounding_mode);
|
auto result = round_time(temporal_time->iso_hour(), temporal_time->iso_minute(), temporal_time->iso_second(), temporal_time->iso_millisecond(), temporal_time->iso_microsecond(), temporal_time->iso_nanosecond(), rounding_increment, *smallest_unit, rounding_mode);
|
||||||
|
|
||||||
// 14. Return ? CreateTemporalTime(result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]]).
|
// 13. Return ? CreateTemporalTime(result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]]).
|
||||||
return TRY(create_temporal_time(global_object, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond));
|
return TRY(create_temporal_time(global_object, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,66 +278,76 @@ ThrowCompletionOr<Duration*> difference_temporal_plain_year_month(GlobalObject&
|
|||||||
// 5. Set options to ? GetOptionsObject(options).
|
// 5. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, options_value));
|
auto const* options = TRY(get_options_object(global_object, options_value));
|
||||||
|
|
||||||
// 6. Let disallowedUnits be « "week", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" ».
|
// 6. Let smallestUnit be ? GetTemporalUnit(options, "smallestUnit", date, "month").
|
||||||
auto disallowed_units = Vector<StringView> { "week"sv, "day"sv, "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv };
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.smallestUnit, UnitGroup::Date, { "month"sv }));
|
||||||
|
|
||||||
// 7. Let smallestUnit be ? ToSmallestTemporalUnit(options, disallowedUnits, "month").
|
// 7. If smallestUnit is "week" or "day", throw a RangeError exception.
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, *options, disallowed_units, "month"sv));
|
if (smallest_unit == "week"sv || smallest_unit == "day"sv)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, *smallest_unit, "smallestUnit"sv);
|
||||||
|
|
||||||
// 8. Let largestUnit be ? ToLargestTemporalUnit(options, disallowedUnits, "auto", "year").
|
// 8. Let largestUnit be ? GetTemporalUnit(options, "largestUnit", date, "auto").
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, disallowed_units, "auto"sv, "year"sv));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.largestUnit, UnitGroup::Date, { "auto"sv }));
|
||||||
|
|
||||||
// 9. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit).
|
// 9. If largestUnit is "week" or "day", throw a RangeError exception.
|
||||||
TRY(validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit));
|
if (largest_unit == "week"sv || largest_unit == "day"sv)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, *largest_unit, "largestUnit"sv);
|
||||||
|
|
||||||
// 10. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 10. If largestUnit is "auto", set largestUnit to "year".
|
||||||
|
if (largest_unit == "auto"sv)
|
||||||
|
largest_unit = "year"sv;
|
||||||
|
|
||||||
|
// 11. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
|
// 12. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
|
||||||
// 11. If operation is since, then
|
// 13. If operation is since, then
|
||||||
if (operation == DifferenceOperation::Since) {
|
if (operation == DifferenceOperation::Since) {
|
||||||
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
||||||
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, undefined, false).
|
// 14. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, undefined, false).
|
||||||
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, {}, false));
|
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, {}, false));
|
||||||
|
|
||||||
// 13. Let fieldNames be ? CalendarFields(calendar, « "monthCode", "year" »).
|
// 15. Let fieldNames be ? CalendarFields(calendar, « "monthCode", "year" »).
|
||||||
auto field_names = TRY(calendar_fields(global_object, calendar, { "monthCode"sv, "year"sv }));
|
auto field_names = TRY(calendar_fields(global_object, calendar, { "monthCode"sv, "year"sv }));
|
||||||
|
|
||||||
// 14. Let otherFields be ? PrepareTemporalFields(other, fieldNames, «»).
|
// 16. Let otherFields be ? PrepareTemporalFields(other, fieldNames, «»).
|
||||||
auto* other_fields = TRY(prepare_temporal_fields(global_object, *other, field_names, {}));
|
auto* other_fields = TRY(prepare_temporal_fields(global_object, *other, field_names, {}));
|
||||||
|
|
||||||
// 15. Perform ! CreateDataPropertyOrThrow(otherFields, "day", 1𝔽).
|
// 17. Perform ! CreateDataPropertyOrThrow(otherFields, "day", 1𝔽).
|
||||||
MUST(other_fields->create_data_property_or_throw(vm.names.day, Value(1)));
|
MUST(other_fields->create_data_property_or_throw(vm.names.day, Value(1)));
|
||||||
|
|
||||||
// 16. Let otherDate be ? CalendarDateFromFields(calendar, otherFields).
|
// 18. Let otherDate be ? CalendarDateFromFields(calendar, otherFields).
|
||||||
auto* other_date = TRY(calendar_date_from_fields(global_object, calendar, *other_fields));
|
auto* other_date = TRY(calendar_date_from_fields(global_object, calendar, *other_fields));
|
||||||
|
|
||||||
// 17. Let thisFields be ? PrepareTemporalFields(yearMonth, fieldNames, «»).
|
// 19. Let thisFields be ? PrepareTemporalFields(yearMonth, fieldNames, «»).
|
||||||
auto* this_fields = TRY(prepare_temporal_fields(global_object, year_month, field_names, {}));
|
auto* this_fields = TRY(prepare_temporal_fields(global_object, year_month, field_names, {}));
|
||||||
|
|
||||||
// 18. Perform ! CreateDataPropertyOrThrow(thisFields, "day", 1𝔽).
|
// 20. Perform ! CreateDataPropertyOrThrow(thisFields, "day", 1𝔽).
|
||||||
MUST(this_fields->create_data_property_or_throw(vm.names.day, Value(1)));
|
MUST(this_fields->create_data_property_or_throw(vm.names.day, Value(1)));
|
||||||
|
|
||||||
// 19. Let thisDate be ? CalendarDateFromFields(calendar, thisFields).
|
// 21. Let thisDate be ? CalendarDateFromFields(calendar, thisFields).
|
||||||
auto* this_date = TRY(calendar_date_from_fields(global_object, calendar, *this_fields));
|
auto* this_date = TRY(calendar_date_from_fields(global_object, calendar, *this_fields));
|
||||||
|
|
||||||
// 20. Let untilOptions be ? MergeLargestUnitOption(options, largestUnit).
|
// 22. Let untilOptions be ? MergeLargestUnitOption(options, largestUnit).
|
||||||
auto* until_options = TRY(merge_largest_unit_option(global_object, options, *largest_unit));
|
auto* until_options = TRY(merge_largest_unit_option(global_object, options, *largest_unit));
|
||||||
|
|
||||||
// 21. Let result be ? CalendarDateUntil(calendar, thisDate, otherDate, untilOptions).
|
// 23. Let result be ? CalendarDateUntil(calendar, thisDate, otherDate, untilOptions).
|
||||||
auto* duration = TRY(calendar_date_until(global_object, calendar, this_date, other_date, *until_options));
|
auto* duration = TRY(calendar_date_until(global_object, calendar, this_date, other_date, *until_options));
|
||||||
|
|
||||||
auto result = DurationRecord { duration->years(), duration->months(), 0, 0, 0, 0, 0, 0, 0, 0 };
|
auto result = DurationRecord { duration->years(), duration->months(), 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
// 22. If smallestUnit is not "month" or roundingIncrement ≠ 1, then
|
// 24. If smallestUnit is not "month" or roundingIncrement ≠ 1, then
|
||||||
if (smallest_unit != "month"sv || rounding_increment != 1) {
|
if (smallest_unit != "month"sv || rounding_increment != 1) {
|
||||||
// a. Set result to (? RoundDuration(result.[[Years]], result.[[Months]], 0, 0, 0, 0, 0, 0, 0, 0, roundingIncrement, smallestUnit, roundingMode, thisDate)).[[DurationRecord]].
|
// a. Set result to (? RoundDuration(result.[[Years]], result.[[Months]], 0, 0, 0, 0, 0, 0, 0, 0, roundingIncrement, smallestUnit, roundingMode, thisDate)).[[DurationRecord]].
|
||||||
result = TRY(round_duration(global_object, result.years, result.months, 0, 0, 0, 0, 0, 0, 0, 0, rounding_increment, *smallest_unit, rounding_mode, this_date)).duration_record;
|
result = TRY(round_duration(global_object, result.years, result.months, 0, 0, 0, 0, 0, 0, 0, 0, rounding_increment, *smallest_unit, rounding_mode, this_date)).duration_record;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 23. Return ! CreateTemporalDuration(sign × result.[[Years]], sign × result.[[Months]], 0, 0, 0, 0, 0, 0, 0, 0).
|
// 25. Return ! CreateTemporalDuration(sign × result.[[Years]], sign × result.[[Months]], 0, 0, 0, 0, 0, 0, 0, 0).
|
||||||
return MUST(create_temporal_duration(global_object, sign * result.years, sign * result.months, 0, 0, 0, 0, 0, 0, 0, 0));
|
return MUST(create_temporal_duration(global_object, sign * result.years, sign * result.months, 0, 0, 0, 0, 0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,34 +557,39 @@ ThrowCompletionOr<Duration*> difference_temporal_zoned_date_time(GlobalObject& g
|
|||||||
// 4. Set options to ? GetOptionsObject(options).
|
// 4. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, options_value));
|
auto const* options = TRY(get_options_object(global_object, options_value));
|
||||||
|
|
||||||
// 5. Let smallestUnit be ? ToSmallestTemporalUnit(options, « », "nanosecond").
|
// 5. Let smallestUnit be ? GetTemporalUnit(options, "smallestUnit", datetime, "nanosecond").
|
||||||
auto smallest_unit = TRY(to_smallest_temporal_unit(global_object, *options, {}, "nanosecond"sv));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.smallestUnit, UnitGroup::DateTime, { "nanosecond"sv }));
|
||||||
|
|
||||||
// 6. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("hour", smallestUnit).
|
// 6. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("hour", smallestUnit).
|
||||||
auto default_largest_unit = larger_of_two_temporal_units("hour"sv, *smallest_unit);
|
auto default_largest_unit = larger_of_two_temporal_units("hour"sv, *smallest_unit);
|
||||||
|
|
||||||
// 7. Let largestUnit be ? ToLargestTemporalUnit(options, « », "auto", defaultLargestUnit).
|
// 7. Let largestUnit be ? GetTemporalUnit(options, "largestUnit", datetime, "auto").
|
||||||
auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, {}, "auto"sv, default_largest_unit));
|
auto largest_unit = TRY(get_temporal_unit(global_object, *options, vm.names.largestUnit, UnitGroup::DateTime, { "auto"sv }));
|
||||||
|
|
||||||
// 8. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit).
|
// 8. If largestUnit is "auto", set largestUnit to defaultLargestUnit.
|
||||||
TRY(validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit));
|
if (largest_unit == "auto"sv)
|
||||||
|
largest_unit = default_largest_unit;
|
||||||
|
|
||||||
// 9. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 9. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
|
// 10. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
|
||||||
// 10. If operation is since, then
|
// 11. If operation is since, then
|
||||||
if (operation == DifferenceOperation::Since) {
|
if (operation == DifferenceOperation::Since) {
|
||||||
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
// a. Set roundingMode to ! NegateTemporalRoundingMode(roundingMode).
|
||||||
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
rounding_mode = negate_temporal_rounding_mode(rounding_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
// 12. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit).
|
||||||
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit);
|
||||||
|
|
||||||
// 12. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
// 13. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false).
|
||||||
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, Optional<double>(maximum), false));
|
auto rounding_increment = TRY(to_temporal_rounding_increment(global_object, *options, Optional<double>(maximum), false));
|
||||||
|
|
||||||
// 13. If largestUnit is not one of "year", "month", "week", or "day", then
|
// 14. If largestUnit is not one of "year", "month", "week", or "day", then
|
||||||
if (!largest_unit->is_one_of("year"sv, "month"sv, "week"sv, "day"sv)) {
|
if (!largest_unit->is_one_of("year"sv, "month"sv, "week"sv, "day"sv)) {
|
||||||
// a. Let differenceNs be ! DifferenceInstant(zonedDateTime.[[Nanoseconds]], other.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode).
|
// a. Let differenceNs be ! DifferenceInstant(zonedDateTime.[[Nanoseconds]], other.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode).
|
||||||
auto* difference_ns = difference_instant(global_object, zoned_date_time.nanoseconds(), other->nanoseconds(), rounding_increment, *smallest_unit, rounding_mode);
|
auto* difference_ns = difference_instant(global_object, zoned_date_time.nanoseconds(), other->nanoseconds(), rounding_increment, *smallest_unit, rounding_mode);
|
||||||
@ -598,25 +603,25 @@ ThrowCompletionOr<Duration*> difference_temporal_zoned_date_time(GlobalObject& g
|
|||||||
return MUST(create_temporal_duration(global_object, 0, 0, 0, 0, sign * balance_result.hours, sign * balance_result.minutes, sign * balance_result.seconds, sign * balance_result.milliseconds, sign * balance_result.microseconds, sign * balance_result.nanoseconds));
|
return MUST(create_temporal_duration(global_object, 0, 0, 0, 0, sign * balance_result.hours, sign * balance_result.minutes, sign * balance_result.seconds, sign * balance_result.milliseconds, sign * balance_result.microseconds, sign * balance_result.nanoseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14. If ? TimeZoneEquals(zonedDateTime.[[TimeZone]], other.[[TimeZone]]) is false, then
|
// 15. If ? TimeZoneEquals(zonedDateTime.[[TimeZone]], other.[[TimeZone]]) is false, then
|
||||||
if (!TRY(time_zone_equals(global_object, zoned_date_time.time_zone(), other->time_zone()))) {
|
if (!TRY(time_zone_equals(global_object, zoned_date_time.time_zone(), other->time_zone()))) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalDifferentTimeZones);
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalDifferentTimeZones);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 15. Let untilOptions be ? MergeLargestUnitOption(options, largestUnit).
|
// 16. Let untilOptions be ? MergeLargestUnitOption(options, largestUnit).
|
||||||
auto* until_options = TRY(merge_largest_unit_option(global_object, options, *largest_unit));
|
auto* until_options = TRY(merge_largest_unit_option(global_object, options, *largest_unit));
|
||||||
|
|
||||||
// 16. Let difference be ? DifferenceZonedDateTime(zonedDateTime.[[Nanoseconds]], other.[[Nanoseconds]], zonedDateTime.[[TimeZone]], zonedDateTime.[[Calendar]], largestUnit, untilOptions).
|
// 17. Let difference be ? DifferenceZonedDateTime(zonedDateTime.[[Nanoseconds]], other.[[Nanoseconds]], zonedDateTime.[[TimeZone]], zonedDateTime.[[Calendar]], largestUnit, untilOptions).
|
||||||
auto difference = TRY(difference_zoned_date_time(global_object, zoned_date_time.nanoseconds(), other->nanoseconds(), zoned_date_time.time_zone(), zoned_date_time.calendar(), *largest_unit, until_options));
|
auto difference = TRY(difference_zoned_date_time(global_object, zoned_date_time.nanoseconds(), other->nanoseconds(), zoned_date_time.time_zone(), zoned_date_time.calendar(), *largest_unit, until_options));
|
||||||
|
|
||||||
// 17. Let roundResult be (? RoundDuration(difference.[[Years]], difference.[[Months]], difference.[[Weeks]], difference.[[Days]], difference.[[Hours]], difference.[[Minutes]], difference.[[Seconds]], difference.[[Milliseconds]], difference.[[Microseconds]], difference.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode, zonedDateTime)).[[DurationRecord]].
|
// 18. Let roundResult be (? RoundDuration(difference.[[Years]], difference.[[Months]], difference.[[Weeks]], difference.[[Days]], difference.[[Hours]], difference.[[Minutes]], difference.[[Seconds]], difference.[[Milliseconds]], difference.[[Microseconds]], difference.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode, zonedDateTime)).[[DurationRecord]].
|
||||||
auto round_result = TRY(round_duration(global_object, difference.years, difference.months, difference.weeks, difference.days, difference.hours, difference.minutes, difference.seconds, difference.milliseconds, difference.microseconds, difference.nanoseconds, rounding_increment, *smallest_unit, rounding_mode, &zoned_date_time)).duration_record;
|
auto round_result = TRY(round_duration(global_object, difference.years, difference.months, difference.weeks, difference.days, difference.hours, difference.minutes, difference.seconds, difference.milliseconds, difference.microseconds, difference.nanoseconds, rounding_increment, *smallest_unit, rounding_mode, &zoned_date_time)).duration_record;
|
||||||
|
|
||||||
// 18. Let result be ? AdjustRoundedDurationDays(roundResult.[[Years]], roundResult.[[Months]], roundResult.[[Weeks]], roundResult.[[Days]], roundResult.[[Hours]], roundResult.[[Minutes]], roundResult.[[Seconds]], roundResult.[[Milliseconds]], roundResult.[[Microseconds]], roundResult.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode, zonedDateTime).
|
// 19. Let result be ? AdjustRoundedDurationDays(roundResult.[[Years]], roundResult.[[Months]], roundResult.[[Weeks]], roundResult.[[Days]], roundResult.[[Hours]], roundResult.[[Minutes]], roundResult.[[Seconds]], roundResult.[[Milliseconds]], roundResult.[[Microseconds]], roundResult.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode, zonedDateTime).
|
||||||
auto result = TRY(adjust_rounded_duration_days(global_object, round_result.years, round_result.months, round_result.weeks, round_result.days, round_result.hours, round_result.minutes, round_result.seconds, round_result.milliseconds, round_result.microseconds, round_result.nanoseconds, rounding_increment, *smallest_unit, rounding_mode, &zoned_date_time));
|
auto result = TRY(adjust_rounded_duration_days(global_object, round_result.years, round_result.months, round_result.weeks, round_result.days, round_result.hours, round_result.minutes, round_result.seconds, round_result.milliseconds, round_result.microseconds, round_result.nanoseconds, rounding_increment, *smallest_unit, rounding_mode, &zoned_date_time));
|
||||||
|
|
||||||
// 19. Return ! CreateTemporalDuration(sign × result.[[Years]], sign × result.[[Months]], sign × result.[[Weeks]], sign × result.[[Days]], sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
// 20. Return ! CreateTemporalDuration(sign × result.[[Years]], sign × result.[[Months]], sign × result.[[Weeks]], sign × result.[[Days]], sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
||||||
return MUST(create_temporal_duration(global_object, sign * result.years, sign * result.months, sign * result.weeks, sign * result.days, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
return MUST(create_temporal_duration(global_object, sign * result.years, sign * result.months, sign * result.weeks, sign * result.days, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,69 +979,62 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::round)
|
|||||||
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
round_to = TRY(get_options_object(global_object, vm.argument(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Let smallestUnit be ? ToSmallestTemporalUnit(roundTo, « "year", "month", "week" », undefined).
|
// 6. Let smallestUnit be ? GetTemporalUnit(roundTo, "smallestUnit", time, required, « "day" »).
|
||||||
auto smallest_unit_value = TRY(to_smallest_temporal_unit(global_object, *round_to, { "year"sv, "month"sv, "week"sv }, {}));
|
auto smallest_unit = TRY(get_temporal_unit(global_object, *round_to, vm.names.smallestUnit, UnitGroup::Time, TemporalUnitRequired {}, { "day"sv }));
|
||||||
|
|
||||||
// 7. If smallestUnit is undefined, throw a RangeError exception.
|
// 7. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
||||||
if (!smallest_unit_value.has_value())
|
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, vm.names.undefined.as_string(), "smallestUnit");
|
|
||||||
|
|
||||||
// NOTE: At this point smallest_unit_value can only be a string
|
|
||||||
auto& smallest_unit = *smallest_unit_value;
|
|
||||||
|
|
||||||
// 8. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"sv));
|
||||||
|
|
||||||
// 9. Let roundingIncrement be ? ToTemporalDateTimeRoundingIncrement(options, smallestUnit).
|
// 8. Let roundingIncrement be ? ToTemporalDateTimeRoundingIncrement(options, smallestUnit).
|
||||||
auto rounding_increment = TRY(to_temporal_date_time_rounding_increment(global_object, *round_to, smallest_unit));
|
auto rounding_increment = TRY(to_temporal_date_time_rounding_increment(global_object, *round_to, *smallest_unit));
|
||||||
|
|
||||||
// 10. Let timeZone be zonedDateTime.[[TimeZone]].
|
// 9. Let timeZone be zonedDateTime.[[TimeZone]].
|
||||||
auto& time_zone = zoned_date_time->time_zone();
|
auto& time_zone = zoned_date_time->time_zone();
|
||||||
|
|
||||||
// 11. Let instant be ! CreateTemporalInstant(zonedDateTime.[[Nanoseconds]]).
|
// 10. Let instant be ! CreateTemporalInstant(zonedDateTime.[[Nanoseconds]]).
|
||||||
auto* instant = MUST(create_temporal_instant(global_object, zoned_date_time->nanoseconds()));
|
auto* instant = MUST(create_temporal_instant(global_object, zoned_date_time->nanoseconds()));
|
||||||
|
|
||||||
// 12. Let calendar be zonedDateTime.[[Calendar]].
|
// 11. Let calendar be zonedDateTime.[[Calendar]].
|
||||||
auto& calendar = zoned_date_time->calendar();
|
auto& calendar = zoned_date_time->calendar();
|
||||||
|
|
||||||
// 13. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar).
|
// 12. 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));
|
||||||
|
|
||||||
// 14. Let isoCalendar be ! GetISO8601Calendar().
|
// 13. Let isoCalendar be ! GetISO8601Calendar().
|
||||||
auto* iso_calendar = get_iso8601_calendar(global_object);
|
auto* iso_calendar = get_iso8601_calendar(global_object);
|
||||||
|
|
||||||
// 15. Let dtStart be ? CreateTemporalDateTime(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], 0, 0, 0, 0, 0, 0, isoCalendar).
|
// 14. Let dtStart be ? CreateTemporalDateTime(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], 0, 0, 0, 0, 0, 0, isoCalendar).
|
||||||
auto* dt_start = TRY(create_temporal_date_time(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), 0, 0, 0, 0, 0, 0, *iso_calendar));
|
auto* dt_start = TRY(create_temporal_date_time(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), 0, 0, 0, 0, 0, 0, *iso_calendar));
|
||||||
|
|
||||||
// 16. Let instantStart be ? BuiltinTimeZoneGetInstantFor(timeZone, dtStart, "compatible").
|
// 15. Let instantStart be ? BuiltinTimeZoneGetInstantFor(timeZone, dtStart, "compatible").
|
||||||
auto* instant_start = TRY(builtin_time_zone_get_instant_for(global_object, &time_zone, *dt_start, "compatible"sv));
|
auto* instant_start = TRY(builtin_time_zone_get_instant_for(global_object, &time_zone, *dt_start, "compatible"sv));
|
||||||
|
|
||||||
// 17. Let startNs be instantStart.[[Nanoseconds]].
|
// 16. Let startNs be instantStart.[[Nanoseconds]].
|
||||||
auto& start_ns = instant_start->nanoseconds();
|
auto& start_ns = instant_start->nanoseconds();
|
||||||
|
|
||||||
// 18. Let endNs be ? AddZonedDateTime(startNs, timeZone, zonedDateTime.[[Calendar]], 0, 0, 0, 1, 0, 0, 0, 0, 0, 0).
|
// 17. Let endNs be ? AddZonedDateTime(startNs, timeZone, zonedDateTime.[[Calendar]], 0, 0, 0, 1, 0, 0, 0, 0, 0, 0).
|
||||||
// TODO: Shouldn't `zonedDateTime.[[Calendar]]` be `calendar` for consistency?
|
// TODO: Shouldn't `zonedDateTime.[[Calendar]]` be `calendar` for consistency?
|
||||||
auto* end_ns = TRY(add_zoned_date_time(global_object, start_ns, &time_zone, zoned_date_time->calendar(), 0, 0, 0, 1, 0, 0, 0, 0, 0, 0));
|
auto* end_ns = TRY(add_zoned_date_time(global_object, start_ns, &time_zone, zoned_date_time->calendar(), 0, 0, 0, 1, 0, 0, 0, 0, 0, 0));
|
||||||
|
|
||||||
// 19. Let dayLengthNs be ℝ(endNs - startNs).
|
// 18. Let dayLengthNs be ℝ(endNs - startNs).
|
||||||
auto day_length_ns = end_ns->big_integer().minus(start_ns.big_integer()).to_double();
|
auto day_length_ns = end_ns->big_integer().minus(start_ns.big_integer()).to_double();
|
||||||
|
|
||||||
// 20. If dayLengthNs is 0, then
|
// 19. If dayLengthNs is 0, then
|
||||||
if (day_length_ns == 0) {
|
if (day_length_ns == 0) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalZonedDateTimeRoundZeroLengthDay);
|
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalZonedDateTimeRoundZeroLengthDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21. Let roundResult be ! RoundISODateTime(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode, dayLengthNs).
|
// 20. Let roundResult be ! RoundISODateTime(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode, dayLengthNs).
|
||||||
auto round_result = round_iso_date_time(temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), rounding_increment, smallest_unit, rounding_mode, day_length_ns);
|
auto round_result = round_iso_date_time(temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), rounding_increment, *smallest_unit, rounding_mode, day_length_ns);
|
||||||
|
|
||||||
// 22. Let offsetNanoseconds be ? GetOffsetNanosecondsFor(timeZone, instant).
|
// 21. Let offsetNanoseconds be ? GetOffsetNanosecondsFor(timeZone, instant).
|
||||||
auto offset_nanoseconds = TRY(get_offset_nanoseconds_for(global_object, &time_zone, *instant));
|
auto offset_nanoseconds = TRY(get_offset_nanoseconds_for(global_object, &time_zone, *instant));
|
||||||
|
|
||||||
// 23. Let epochNanoseconds be ? InterpretISODateTimeOffset(roundResult.[[Year]], roundResult.[[Month]], roundResult.[[Day]], roundResult.[[Hour]], roundResult.[[Minute]], roundResult.[[Second]], roundResult.[[Millisecond]], roundResult.[[Microsecond]], roundResult.[[Nanosecond]], option, offsetNanoseconds, timeZone, "compatible", "prefer", match exactly).
|
// 22. Let epochNanoseconds be ? InterpretISODateTimeOffset(roundResult.[[Year]], roundResult.[[Month]], roundResult.[[Day]], roundResult.[[Hour]], roundResult.[[Minute]], roundResult.[[Second]], roundResult.[[Millisecond]], roundResult.[[Microsecond]], roundResult.[[Nanosecond]], option, offsetNanoseconds, timeZone, "compatible", "prefer", match exactly).
|
||||||
auto* epoch_nanoseconds = TRY(interpret_iso_date_time_offset(global_object, round_result.year, round_result.month, round_result.day, round_result.hour, round_result.minute, round_result.second, round_result.millisecond, round_result.microsecond, round_result.nanosecond, OffsetBehavior::Option, offset_nanoseconds, &time_zone, "compatible"sv, "prefer"sv, MatchBehavior::MatchExactly));
|
auto* epoch_nanoseconds = TRY(interpret_iso_date_time_offset(global_object, round_result.year, round_result.month, round_result.day, round_result.hour, round_result.minute, round_result.second, round_result.millisecond, round_result.microsecond, round_result.nanosecond, OffsetBehavior::Option, offset_nanoseconds, &time_zone, "compatible"sv, "prefer"sv, MatchBehavior::MatchExactly));
|
||||||
|
|
||||||
// 24. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar).
|
// 23. 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ describe("errors", () => {
|
|||||||
dateOne.since(dateTwo, pluralSmallestUnitOptions);
|
dateOne.since(dateTwo, pluralSmallestUnitOptions);
|
||||||
}).toThrowWithMessage(
|
}).toThrowWithMessage(
|
||||||
RangeError,
|
RangeError,
|
||||||
`${smallestUnit} is not a valid value for option smallestUnit`
|
`${smallestUnit}s is not a valid value for option smallestUnit`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ describe("errors", () => {
|
|||||||
dateOne.since(dateTwo, pluralLargestUnitOptions);
|
dateOne.since(dateTwo, pluralLargestUnitOptions);
|
||||||
}).toThrowWithMessage(
|
}).toThrowWithMessage(
|
||||||
RangeError,
|
RangeError,
|
||||||
`${largestUnit} is not a valid value for option largestUnit`
|
`${largestUnit}s is not a valid value for option largestUnit`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -170,7 +170,7 @@ describe("errors", () => {
|
|||||||
dateOne.until(dateTwo, pluralSmallestUnitOptions);
|
dateOne.until(dateTwo, pluralSmallestUnitOptions);
|
||||||
}).toThrowWithMessage(
|
}).toThrowWithMessage(
|
||||||
RangeError,
|
RangeError,
|
||||||
`${smallestUnit} is not a valid value for option smallestUnit`
|
`${smallestUnit}s is not a valid value for option smallestUnit`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ describe("errors", () => {
|
|||||||
dateOne.until(dateTwo, pluralLargestUnitOptions);
|
dateOne.until(dateTwo, pluralLargestUnitOptions);
|
||||||
}).toThrowWithMessage(
|
}).toThrowWithMessage(
|
||||||
RangeError,
|
RangeError,
|
||||||
`${largestUnit} is not a valid value for option largestUnit`
|
`${largestUnit}s is not a valid value for option largestUnit`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user