Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 43 additions & 18 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* global __debug__ */

const ArrayIncludes = Array.prototype.includes;
const ArrayPrototypeMap = Array.prototype.map;
const ArrayPrototypePush = Array.prototype.push;
const ArrayPrototypeSort = Array.prototype.sort;
const ArrayPrototypeFind = Array.prototype.find;
Expand Down Expand Up @@ -2422,6 +2423,10 @@ export function DisambiguatePossibleInstants(possibleInstants, timeZoneRec, date
const offsetBefore = GetOffsetNanosecondsFor(timeZoneRec, dayBefore);
const offsetAfter = GetOffsetNanosecondsFor(timeZoneRec, dayAfter);
const nanoseconds = offsetAfter - offsetBefore;
if (MathAbs(nanoseconds) > DAY_NANOS) {
throw new RangeError('bad return from getOffsetNanosecondsFor: UTC offset shift longer than 24 hours');
}

switch (disambiguation) {
case 'earlier': {
const norm = TimeDuration.normalize(0, 0, 0, 0, 0, -nanoseconds);
Expand Down Expand Up @@ -2479,6 +2484,17 @@ export function GetPossibleInstantsFor(timeZoneRec, dateTime) {
}
Call(ArrayPrototypePush, result, [instant]);
}

const numResults = result.length;
if (numResults > 1) {
const mapped = Call(ArrayPrototypeMap, result, [(i) => GetSlot(i, EPOCHNANOSECONDS)]);
const min = bigInt.min(...mapped);
const max = bigInt.max(...mapped);
if (bigInt(max).subtract(min).abs().greater(DAY_NANOS)) {
throw new RangeError('bad return from getPossibleInstantsFor: UTC offset shift longer than 24 hours');
}
}

return result;
}

Expand Down Expand Up @@ -3260,20 +3276,34 @@ export function NormalizedTimeDurationToDays(norm, zonedRelativeTo, timeZoneRec,
// back inside the period where it belongs. Note that this case only can
// happen for positive durations because the only direction that
// `disambiguation: 'compatible'` can change clock time is forwards.
if (sign === 1) {
while (days > 0 && relativeResult.epochNs.greater(endNs)) {
days--;
relativeResult = AddDaysToZonedDateTime(start, dtStart, timeZoneRec, calendar, days);
// may do disambiguation
if (sign === 1 && days > 0 && relativeResult.epochNs.greater(endNs)) {
days--;
relativeResult = AddDaysToZonedDateTime(start, dtStart, timeZoneRec, calendar, days);
// may do disambiguation
if (days > 0 && relativeResult.epochNs.greater(endNs)) {
throw new RangeError('inconsistent result from custom time zone getInstantFor()');
}
}
norm = TimeDuration.fromEpochNsDiff(endNs, relativeResult.epochNs);

let isOverflow = false;
let dayLengthNs;
do {
// calculate length of the next day (day that contains the time remainder)
const oneDayFarther = AddDaysToZonedDateTime(
// calculate length of the next day (day that contains the time remainder)
let oneDayFarther = AddDaysToZonedDateTime(
relativeResult.instant,
relativeResult.dateTime,
timeZoneRec,
calendar,
sign
);
let dayLengthNs = TimeDuration.fromEpochNsDiff(oneDayFarther.epochNs, relativeResult.epochNs);
const oneDayLess = norm.subtract(dayLengthNs);
let isOverflow = oneDayLess.sign() * sign >= 0;
if (isOverflow) {
norm = oneDayLess;
relativeResult = oneDayFarther;
days += sign;

// ensure there was no more overflow
oneDayFarther = AddDaysToZonedDateTime(
relativeResult.instant,
relativeResult.dateTime,
timeZoneRec,
Expand All @@ -3282,14 +3312,9 @@ export function NormalizedTimeDurationToDays(norm, zonedRelativeTo, timeZoneRec,
);

dayLengthNs = TimeDuration.fromEpochNsDiff(oneDayFarther.epochNs, relativeResult.epochNs);
const oneDayLess = norm.subtract(dayLengthNs);
isOverflow = oneDayLess.sign() * sign >= 0;
if (isOverflow) {
norm = oneDayLess;
relativeResult = oneDayFarther;
days += sign;
}
} while (isOverflow);
isOverflow = norm.subtract(dayLengthNs).sign() * sign >= 0;
if (isOverflow) throw new RangeError('inconsistent result from custom time zone getPossibleInstantsFor()');
}
if (days !== 0 && MathSign(days) != sign) {
throw new RangeError('Time zone or calendar converted nanoseconds into a number of days with the opposite sign');
}
Expand Down
2 changes: 1 addition & 1 deletion polyfill/test262
Submodule test262 updated 73 files
+48 −0 test/built-ins/Temporal/Duration/compare/relativeto-propertybag-out-of-range-backward-offset-shift.js
+43 −0 test/built-ins/Temporal/Duration/compare/relativeto-propertybag-out-of-range-forward-offset-shift.js
+29 −58 test/built-ins/Temporal/Duration/prototype/add/normalized-time-duration-to-days-loop-arbitrarily.js
+47 −0 test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-out-of-range-backward-offset-shift.js
+42 −0 test/built-ins/Temporal/Duration/prototype/add/relativeto-propertybag-out-of-range-forward-offset-shift.js
+10 −10 ...s/Temporal/Duration/prototype/add/relativeto-zoneddatetime-normalized-time-duration-to-days-range-errors.js
+28 −60 test/built-ins/Temporal/Duration/prototype/round/normalized-time-duration-to-days-loop-arbitrarily.js
+47 −0 test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-out-of-range-backward-offset-shift.js
+42 −0 test/built-ins/Temporal/Duration/prototype/round/relativeto-propertybag-out-of-range-forward-offset-shift.js
+10 −10 ...Temporal/Duration/prototype/round/relativeto-zoneddatetime-normalized-time-duration-to-days-range-errors.js
+29 −58 test/built-ins/Temporal/Duration/prototype/subtract/normalized-time-duration-to-days-loop-arbitrarily.js
+47 −0 ...built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-out-of-range-backward-offset-shift.js
+42 −0 .../built-ins/Temporal/Duration/prototype/subtract/relativeto-propertybag-out-of-range-forward-offset-shift.js
+10 −10 ...poral/Duration/prototype/subtract/relativeto-zoneddatetime-normalized-time-duration-to-days-range-errors.js
+26 −60 test/built-ins/Temporal/Duration/prototype/total/normalized-time-duration-to-days-loop-arbitrarily.js
+1 −1 test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-3.js
+47 −0 test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-out-of-range-backward-offset-shift.js
+42 −0 test/built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-out-of-range-forward-offset-shift.js
+10 −10 ...Temporal/Duration/prototype/total/relativeto-zoneddatetime-normalized-time-duration-to-days-range-errors.js
+46 −0 ...lt-ins/Temporal/PlainDate/prototype/toZonedDateTime/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...s/Temporal/PlainDate/prototype/toZonedDateTime/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 ...lt-ins/Temporal/PlainDate/prototype/toZonedDateTime/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...s/Temporal/PlainDate/prototype/toZonedDateTime/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+46 −0 ...ns/Temporal/PlainDateTime/prototype/toZonedDateTime/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...mporal/PlainDateTime/prototype/toZonedDateTime/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 ...ns/Temporal/PlainDateTime/prototype/toZonedDateTime/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...mporal/PlainDateTime/prototype/toZonedDateTime/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+46 −0 ...lt-ins/Temporal/PlainTime/prototype/toZonedDateTime/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...s/Temporal/PlainTime/prototype/toZonedDateTime/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 ...lt-ins/Temporal/PlainTime/prototype/toZonedDateTime/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...s/Temporal/PlainTime/prototype/toZonedDateTime/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+48 −0 ...built-ins/Temporal/TimeZone/prototype/getInstantFor/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+43 −0 ...-ins/Temporal/TimeZone/prototype/getInstantFor/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+52 −0 ...built-ins/Temporal/TimeZone/prototype/getInstantFor/getpossibleinstantsfor-maximum-backward-offset-shift.js
+47 −0 ...-ins/Temporal/TimeZone/prototype/getInstantFor/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+48 −0 test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-out-of-range-backward-offset-shift.js
+43 −0 test/built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-out-of-range-forward-offset-shift.js
+46 −0 test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-out-of-range-backward-offset-shift.js
+41 −0 test/built-ins/Temporal/ZonedDateTime/from/argument-propertybag-out-of-range-forward-offset-shift.js
+47 −0 ...uilt-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-out-of-range-backward-offset-shift.js
+42 −0 ...built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-out-of-range-forward-offset-shift.js
+46 −0 ...ilt-ins/Temporal/ZonedDateTime/prototype/hoursInDay/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...ns/Temporal/ZonedDateTime/prototype/hoursInDay/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 ...ilt-ins/Temporal/ZonedDateTime/prototype/hoursInDay/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...ns/Temporal/ZonedDateTime/prototype/hoursInDay/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+46 −0 test/built-ins/Temporal/ZonedDateTime/prototype/round/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...ilt-ins/Temporal/ZonedDateTime/prototype/round/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 test/built-ins/Temporal/ZonedDateTime/prototype/round/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...ilt-ins/Temporal/ZonedDateTime/prototype/round/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+47 −0 ...built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-out-of-range-backward-offset-shift.js
+42 −0 .../built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-out-of-range-forward-offset-shift.js
+25 −59 test/built-ins/Temporal/ZonedDateTime/prototype/since/normalized-time-duration-to-days-loop-arbitrarily.js
+9 −9 test/built-ins/Temporal/ZonedDateTime/prototype/since/normalized-time-duration-to-days-range-errors.js
+46 −0 ...ilt-ins/Temporal/ZonedDateTime/prototype/startOfDay/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...ns/Temporal/ZonedDateTime/prototype/startOfDay/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 ...ilt-ins/Temporal/ZonedDateTime/prototype/startOfDay/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...ns/Temporal/ZonedDateTime/prototype/startOfDay/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+47 −0 ...built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-out-of-range-backward-offset-shift.js
+42 −0 .../built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-out-of-range-forward-offset-shift.js
+25 −59 test/built-ins/Temporal/ZonedDateTime/prototype/until/normalized-time-duration-to-days-loop-arbitrarily.js
+9 −9 test/built-ins/Temporal/ZonedDateTime/prototype/until/normalized-time-duration-to-days-range-errors.js
+49 −0 test/built-ins/Temporal/ZonedDateTime/prototype/with/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+43 −0 ...uilt-ins/Temporal/ZonedDateTime/prototype/with/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+53 −0 test/built-ins/Temporal/ZonedDateTime/prototype/with/getpossibleinstantsfor-maximum-backward-offset-shift.js
+48 −0 ...uilt-ins/Temporal/ZonedDateTime/prototype/with/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+46 −0 ...-ins/Temporal/ZonedDateTime/prototype/withPlainDate/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...Temporal/ZonedDateTime/prototype/withPlainDate/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 ...-ins/Temporal/ZonedDateTime/prototype/withPlainDate/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...Temporal/ZonedDateTime/prototype/withPlainDate/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
+46 −0 ...-ins/Temporal/ZonedDateTime/prototype/withPlainTime/getoffsetnanosecondsfor-maximum-forward-offset-shift.js
+41 −0 ...Temporal/ZonedDateTime/prototype/withPlainTime/getoffsetnanosecondsfor-out-of-range-forward-offset-shift.js
+50 −0 ...-ins/Temporal/ZonedDateTime/prototype/withPlainTime/getpossibleinstantsfor-maximum-backward-offset-shift.js
+46 −0 ...Temporal/ZonedDateTime/prototype/withPlainTime/getpossibleinstantsfor-out-of-range-backward-offset-shift.js
9 changes: 9 additions & 0 deletions spec/timezone.html
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,7 @@ <h1>
1. Let _offsetBefore_ be ? GetOffsetNanosecondsFor(_timeZoneRec_, _dayBefore_).
1. Let _offsetAfter_ be ? GetOffsetNanosecondsFor(_timeZoneRec_, _dayAfter_).
1. Let _nanoseconds_ be _offsetAfter_ - _offsetBefore_.
1. If abs(_nanoseconds_) > nsPerDay, throw a *RangeError* exception.
1. If _disambiguation_ is *"earlier"*, then
1. Let _norm_ be NormalizeTimeDuration(0, 0, 0, 0, 0, -_nanoseconds_).
1. Let _earlierTime_ be AddTime(_dateTime_.[[ISOHour]], _dateTime_.[[ISOMinute]], _dateTime_.[[ISOSecond]], _dateTime_.[[ISOMillisecond]], _dateTime_.[[ISOMicrosecond]], _dateTime_.[[ISONanosecond]], _norm_).
Expand Down Expand Up @@ -978,6 +979,14 @@ <h1>
1. Repeat,
1. Let _value_ be ? IteratorStepValue(_iteratorRecord_).
1. If _value_ is ~done~, then
1. Let _numResults_ be _list_'s length.
1. If _numResults_ &gt; 1, then
1. Let _epochNs_ be a new empty List.
1. For each value _instant_ in _list_, do
1. Append _instant_.[[EpochNanoseconds]] to the end of the List _epochNs_.
1. Let _min_ be the least element of the List _epochNs_.
1. Let _max_ be the greatest element of the List _epochNs_.
1. If abs(ℝ(_max_ - _min_)) &gt; nsPerDay, throw a *RangeError* exception.
1. Return _list_.
1. If _value_ is not an Object or _value_ does not have an [[InitializedTemporalInstant]] internal slot, then
1. Let _completion_ be ThrowCompletion(a newly created *TypeError* object).
Expand Down
31 changes: 15 additions & 16 deletions spec/zoneddatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -1444,23 +1444,22 @@ <h1>
1. Else if _days_ &lt; 0 and _timeSign_ &lt; 0, then
1. Set _days_ to _days_ + 1.
1. Let _relativeResult_ be ? AddDaysToZonedDateTime(_startInstant_, _startDateTime_, _timeZoneRec_, _zonedRelativeTo_.[[Calendar]], _days_).
1. If _sign_ is 1, then
1. Repeat, while _days_ &gt; 0 and ℝ(_relativeResult_.[[EpochNanoseconds]]) &gt; _endNs_,
1. Set _days_ to _days_ - 1.
1. Set _relativeResult_ to ? AddDaysToZonedDateTime(_startInstant_, _startDateTime_, _timeZoneRec_, _zonedRelativeTo_.[[Calendar]], _days_).
1. If _sign_ = 1, and _days_ &gt; 0, and ℝ(_relativeResult_.[[EpochNanoseconds]]) &gt; _endNs_, then
1. Set _days_ to _days_ - 1.
1. Set _relativeResult_ to ? AddDaysToZonedDateTime(_startInstant_, _startDateTime_, _timeZoneRec_, _zonedRelativeTo_.[[Calendar]], _days_).
1. If _days_ &gt; 0 and ℝ(_relativeResult_.[[EpochNanoseconds]]) &gt; _endNs_, throw a *RangeError* exception.
1. Set _norm_ to NormalizedTimeDurationFromEpochNanosecondsDifference(_endNs_, _relativeResult_.[[EpochNanoseconds]]).
1. Let _done_ be *false*.
1. Let _dayLengthNs_ be ~unset~.
1. Repeat, while _done_ is *false*,
1. Let _oneDayFarther_ be ? AddDaysToZonedDateTime(_relativeResult_.[[Instant]], _relativeResult_.[[DateTime]], _timeZoneRec_, _zonedRelativeTo_.[[Calendar]], _sign_).
1. Set _dayLengthNs_ to NormalizedTimeDurationFromEpochNanosecondsDifference(_oneDayFarther_.[[EpochNanoseconds]], _relativeResult_.[[EpochNanoseconds]]).
1. Let _oneDayLess_ be ! SubtractNormalizedTimeDuration(_norm_, _dayLengthNs_).
1. If NormalizedTimeDurationSign(_oneDayLess_) &times; _sign_ &ge; 0, then
1. Set _norm_ to _oneDayLess_.
1. Set _relativeResult_ to _oneDayFarther_.
1. Set _days_ to _days_ + _sign_.
1. Else,
1. Set _done_ to *true*.
1. Let _oneDayFarther_ be ? AddDaysToZonedDateTime(_relativeResult_.[[Instant]], _relativeResult_.[[DateTime]], _timeZoneRec_, _zonedRelativeTo_.[[Calendar]], _sign_).
1. Let _dayLengthNs_ be NormalizedTimeDurationFromEpochNanosecondsDifference(_oneDayFarther.[[EpochNanoseconds]], _relativeResult_.[[EpochNanoseconds]]).
1. Let _oneDayLess_ be ! SubtractNormalizedTimeDuration(_norm_, _dayLengthNs_).
1. If NormalizedTimeDurationSign(_oneDayLess_) &times; _sign_ &ge; 0, then
1. Set _norm_ to _oneDayLess_.
1. Set _relativeResult_ to _oneDayFarther_.
1. Set _days_ to _days_ + _sign_.
1. Set _oneDayFarther_ to ? AddDaysToZonedDateTime(_relativeResult_.[[Instant]], _relativeResult_.[[DateTime]], _timeZoneRec_, _zonedRelativeTo_.[[Calendar]], _sign_).
1. Set _dayLengthNs_ to NormalizedTimeDurationFromEpochNanosecondsDifference(_oneDayFarther.[[EpochNanoseconds]], _relativeResult_.[[EpochNanoseconds]]).
1. If NormalizedTimeDurationSign(? SubtractNormalizedTimeDuration(_norm_, _dayLengthNs_)) &times; _sign_ &ge; 0, then
1. Throw a *RangeError* exception.
1. If _days_ &lt; 0 and _sign_ = 1, throw a *RangeError* exception.
1. If _days_ &gt; 0 and _sign_ = -1, throw a *RangeError* exception.
1. If NormalizedTimeDurationSign(_norm_) = -1, then
Expand Down