Skip to content

Commit

Permalink
Editorial: Adjust RangeError condition in GetPossibleEpochNanoseconds
Browse files Browse the repository at this point in the history
Similarly to the previous commit, we must avoid calling
GetUTCEpochNanoseconds with dates that are too large because it is
ill-defined in ECMA-262 what is supposed to happen. (See
tc39/ecma262#1087). Previously to PR #2925, that
could not happen because GetPossibleInstantsFor took a PlainDateTime
object, but now it takes an ISO Date-Time Record.

Note that this is editorial, because IsValidEpochNanoseconds would throw
anyway in this case even if GetUTCEpochNanoseconds was fully defined for
large inputs.
  • Loading branch information
ptomato committed Oct 1, 2024
1 parent 43bc062 commit fcc0c0f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
32 changes: 27 additions & 5 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2098,11 +2098,33 @@ export function GetPossibleEpochNanoseconds(timeZone, isoDateTime) {
const { year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = isoDateTime;
const offsetMinutes = ParseTimeZoneIdentifier(timeZone).offsetMinutes;
if (offsetMinutes !== undefined) {
return [
GetUTCEpochNanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond).subtract(
offsetMinutes * 60e9
)
];
const balanced = BalanceISODateTime(
year,
month,
day,
hour,
minute - offsetMinutes,
second,
millisecond,
microsecond,
nanosecond
);
if (MathAbs(ISODateToEpochDays(balanced.year, balanced.month - 1, balanced.day)) > 1e8) {
throw new RangeErrorCtor('date/time value is outside the supported range');
}
const epochNs = GetUTCEpochNanoseconds(
balanced.year,
balanced.month,
balanced.day,
balanced.hour,
balanced.minute,
balanced.second,
balanced.millisecond,
balanced.microsecond,
balanced.nanosecond
);
ValidateEpochNanoseconds(epochNs);
return [epochNs];
}

return GetNamedTimeZoneEpochNanoseconds(
Expand Down
5 changes: 3 additions & 2 deletions spec/timezone.html
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,9 @@ <h1>
<emu-alg>
1. Let _parseResult_ be ! ParseTimeZoneIdentifier(_timeZone_).
1. If _parseResult_.[[OffsetMinutes]] is not ~empty~, then
1. Let _offsetNanoseconds_ be _parseResult_.[[OffsetMinutes]] × (60 × 10<sup>9</sup>).
1. Let _epochNanoseconds_ be GetUTCEpochNanoseconds(_isoDateTime_.[[Year]], _isoDateTime_.[[Month]], _isoDateTime_.[[Day]], _isoDateTime_.[[Hour]], _isoDateTime_.[[Minute]], _isoDateTime_.[[Second]], _isoDateTime_.[[Millisecond]], _isoDateTime_.[[Microsecond]], _isoDateTime_.[[Nanosecond]]) - ℤ(_offsetNanoseconds_).
1. Let _balanced_ be BalanceISODateTime(_isoDateTime_.[[Year]], _isoDateTime_.[[Month]], _isoDateTime_.[[Day]], _isoDateTime_.[[Hour]], _isoDateTime_.[[Minute]] - _parseResult_.[[OffsetMinutes]], _isoDateTime_.[[Second]], _isoDateTime_.[[Millisecond]], _isoDateTime_.[[Microsecond]], _isoDateTime_.[[Nanosecond]]).
1. If abs(ISODateToEpochDays(_balanced_.[[Year]], _balanced_.[[Month]] - 1, _balanced_.[[Day]])) > 10<sup>8</sup>, throw a *RangeError* exception.
1. Let _epochNanoseconds_ be GetUTCEpochNanoseconds(_balanced_.[[Year]], _balanced_.[[Month]], _balanced_.[[Day]], _balanced_.[[Hour]], _balanced_.[[Minute]], _balanced_.[[Second]], _balanced_.[[Millisecond]], _balanced_.[[Microsecond]], _balanced_.[[Nanosecond]]).
1. Let _possibleEpochNanoseconds_ be « _epochNanoseconds_ ».
1. Else,
1. Let _possibleEpochNanoseconds_ be GetNamedTimeZoneEpochNanoseconds(_parseResult_.[[Name]], _isoDateTime_.[[Year]], _isoDateTime_.[[Month]], _isoDateTime_.[[Day]], _isoDateTime_.[[Hour]], _isoDateTime_.[[Minute]], _isoDateTime_.[[Second]], _isoDateTime_.[[Millisecond]], _isoDateTime_.[[Microsecond]], _isoDateTime_.[[Nanosecond]]).
Expand Down

0 comments on commit fcc0c0f

Please sign in to comment.