Skip to content

Commit

Permalink
Normative: Handle days overflow in BalancePossiblyInfiniteTimeDuratio…
Browse files Browse the repository at this point in the history
…nRelative

Return an overflow marker when `𝔽(days)` is infinite. Strictly speaking
a normative change, but can only happen when there are over 1e292
iterations in NanosecondsToDays.

When passing a finite `𝔽(days)` to CreateTimeDurationRecord,
CreateTimeDurationRecord can't fail anymore, so it's now marked as
infallible.

Example how to trigger infinite days in theory:
```js
let cal = new class extends Temporal.Calendar {
  #dateUntil = 0;

  dateUntil(one, two, options) {
    if (this.#dateUntil++ === 0) {
      return Temporal.Duration.from({days: Number.MAX_VALUE})
    }
    return super.dateUntil(one, two, options);
  }

  #dateAdd = 0;

  dateAdd(date, duration, options) {
    if (this.#dateAdd++ === 0) {
      return date;
    }
    if (duration.days > 1) {
      return date;
    }
    return super.dateAdd(date, duration, options)
  }
}("iso8601");

let tz = new class extends Temporal.TimeZone {
  #getPossibleInstantsFor = 0n;

  getPossibleInstantsFor(dateTime) {
    if (this.#getPossibleInstantsFor++ < 10n**292n) {
      return [new Temporal.Instant(0n)];
    }
    return super.getPossibleInstantsFor(dateTime);
  }
}("UTC");

let zdt = new Temporal.ZonedDateTime(0n, tz, cal);
let d = Temporal.Duration.from({nanoseconds: 1});
let r = d.total({unit: "days", relativeTo: zdt})
```
  • Loading branch information
anba committed Jun 19, 2023
1 parent c570534 commit bbeeee4
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion spec/duration.html
Original file line number Diff line number Diff line change
Expand Up @@ -1353,9 +1353,12 @@ <h1>
1. Set _largestUnit_ to *"hour"*.
1. Else,
1. Set _days_ to 0.
1. If 𝔽(_days_) is not finite, then
1. If _days_ &gt; 0, return ~positive overflow~.
1. Else, return ~negative overflow~.
1. Let _balanceResult_ be BalancePossiblyInfiniteTimeDuration(0, 0, 0, 0, 0, 0, _result_.[[Nanoseconds]], _largestUnit_).
1. If _balanceResult_ is ~positive overflow~ or ~negative overflow~, return _balanceResult_.
1. Return ? CreateTimeDurationRecord(_days_, _balanceResult_.[[Hours]], _balanceResult_.[[Minutes]], _balanceResult_.[[Seconds]], _balanceResult_.[[Milliseconds]], _balanceResult_.[[Microseconds]], _balanceResult_.[[Nanoseconds]]).
1. Return ! CreateTimeDurationRecord(_days_, _balanceResult_.[[Hours]], _balanceResult_.[[Minutes]], _balanceResult_.[[Seconds]], _balanceResult_.[[Milliseconds]], _balanceResult_.[[Microseconds]], _balanceResult_.[[Nanoseconds]]).
</emu-alg>
</emu-clause>

Expand Down

0 comments on commit bbeeee4

Please sign in to comment.