1 // |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
2 // Copyright (C) 2022 André Bargull. All rights reserved.
3 // This code is governed by the BSD license found in the LICENSE file.
5 esid: sec-temporal.duration.prototype.round
7 NormalizedTimeDurationToDays should not be able to loop arbitrarily.
9 NormalizedTimeDurationToDays ( norm, zonedRelativeTo, timeZoneRec [ , precalculatedPlainDatetime ] )
11 22. If NormalizedTimeDurationSign(_oneDayLess_) × _sign_ ≥ 0, then
12 a. Set _norm_ to _oneDayLess_.
13 b. Set _relativeResult_ to _oneDayFarther_.
14 c. Set _days_ to _days_ + _sign_.
15 d. Set _oneDayFarther_ to ? AddDaysToZonedDateTime(_relativeResult_.[[Instant]], _relativeResult_.[[DateTime]], _timeZoneRec_, _zonedRelativeTo_.[[Calendar]], _sign_).
16 e. Set dayLengthNs to NormalizedTimeDurationFromEpochNanosecondsDifference(_oneDayFarther.[[EpochNanoseconds]], relativeResult.[[EpochNanoseconds]]).
17 f. If NormalizedTimeDurationSign(? SubtractNormalizedTimeDuration(_norm_, _dayLengthNs_)) × _sign_ ≥ 0, then
18 i. Throw a *RangeError* exception.
22 const duration = Temporal.Duration.from({ days: 1 });
24 const dayLengthNs = 86400000000000n;
25 const dayInstant = new Temporal.Instant(dayLengthNs);
27 const timeZone = new class extends Temporal.TimeZone {
28 getPossibleInstantsFor() {
34 const relativeTo = new Temporal.ZonedDateTime(0n, timeZone);
36 assert.throws(RangeError, () => duration.round({ smallestUnit: "days", relativeTo }), "indefinite loop is prevented");
37 assert.sameValue(calls, 5, "getPossibleInstantsFor is not called indefinitely");
39 // RoundDuration -> MoveRelativeZonedDateTime -> AddZonedDateTime (1)
40 // BalanceTimeDurationRelative ->
41 // AddZonedDateTime (2)
42 // NormalizedTimeDurationToDays ->
43 // AddDaysToZonedDateTime (3, step 12)
44 // AddDaysToZonedDateTime (4, step 15)
45 // AddDaysToZonedDateTime (5, step 18.d)