mirror of
https://github.com/tc39/test262.git
synced 2025-07-20 20:44:43 +02:00
Temporal: Remove BigInt arithmetic and loops in UnbalanceDurationRelative
This commit is contained in:
parent
b218cf6dec
commit
50abc12d97
@ -1137,25 +1137,6 @@ var TemporalHelpers = {
|
|||||||
return new CalendarDateAddPlainDateInstance();
|
return new CalendarDateAddPlainDateInstance();
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
|
||||||
* A custom calendar that returns @returnValue from its dateUntil() method,
|
|
||||||
* recording the call in @calls.
|
|
||||||
*/
|
|
||||||
calendarDateUntilObservable(calls, returnValue) {
|
|
||||||
class CalendarDateUntilObservable extends Temporal.Calendar {
|
|
||||||
constructor() {
|
|
||||||
super("iso8601");
|
|
||||||
}
|
|
||||||
|
|
||||||
dateUntil() {
|
|
||||||
calls.push("call dateUntil");
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CalendarDateUntilObservable();
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A custom calendar that returns an iterable instead of an array from its
|
* A custom calendar that returns an iterable instead of an array from its
|
||||||
* fields() method, otherwise identical to the ISO calendar.
|
* fields() method, otherwise identical to the ISO calendar.
|
||||||
|
@ -181,14 +181,8 @@ actual.splice(0); // clear
|
|||||||
// to days:
|
// to days:
|
||||||
const expectedOpsForPlainDayBalancing = expectedOpsForPlainRelativeTo.concat(
|
const expectedOpsForPlainDayBalancing = expectedOpsForPlainRelativeTo.concat(
|
||||||
[
|
[
|
||||||
// UnbalanceDurationRelative
|
"call options.relativeTo.calendar.dateAdd", // UnbalanceDateDurationRelative on 1st argument
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate
|
"call options.relativeTo.calendar.dateAdd", // UnbalanceDateDurationRelative on 2nd argument
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate
|
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate
|
|
||||||
// UnbalanceDurationRelative again for the second argument:
|
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate
|
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate
|
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
Temporal.Duration.compare(
|
Temporal.Duration.compare(
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
|
||||||
|
|
||||||
/*---
|
|
||||||
esid: sec-temporal.duration.compare
|
|
||||||
description: >
|
|
||||||
Duration components are precise mathematical integers.
|
|
||||||
info: |
|
|
||||||
Temporal.Duration.compare ( one, two [ , options ] )
|
|
||||||
|
|
||||||
...
|
|
||||||
7. If any of one.[[Years]], two.[[Years]], one.[[Months]], two.[[Months]], one.[[Weeks]], or
|
|
||||||
two.[[Weeks]] are not 0, then
|
|
||||||
a. Let unbalanceResult1 be ? UnbalanceDurationRelative(one.[[Years]], one.[[Months]],
|
|
||||||
one.[[Weeks]], one.[[Days]], "day", relativeTo).
|
|
||||||
...
|
|
||||||
9. Let ns1 be ! TotalDurationNanoseconds(days1, one.[[Hours]], one.[[Minutes]], one.[[Seconds]],
|
|
||||||
one.[[Milliseconds]], one.[[Microseconds]], one.[[Nanoseconds]], shift1).
|
|
||||||
10. Let ns2 be ! TotalDurationNanoseconds(days2, two.[[Hours]], two.[[Minutes]], two.[[Seconds]],
|
|
||||||
two.[[Milliseconds]], two.[[Microseconds]], two.[[Nanoseconds]], shift2).
|
|
||||||
11. If ns1 > ns2, return 1𝔽.
|
|
||||||
12. If ns1 < ns2, return -1𝔽.
|
|
||||||
13. Return +0𝔽.
|
|
||||||
|
|
||||||
UnbalanceDurationRelative ( years, months, weeks, days, largestUnit, relativeTo )
|
|
||||||
|
|
||||||
...
|
|
||||||
11. Else,
|
|
||||||
a. If any of years, months, and weeks are not zero, then
|
|
||||||
...
|
|
||||||
iv. Repeat, while weeks ≠ 0,
|
|
||||||
1. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneWeek).
|
|
||||||
2. Set relativeTo to moveResult.[[RelativeTo]].
|
|
||||||
3. Set days to days + moveResult.[[Days]].
|
|
||||||
4. Set weeks to weeks - sign.
|
|
||||||
12. Return ? CreateDateDurationRecord(years, months, weeks, days).
|
|
||||||
features: [Temporal]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
var one = Temporal.Duration.from({
|
|
||||||
days: Number.MAX_SAFE_INTEGER,
|
|
||||||
weeks: 3,
|
|
||||||
});
|
|
||||||
|
|
||||||
var two = Temporal.Duration.from({
|
|
||||||
days: Number.MAX_SAFE_INTEGER + 3,
|
|
||||||
weeks: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
var cal = new class extends Temporal.Calendar {
|
|
||||||
dateAdd(date, duration, options) {
|
|
||||||
// Add one day when one week was requested.
|
|
||||||
if (duration.toString() === "P1W") {
|
|
||||||
return super.dateAdd(date, "P1D", options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only expect to add one week.
|
|
||||||
throw new Test262Error("dateAdd called with unexpected value");
|
|
||||||
}
|
|
||||||
}("iso8601");
|
|
||||||
|
|
||||||
var pd = new Temporal.PlainDate(1970, 1, 1, cal);
|
|
||||||
|
|
||||||
// |Number.MAX_SAFE_INTEGER + 1 + 1 + 1| is unequal to |Number.MAX_SAFE_INTEGER + 3|
|
|
||||||
// when the addition is performed using IEEE-754 semantics. But for compare we have
|
|
||||||
// to ensure exact mathematical computations are performed.
|
|
||||||
|
|
||||||
assert.sameValue(Temporal.Duration.compare(one, two, {relativeTo: pd}), 0);
|
|
@ -1,69 +0,0 @@
|
|||||||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
|
||||||
|
|
||||||
/*---
|
|
||||||
esid: sec-temporal.duration.compare
|
|
||||||
description: >
|
|
||||||
Duration components are precise mathematical integers.
|
|
||||||
info: |
|
|
||||||
Temporal.Duration.compare ( one, two [ , options ] )
|
|
||||||
|
|
||||||
...
|
|
||||||
7. If any of one.[[Years]], two.[[Years]], one.[[Months]], two.[[Months]], one.[[Weeks]], or
|
|
||||||
two.[[Weeks]] are not 0, then
|
|
||||||
a. Let unbalanceResult1 be ? UnbalanceDurationRelative(one.[[Years]], one.[[Months]],
|
|
||||||
one.[[Weeks]], one.[[Days]], "day", relativeTo).
|
|
||||||
...
|
|
||||||
9. Let ns1 be ! TotalDurationNanoseconds(days1, one.[[Hours]], one.[[Minutes]], one.[[Seconds]],
|
|
||||||
one.[[Milliseconds]], one.[[Microseconds]], one.[[Nanoseconds]], shift1).
|
|
||||||
10. Let ns2 be ! TotalDurationNanoseconds(days2, two.[[Hours]], two.[[Minutes]], two.[[Seconds]],
|
|
||||||
two.[[Milliseconds]], two.[[Microseconds]], two.[[Nanoseconds]], shift2).
|
|
||||||
11. If ns1 > ns2, return 1𝔽.
|
|
||||||
12. If ns1 < ns2, return -1𝔽.
|
|
||||||
13. Return +0𝔽.
|
|
||||||
|
|
||||||
UnbalanceDurationRelative ( years, months, weeks, days, largestUnit, relativeTo )
|
|
||||||
|
|
||||||
...
|
|
||||||
11. Else,
|
|
||||||
a. If any of years, months, and weeks are not zero, then
|
|
||||||
...
|
|
||||||
iv. Repeat, while weeks ≠ 0,
|
|
||||||
1. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneWeek).
|
|
||||||
2. Set relativeTo to moveResult.[[RelativeTo]].
|
|
||||||
3. Set days to days + moveResult.[[Days]].
|
|
||||||
4. Set weeks to weeks - sign.
|
|
||||||
12. Return ? CreateDateDurationRecord(years, months, weeks, days).
|
|
||||||
features: [Temporal]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
var one = Temporal.Duration.from({
|
|
||||||
days: Number.MAX_SAFE_INTEGER,
|
|
||||||
weeks: 3,
|
|
||||||
years: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
var two = Temporal.Duration.from({
|
|
||||||
days: Number.MAX_SAFE_INTEGER + 3,
|
|
||||||
years: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
var cal = new class extends Temporal.Calendar {
|
|
||||||
dateAdd(date, duration, options) {
|
|
||||||
// Add one day when one week was requested.
|
|
||||||
if (duration.toString() === "P1W") {
|
|
||||||
return super.dateAdd(date, "P1D", options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use zero duration to avoid a RangeError during CalculateOffsetShift.
|
|
||||||
return super.dateAdd(date, "PT0S", options);
|
|
||||||
}
|
|
||||||
}("iso8601");
|
|
||||||
|
|
||||||
var zdt = new Temporal.ZonedDateTime(0n, "UTC", cal);
|
|
||||||
|
|
||||||
// |Number.MAX_SAFE_INTEGER + 1 + 1 + 1| is unequal to |Number.MAX_SAFE_INTEGER + 3|
|
|
||||||
// when the addition is performed using IEEE-754 semantics. But for compare we have
|
|
||||||
// to ensure exact mathematical computations are performed.
|
|
||||||
|
|
||||||
assert.sameValue(Temporal.Duration.compare(one, two, {relativeTo: zdt}), 0);
|
|
@ -6,22 +6,17 @@ esid: sec-temporal.duration.prototype.round
|
|||||||
description: The options object passed to calendar.dateUntil has a largestUnit property with its value in the singular form
|
description: The options object passed to calendar.dateUntil has a largestUnit property with its value in the singular form
|
||||||
info: |
|
info: |
|
||||||
sec-temporal.duration.prototype.round steps 23–27:
|
sec-temporal.duration.prototype.round steps 23–27:
|
||||||
23. Let _unbalanceResult_ be ? UnbalanceDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _relativeTo_).
|
23. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _relativeTo_).
|
||||||
24. Let _roundResult_ be (? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_)).[[DurationRecord]].
|
24. Let _roundResult_ be (? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_)).[[DurationRecord]].
|
||||||
25. Let _adjustResult_ 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_, _relativeTo_).
|
25. Let _adjustResult_ 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_, _relativeTo_).
|
||||||
26. Let _balanceResult_ be ? BalanceDuration(_adjustResult_.[[Days]], _adjustResult_.[[Hours]], _adjustResult_.[[Minutes]], _adjustResult_.[[Seconds]], _adjustResult_.[[Milliseconds]], _adjustResult_.[[Microseconds]], _adjustResult_.[[Nanoseconds]], _largestUnit_, _relativeTo_).
|
26. Let _balanceResult_ be ? BalanceDuration(_adjustResult_.[[Days]], _adjustResult_.[[Hours]], _adjustResult_.[[Minutes]], _adjustResult_.[[Seconds]], _adjustResult_.[[Milliseconds]], _adjustResult_.[[Microseconds]], _adjustResult_.[[Nanoseconds]], _largestUnit_, _relativeTo_).
|
||||||
27. Let _result_ be ? BalanceDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]], _adjustResult_.[[Weeks]], _balanceResult_.[[Days]], _largestUnit_, _relativeTo_).
|
27. Let _result_ be ? BalanceDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]], _adjustResult_.[[Weeks]], _balanceResult_.[[Days]], _largestUnit_, _relativeTo_).
|
||||||
sec-temporal-unbalancedurationrelative steps 1 and 9.d.iii–v:
|
sec-temporal-unbalancedatedurationrelative step 3:
|
||||||
1. If _largestUnit_ is *"year"*, or _years_, _months_, _weeks_, and _days_ are all 0, then
|
3. If _largestUnit_ is *"month"*, then
|
||||||
a. Return ...
|
|
||||||
...
|
|
||||||
9. If _largestUnit_ is *"month"*, then
|
|
||||||
...
|
...
|
||||||
d. Repeat, while abs(_years_) > 0,
|
g. Let _untilOptions_ be ! OrdinaryObjectCreate(*null*).
|
||||||
...
|
h. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
|
||||||
iii. Let _untilOptions_ be ! OrdinaryObjectCreate(*null*).
|
i. Let _untilResult_ be ? CalendarDateUntil(_calendarRec_.[[Receiver]], _plainRelativeTo_, _later_, _untilOptions_, _calendarRec_.[[DateUntil]]).
|
||||||
iv. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
|
|
||||||
v. Let _untilResult_ be ? CalendarDateUntil(_calendar_, _relativeTo_, _newRelativeTo_, _untilOptions_, _dateUntil_).
|
|
||||||
sec-temporal-roundduration steps 5.d and 8.n–p:
|
sec-temporal-roundduration steps 5.d and 8.n–p:
|
||||||
5. If _unit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
|
5. If _unit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
|
||||||
...
|
...
|
||||||
@ -128,7 +123,7 @@ TemporalHelpers.checkCalendarDateUntilLargestUnitSingular(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
years: ["month", "month", "month", "month", "month", "month"],
|
years: ["month", "month", "month", "month", "month", "month"],
|
||||||
months: ["month", "month", "month", "month", "month"],
|
months: ["month"],
|
||||||
weeks: [],
|
weeks: [],
|
||||||
days: [],
|
days: [],
|
||||||
hours: [],
|
hours: [],
|
||||||
|
@ -10,19 +10,25 @@ includes: [compareArray.js, temporalHelpers.js]
|
|||||||
features: [Temporal]
|
features: [Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// One path, through UnbalanceDurationRelative, calls dateUntil() in a loop for
|
|
||||||
// each year in the duration
|
|
||||||
|
|
||||||
const actual = [];
|
const actual = [];
|
||||||
|
|
||||||
|
class CalendarDateUntilObservable extends Temporal.Calendar {
|
||||||
|
dateUntil(...args) {
|
||||||
|
actual.push("call dateUntil");
|
||||||
|
const returnValue = super.dateUntil(...args);
|
||||||
|
TemporalHelpers.observeProperty(actual, returnValue, "months", Infinity);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const calendar = new CalendarDateUntilObservable("iso8601");
|
||||||
|
const relativeTo = new Temporal.PlainDate(2018, 10, 12, calendar);
|
||||||
|
|
||||||
|
// One path, through UnbalanceDateDurationRelative, calls dateUntil()
|
||||||
|
|
||||||
const expected1 = [
|
const expected1 = [
|
||||||
"call dateUntil",
|
"call dateUntil",
|
||||||
"call dateUntil",
|
|
||||||
];
|
];
|
||||||
const duration = new Temporal.Duration(0, 12);
|
|
||||||
TemporalHelpers.observeProperty(actual, duration, "months", 1);
|
|
||||||
|
|
||||||
const calendar = TemporalHelpers.calendarDateUntilObservable(actual, duration);
|
|
||||||
const relativeTo = new Temporal.PlainDateTime(2018, 10, 12, 0, 0, 0, 0, 0, 0, calendar);
|
|
||||||
|
|
||||||
const years = new Temporal.Duration(2);
|
const years = new Temporal.Duration(2);
|
||||||
const result1 = years.round({ largestUnit: "months", relativeTo });
|
const result1 = years.round({ largestUnit: "months", relativeTo });
|
||||||
|
@ -151,9 +151,9 @@ actual.splice(0); // clear
|
|||||||
|
|
||||||
// code path through Duration.prototype.round that rounds to the nearest month:
|
// code path through Duration.prototype.round that rounds to the nearest month:
|
||||||
const expectedOpsForMonthRounding = expectedOpsForPlainRelativeTo.concat([
|
const expectedOpsForMonthRounding = expectedOpsForPlainRelativeTo.concat([
|
||||||
// UnbalanceDurationRelative
|
// UnbalanceDateDurationRelative
|
||||||
"call options.relativeTo.calendar.dateAdd", // 9.d.i
|
"call options.relativeTo.calendar.dateAdd", // 3.f
|
||||||
"call options.relativeTo.calendar.dateUntil", // 9.d.iv
|
"call options.relativeTo.calendar.dateUntil", // 3.i
|
||||||
// RoundDuration
|
// RoundDuration
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.c
|
"call options.relativeTo.calendar.dateAdd", // 10.c
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.e
|
"call options.relativeTo.calendar.dateAdd", // 10.e
|
||||||
@ -169,9 +169,8 @@ actual.splice(0); // clear
|
|||||||
|
|
||||||
// code path through Duration.prototype.round that rounds to the nearest week:
|
// code path through Duration.prototype.round that rounds to the nearest week:
|
||||||
const expectedOpsForWeekRounding = expectedOpsForPlainRelativeTo.concat([
|
const expectedOpsForWeekRounding = expectedOpsForPlainRelativeTo.concat([
|
||||||
// UnbalanceDurationRelative
|
// UnbalanceDateDurationRelative
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.c.i MoveRelativeDate
|
"call options.relativeTo.calendar.dateAdd", // 4.e
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.d.i MoveRelativeDate
|
|
||||||
// RoundDuration
|
// RoundDuration
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.d MoveRelativeDate
|
"call options.relativeTo.calendar.dateAdd", // 11.d MoveRelativeDate
|
||||||
], Array(58).fill("call options.relativeTo.calendar.dateAdd"), [ // 58× 11.g.iii MoveRelativeDate (52 + 4 + 2)
|
], Array(58).fill("call options.relativeTo.calendar.dateAdd"), [ // 58× 11.g.iii MoveRelativeDate (52 + 4 + 2)
|
||||||
@ -185,9 +184,7 @@ actual.splice(0); // clear
|
|||||||
|
|
||||||
// code path through UnbalanceDurationRelative that rounds to the nearest day:
|
// code path through UnbalanceDurationRelative that rounds to the nearest day:
|
||||||
const expectedOpsForDayRounding = expectedOpsForPlainRelativeTo.concat([
|
const expectedOpsForDayRounding = expectedOpsForPlainRelativeTo.concat([
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate
|
"call options.relativeTo.calendar.dateAdd", // 9
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate
|
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate
|
|
||||||
]);
|
]);
|
||||||
const instance4 = new Temporal.Duration(1, 1, 1)
|
const instance4 = new Temporal.Duration(1, 1, 1)
|
||||||
instance4.round(createOptionsObserver({ largestUnit: "days", smallestUnit: "days", relativeTo: plainRelativeTo }));
|
instance4.round(createOptionsObserver({ largestUnit: "days", smallestUnit: "days", relativeTo: plainRelativeTo }));
|
||||||
@ -427,7 +424,7 @@ const expectedOpsForUnbalanceRoundBalance = expectedOpsForZonedRelativeTo.concat
|
|||||||
// lookup in Duration.p.round
|
// lookup in Duration.p.round
|
||||||
"get options.relativeTo.calendar.dateAdd",
|
"get options.relativeTo.calendar.dateAdd",
|
||||||
"get options.relativeTo.calendar.dateUntil",
|
"get options.relativeTo.calendar.dateUntil",
|
||||||
// No user code calls in UnbalanceDurationRelative
|
// No user code calls in UnbalanceDateDurationRelative
|
||||||
// RoundDuration → MoveRelativeZonedDateTime → AddZonedDateTime
|
// RoundDuration → MoveRelativeZonedDateTime → AddZonedDateTime
|
||||||
"call options.relativeTo.calendar.dateAdd",
|
"call options.relativeTo.calendar.dateAdd",
|
||||||
"call options.relativeTo.timeZone.getPossibleInstantsFor", // 13. GetInstantFor
|
"call options.relativeTo.timeZone.getPossibleInstantsFor", // 13. GetInstantFor
|
||||||
|
@ -15,16 +15,13 @@ const timeZone = TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 3600
|
|||||||
const relativeTo = new Temporal.ZonedDateTime(0n, timeZone, calendar);
|
const relativeTo = new Temporal.ZonedDateTime(0n, timeZone, calendar);
|
||||||
|
|
||||||
// Total of a calendar unit where larger calendar units have to be converted
|
// Total of a calendar unit where larger calendar units have to be converted
|
||||||
// down, to cover the path that goes through UnbalanceDurationRelative
|
// down, to cover the path that goes through UnbalanceDateDurationRelative
|
||||||
// The calls come from these paths:
|
// The calls come from the path:
|
||||||
// Duration.total() ->
|
// Duration.total() -> UnbalanceDateDurationRelative -> calendar.dateAdd()
|
||||||
// UnbalanceDurationRelative -> MoveRelativeDate -> calendar.dateAdd() (3x)
|
|
||||||
// BalanceDuration ->
|
|
||||||
// AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd()
|
|
||||||
|
|
||||||
const instance1 = new Temporal.Duration(1, 1, 1, 1, 1);
|
const instance1 = new Temporal.Duration(1, 1, 1, 1, 1);
|
||||||
instance1.total({ unit: "days", relativeTo });
|
instance1.total({ unit: "days", relativeTo });
|
||||||
assert.sameValue(calendar.dateAddCallCount, 3, "converting larger calendar units down");
|
assert.sameValue(calendar.dateAddCallCount, 1, "converting larger calendar units down");
|
||||||
|
|
||||||
// Total of a calendar unit where smaller calendar units have to be converted
|
// Total of a calendar unit where smaller calendar units have to be converted
|
||||||
// up, to cover the path that goes through MoveRelativeZonedDateTime
|
// up, to cover the path that goes through MoveRelativeZonedDateTime
|
||||||
|
@ -6,21 +6,16 @@ esid: sec-temporal.duration.prototype.total
|
|||||||
description: The options object passed to calendar.dateUntil has a largestUnit property with its value in the singular form
|
description: The options object passed to calendar.dateUntil has a largestUnit property with its value in the singular form
|
||||||
info: |
|
info: |
|
||||||
sec-temporal.duration.prototype.total steps 7–11:
|
sec-temporal.duration.prototype.total steps 7–11:
|
||||||
7. Let _unbalanceResult_ be ? UnbalanceDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _unit_, _relativeTo_).
|
7. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _unit_, _relativeTo_).
|
||||||
...
|
...
|
||||||
10. Let _balanceResult_ be ? BalanceDuration(_unbalanceResult_.[[Days]], _unbalanceResult_.[[Hours]], _unbalanceResult_.[[Minutes]], _unbalanceResult_.[[Seconds]], _unbalanceResult_.[[Milliseconds]], _unbalanceResult_.[[Microseconds]], _unbalanceResult_.[[Nanoseconds]], _unit_, _intermediate_).
|
10. Let _balanceResult_ be ? BalanceDuration(_unbalanceResult_.[[Days]], _unbalanceResult_.[[Hours]], _unbalanceResult_.[[Minutes]], _unbalanceResult_.[[Seconds]], _unbalanceResult_.[[Milliseconds]], _unbalanceResult_.[[Microseconds]], _unbalanceResult_.[[Nanoseconds]], _unit_, _intermediate_).
|
||||||
11. Let _roundResult_ 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_).
|
11. Let _roundResult_ 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_).
|
||||||
sec-temporal-unbalancedurationrelative steps 1 and 9.d.iii–v:
|
sec-temporal-unbalancedatedurationrelative step 3:
|
||||||
1. If _largestUnit_ is *"year"*, or _years_, _months_, _weeks_, and _days_ are all 0, then
|
3. If _largestUnit_ is *"month"*, then
|
||||||
a. Return ...
|
|
||||||
...
|
|
||||||
9. If _largestUnit_ is *"month"*, then
|
|
||||||
...
|
...
|
||||||
d. Repeat, while abs(_years_) > 0,
|
g. Let _untilOptions_ be ! OrdinaryObjectCreate(*null*).
|
||||||
...
|
h. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
|
||||||
iii. Let _untilOptions_ be ! OrdinaryObjectCreate(*null*).
|
i. Let _untilResult_ be ? CalendarDateUntil(_calendarRec_.[[Receiver]], _plainRelativeTo_, _later_, _untilOptions_, _calendarRec_.[[DateUntil]]).
|
||||||
iv. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
|
|
||||||
v. Let _untilResult_ be ? CalendarDateUntil(_calendar_, _relativeTo_, _newRelativeTo_, _untilOptions_, _dateUntil_).
|
|
||||||
sec-temporal-balanceduration step 3.a:
|
sec-temporal-balanceduration step 3.a:
|
||||||
3. If _largestUnit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
|
3. If _largestUnit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
|
||||||
a. Let _result_ be ? NanosecondsToDays(_nanoseconds_, _relativeTo_).
|
a. Let _result_ be ? NanosecondsToDays(_nanoseconds_, _relativeTo_).
|
||||||
@ -79,7 +74,7 @@ TemporalHelpers.checkCalendarDateUntilLargestUnitSingular(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
years: ["year"],
|
years: ["year"],
|
||||||
months: ["month", "month", "month", "month", "month"],
|
months: ["month"],
|
||||||
weeks: [],
|
weeks: [],
|
||||||
days: [],
|
days: [],
|
||||||
hours: [],
|
hours: [],
|
||||||
|
@ -11,17 +11,23 @@ features: [Temporal]
|
|||||||
---*/
|
---*/
|
||||||
|
|
||||||
const actual = [];
|
const actual = [];
|
||||||
|
|
||||||
|
class CalendarDateUntilObservable extends Temporal.Calendar {
|
||||||
|
dateUntil(...args) {
|
||||||
|
actual.push("call dateUntil");
|
||||||
|
const returnValue = super.dateUntil(...args);
|
||||||
|
TemporalHelpers.observeProperty(actual, returnValue, "months", Infinity);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const calendar = new CalendarDateUntilObservable("iso8601");
|
||||||
|
const relativeTo = new Temporal.PlainDate(2018, 10, 12, calendar);
|
||||||
|
|
||||||
const expected = [
|
const expected = [
|
||||||
"call dateUntil",
|
"call dateUntil",
|
||||||
"call dateUntil",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const duration = new Temporal.Duration(0, 12);
|
|
||||||
TemporalHelpers.observeProperty(actual, duration, "months", 1);
|
|
||||||
|
|
||||||
const calendar = TemporalHelpers.calendarDateUntilObservable(actual, duration);
|
|
||||||
const relativeTo = new Temporal.PlainDateTime(2018, 10, 12, 0, 0, 0, 0, 0, 0, calendar);
|
|
||||||
|
|
||||||
const years = new Temporal.Duration(2);
|
const years = new Temporal.Duration(2);
|
||||||
const result = years.total({ unit: "months", relativeTo });
|
const result = years.total({ unit: "months", relativeTo });
|
||||||
assert.sameValue(result, 24, "result");
|
assert.sameValue(result, 24, "result");
|
||||||
|
@ -129,9 +129,9 @@ actual.splice(0); // clear
|
|||||||
|
|
||||||
// code path through Duration.prototype.total that rounds to the nearest month:
|
// code path through Duration.prototype.total that rounds to the nearest month:
|
||||||
const expectedOpsForMonthRounding = expectedOpsForPlainRelativeTo.concat([
|
const expectedOpsForMonthRounding = expectedOpsForPlainRelativeTo.concat([
|
||||||
// UnbalanceDurationRelative
|
// UnbalanceDateDurationRelative
|
||||||
"call options.relativeTo.calendar.dateAdd", // 9.d.i
|
"call options.relativeTo.calendar.dateAdd", // 3.f
|
||||||
"call options.relativeTo.calendar.dateUntil", // 9.d.iv
|
"call options.relativeTo.calendar.dateUntil", // 3.i
|
||||||
// RoundDuration
|
// RoundDuration
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.c
|
"call options.relativeTo.calendar.dateAdd", // 10.c
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.e
|
"call options.relativeTo.calendar.dateAdd", // 10.e
|
||||||
@ -144,9 +144,8 @@ actual.splice(0); // clear
|
|||||||
|
|
||||||
// code path through Duration.prototype.total that rounds to the nearest week:
|
// code path through Duration.prototype.total that rounds to the nearest week:
|
||||||
const expectedOpsForWeekRounding = expectedOpsForPlainRelativeTo.concat([
|
const expectedOpsForWeekRounding = expectedOpsForPlainRelativeTo.concat([
|
||||||
// UnbalanceDurationRelative
|
// UnbalanceDateDurationRelative
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.c.i MoveRelativeDate
|
"call options.relativeTo.calendar.dateAdd", // 4.e
|
||||||
"call options.relativeTo.calendar.dateAdd", // 10.d.i MoveRelativeDate
|
|
||||||
// RoundDuration
|
// RoundDuration
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.d MoveRelativeDate
|
"call options.relativeTo.calendar.dateAdd", // 11.d MoveRelativeDate
|
||||||
], Array(58).fill("call options.relativeTo.calendar.dateAdd")); // 58× 11.g.iii MoveRelativeDate (52 + 4 + 2)
|
], Array(58).fill("call options.relativeTo.calendar.dateAdd")); // 58× 11.g.iii MoveRelativeDate (52 + 4 + 2)
|
||||||
@ -155,11 +154,9 @@ instance3.total(createOptionsObserver({ unit: "weeks", relativeTo: plainRelative
|
|||||||
assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with unit = weeks");
|
assert.compareArray(actual, expectedOpsForWeekRounding, "order of operations with unit = weeks");
|
||||||
actual.splice(0); // clear
|
actual.splice(0); // clear
|
||||||
|
|
||||||
// code path through UnbalanceDurationRelative that rounds to the nearest day:
|
// code path through UnbalanceDateDurationRelative that rounds to the nearest day:
|
||||||
const expectedOpsForDayRounding = expectedOpsForPlainRelativeTo.concat([
|
const expectedOpsForDayRounding = expectedOpsForPlainRelativeTo.concat([
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate
|
"call options.relativeTo.calendar.dateAdd", // 10
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate
|
|
||||||
"call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate
|
|
||||||
]);
|
]);
|
||||||
const instance4 = new Temporal.Duration(1, 1, 1)
|
const instance4 = new Temporal.Duration(1, 1, 1)
|
||||||
instance4.total(createOptionsObserver({ unit: "days", relativeTo: plainRelativeTo }));
|
instance4.total(createOptionsObserver({ unit: "days", relativeTo: plainRelativeTo }));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user