Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editorial: Follow up suggestions from Justin #3006

Merged
merged 3 commits into from
Oct 9, 2024
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
57 changes: 30 additions & 27 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1301,9 +1301,7 @@ export function ToTemporalInstant(item) {
microsecond,
nanosecond - offsetNanoseconds
);
if (MathAbs(ISODateToEpochDays(balanced.isoDate.year, balanced.isoDate.month - 1, balanced.isoDate.day)) > 1e8) {
throw new RangeErrorCtor('date/time value is outside the supported range');
}
CheckISODaysRange(balanced.isoDate);
const epochNanoseconds = GetUTCEpochNanoseconds(balanced);
ValidateEpochNanoseconds(epochNanoseconds);
return new TemporalInstant(epochNanoseconds);
Expand Down Expand Up @@ -1441,17 +1439,13 @@ export function InterpretISODateTimeOffset(
time.microsecond,
time.nanosecond - offsetNs
);
if (MathAbs(ISODateToEpochDays(balanced.year, balanced.month - 1, balanced.day)) > 1e8) {
throw new RangeErrorCtor('date/time outside of supported range');
}
CheckISODaysRange(balanced.isoDate);
const epochNs = GetUTCEpochNanoseconds(balanced);
ValidateEpochNanoseconds(epochNs);
return epochNs;
}

if (MathAbs(ISODateToEpochDays(isoDate.year, isoDate.month - 1, isoDate.day)) > 1e8) {
throw new RangeErrorCtor('date/time outside of supported range');
}
CheckISODaysRange(isoDate);
const utcEpochNs = GetUTCEpochNanoseconds(dt);

// "prefer" or "reject"
Expand Down Expand Up @@ -1936,19 +1930,13 @@ export function GetPossibleEpochNanoseconds(timeZone, isoDateTime) {
isoDateTime.time.microsecond,
isoDateTime.time.nanosecond
);
if (MathAbs(ISODateToEpochDays(balanced.isoDate.year, balanced.isoDate.month - 1, balanced.isoDate.day)) > 1e8) {
throw new RangeErrorCtor('date/time value is outside the supported range');
}
CheckISODaysRange(balanced.isoDate);
const epochNs = GetUTCEpochNanoseconds(balanced);
ValidateEpochNanoseconds(epochNs);
return [epochNs];
}

if (
MathAbs(ISODateToEpochDays(isoDateTime.isoDate.year, isoDateTime.isoDate.month - 1, isoDateTime.isoDate.day)) > 1e8
) {
throw new RangeErrorCtor('date/time value is outside the supported range');
}
CheckISODaysRange(isoDateTime.isoDate);
return GetNamedTimeZoneEpochNanoseconds(timeZone, isoDateTime);
}

Expand Down Expand Up @@ -2291,7 +2279,7 @@ function GetNamedTimeZoneOffsetNanosecondsImpl(id, epochMilliseconds) {
const { year, month, day, hour, minute, second } = GetFormatterParts(id, epochMilliseconds);
let millisecond = epochMilliseconds % 1000;
if (millisecond < 0) millisecond += 1000;
const utc = GetUTCEpochMilliseconds(year, month, day, hour, minute, second, millisecond);
const utc = GetUTCEpochMilliseconds({ isoDate: { year, month, day }, time: { hour, minute, second, millisecond } });
return (utc - epochMilliseconds) * 1e6;
}

Expand All @@ -2316,7 +2304,10 @@ export function FormatDateTimeUTCOffsetRounded(offsetNanoseconds) {
return FormatOffsetTimeZoneIdentifier(offsetNanoseconds / 60e9);
}

function GetUTCEpochMilliseconds(year, month, day, hour, minute, second, millisecond) {
function GetUTCEpochMilliseconds({
isoDate: { year, month, day },
time: { hour, minute, second, millisecond /* ignored: microsecond, nanosecond */ }
}) {
// The pattern of leap years in the ISO 8601 calendar repeats every 400
// years. To avoid overflowing at the edges of the range, we reduce the year
// to the remainder after dividing by 400, and then add back all the
Expand All @@ -2333,12 +2324,9 @@ function GetUTCEpochMilliseconds(year, month, day, hour, minute, second, millise
return ms + MS_IN_400_YEAR_CYCLE * yearCycles;
}

function GetUTCEpochNanoseconds({
isoDate: { year, month, day },
time: { hour, minute, second, millisecond, microsecond, nanosecond }
}) {
const ms = GetUTCEpochMilliseconds(year, month, day, hour, minute, second, millisecond);
const subMs = microsecond * 1e3 + nanosecond;
function GetUTCEpochNanoseconds(isoDateTime) {
const ms = GetUTCEpochMilliseconds(isoDateTime);
const subMs = isoDateTime.time.microsecond * 1e3 + isoDateTime.time.nanosecond;
return bigInt(ms).multiply(1e6).plus(subMs);
}

Expand Down Expand Up @@ -2974,8 +2962,23 @@ function CombineDateAndNormalizedTimeDuration(dateDuration, norm) {
}

// Caution: month is 0-based
export function ISODateToEpochDays(y, m, d) {
return GetUTCEpochMilliseconds(y, m + 1, d, 0, 0, 0, 0) / DAY_MS;
export function ISODateToEpochDays(year, month, day) {
return (
GetUTCEpochMilliseconds({
isoDate: { year, month: month + 1, day },
time: { hour: 0, minute: 0, second: 0, millisecond: 0 }
}) / DAY_MS
);
}

// This is needed before calling GetUTCEpochNanoseconds, because it uses MakeDay
// which is ill-defined in how it handles large year numbers. If the issue
// https://github.com/tc39/ecma262/issues/1087 is fixed, this can be removed
// with no observable changes.
function CheckISODaysRange({ year, month, day }) {
if (MathAbs(ISODateToEpochDays(year, month - 1, day)) > 1e8) {
throw new RangeErrorCtor('date/time value is outside the supported range');
}
}

function DifferenceTime(time1, time2) {
Expand Down
7 changes: 1 addition & 6 deletions polyfill/lib/plaindatetime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,7 @@ export class PlainDateTime {
const calendar = GetSlot(this, CALENDAR);
let fields = ES.ISODateToFields(calendar, GetSlot(this, ISO_DATE_TIME).isoDate);
const isoDateTime = GetSlot(this, ISO_DATE_TIME);
fields.hour = isoDateTime.time.hour;
fields.minute = isoDateTime.time.minute;
fields.second = isoDateTime.time.second;
fields.millisecond = isoDateTime.time.millisecond;
fields.microsecond = isoDateTime.time.microsecond;
fields.nanosecond = isoDateTime.time.nanosecond;
fields = { ...fields, ...isoDateTime.time };
const partialDateTime = ES.PrepareCalendarFields(
calendar,
temporalDateTimeLike,
Expand Down
12 changes: 5 additions & 7 deletions polyfill/lib/zoneddatetime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,11 @@ export class ZonedDateTime {
const offsetNs = ES.GetOffsetNanosecondsFor(timeZone, epochNs);
const isoDateTime = dateTime(this);
let fields = ES.ISODateToFields(calendar, isoDateTime.isoDate);
fields.hour = isoDateTime.time.hour;
fields.minute = isoDateTime.time.minute;
fields.second = isoDateTime.time.second;
fields.millisecond = isoDateTime.time.millisecond;
fields.microsecond = isoDateTime.time.microsecond;
fields.nanosecond = isoDateTime.time.nanosecond;
fields.offset = ES.FormatUTCOffsetNanoseconds(offsetNs);
fields = {
...fields,
...isoDateTime.time,
offset: ES.FormatUTCOffsetNanoseconds(offsetNs)
};
const partialZonedDateTime = ES.PrepareCalendarFields(
calendar,
temporalZonedDateTimeLike,
Expand Down
22 changes: 22 additions & 0 deletions spec/abstractops.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,28 @@ <h1>Date Equations</h1>
<emu-note type="editor"> Note that the operation EpochTimeToMonthInYear(_t_) uses 0-based months unlike rest of Temporal since it's intended to be unified with MonthFromTime(_t_) when the above mentioned issue is fixed.</emu-note>
</emu-clause>

<emu-clause id="sec-checkisodaysrange" type="abstract operation">
<h1>
CheckISODaysRange (
_isoDate_: an ISO Date Record,
): either a normal completion containing ~unused~ or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It checks that the given date is within the range of 10<sup>8</sup> days from the epoch.</dd>
</dl>
<emu-alg>
1. If abs(ISODateToEpochDays(_isoDate_.[[Year]], _isoDate_.[[Month]] - 1, _isoDate_.[[Day]])) > 10<sup>8</sup>, then
1. Throw a *RangeError* exception.
1. Return ~unused~.
</emu-alg>
<emu-note type="editor">
This operation is solely present to ensure that GetUTCEpochNanoseconds is not called with numbers that are too large.
It is distinct from ISODateWithinLimits, which uses GetUTCEpochNanoseconds.
This operation can be removed with no observable effect when https://github.com/tc39/ecma262/issues/1087 is fixed.
</emu-note>
</emu-clause>

<emu-clause id="sec-temporal-units">
<h1>Units</h1>
<p>
Expand Down
2 changes: 1 addition & 1 deletion spec/instant.html
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ <h1>
1. If _parsed_.[[TimeZone]].[[Z]] is *true*, let _offsetNanoseconds_ be 0; otherwise, let _offsetNanoseconds_ be ! ParseDateTimeUTCOffset(_parsed_.[[TimeZone]].[[OffsetString]]).
1. If _parsed_.[[Time]] is ~start-of-day~, let _time_ be MidnightTimeRecord(); else let _time_ be _parsed_.[[Time]].
1. Let _balanced_ be BalanceISODateTime(_parsed_.[[Year]], _parsed_.[[Month]], _parsed_.[[Day]], _time_.[[Hour]], _time_.[[Minute]], _time_.[[Second]], _time_.[[Millisecond]], _time_.[[Microsecond]], _time_.[[Nanosecond]] - _offsetNanoseconds_).
1. If abs(ISODateToEpochDays(_balanced_.[[ISODate]].[[Year]], _balanced_.[[ISODate]].[[Month]] - 1, _balanced_.[[ISODate]].[[Day]])) > 10<sup>8</sup>, throw a *RangeError* exception.
1. Perform ? CheckISODaysRange(_balanced_.[[ISODate]]).
1. Let _epochNanoseconds_ be GetUTCEpochNanoseconds(_balanced_).
1. If IsValidEpochNanoseconds(_epochNanoseconds_) is *false*, throw a *RangeError* exception.
1. Return ! CreateTemporalInstant(_epochNanoseconds_).
Expand Down
4 changes: 2 additions & 2 deletions spec/timezone.html
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,11 @@ <h1>
1. Let _parseResult_ be ! ParseTimeZoneIdentifier(_timeZone_).
1. If _parseResult_.[[OffsetMinutes]] is not ~empty~, then
1. Let _balanced_ be BalanceISODateTime(_isoDateTime_.[[ISODate]].[[Year]], _isoDateTime_.[[ISODate]].[[Month]], _isoDateTime_.[[ISODate]].[[Day]], _isoDateTime_.[[Time]].[[Hour]], _isoDateTime_.[[Time]].[[Minute]] - _parseResult_.[[OffsetMinutes]], _isoDateTime_.[[Time]].[[Second]], _isoDateTime_.[[Time]].[[Millisecond]], _isoDateTime_.[[Time]].[[Microsecond]], _isoDateTime_.[[Time]].[[Nanosecond]]).
1. If abs(ISODateToEpochDays(_balanced_.[[ISODate]].[[Year]], _balanced_.[[ISODate]].[[Month]] - 1, _balanced_.[[ISODate]].[[Day]])) > 10<sup>8</sup>, throw a *RangeError* exception.
1. Perform ? CheckISODaysRange(_balanced_.[[ISODate]]).
1. Let _epochNanoseconds_ be GetUTCEpochNanoseconds(_balanced_).
1. Let _possibleEpochNanoseconds_ be « _epochNanoseconds_ ».
1. Else,
1. If abs(ISODateToEpochDays(_isoDateTime_.[[ISODate]].[[Year]], _isoDateTime_.[[ISODate]].[[Month]] - 1, _isoDateTime_.[[ISODate]].[[Day]])) > 10<sup>8</sup>, throw a *RangeError* exception.
1. Perform ? CheckISODaysRange(_isoDateTime_.[[ISODate]]).
1. Let _possibleEpochNanoseconds_ be GetNamedTimeZoneEpochNanoseconds(_parseResult_.[[Name]], _isoDateTime_).
1. For each value _epochNanoseconds_ in _possibleEpochNanoseconds_, do
1. If IsValidEpochNanoseconds(_epochNanoseconds_) is *false*, throw a *RangeError* exception.
Expand Down
4 changes: 2 additions & 2 deletions spec/zoneddatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -916,13 +916,13 @@ <h1>
1. Return ? GetEpochNanosecondsFor(_timeZone_, _isoDateTime_, _disambiguation_).
1. If _offsetBehaviour_ is ~exact~, or _offsetBehaviour_ is ~option~ and _offsetOption_ is ~use~, then
1. Let _balanced_ be BalanceISODateTime(_isoDate_.[[Year]], _isoDate_.[[Month]], _isoDate_.[[Day]], _time_.[[Hour]], _time_.[[Minute]], _time_.[[Second]], _time_.[[Millisecond]], _time_.[[Microsecond]], _time_.[[Nanosecond]] - _offsetNanoseconds_).
1. If abs(ISODateToEpochDays(_balanced_.[[ISODate]].[[Year]], _balanced_.[[ISODate]].[[Month]] - 1, _balanced_.[[ISODate]].[[Day]])) > 10<sup>8</sup>, throw a *RangeError* exception.
1. Perform ? CheckISODaysRange(_balanced_.[[ISODate]]).
1. Let _epochNanoseconds_ be GetUTCEpochNanoseconds(_balanced_).
1. If IsValidEpochNanoseconds(_epochNanoseconds_) is *false*, throw a *RangeError* exception.
1. Return _epochNanoseconds_.
1. Assert: _offsetBehaviour_ is ~option~.
1. Assert: _offsetOption_ is ~prefer~ or ~reject~.
1. If abs(ISODateToEpochDays(_isoDate_.[[Year]], _isoDate_.[[Month]] - 1, _isoDate_.[[Day]])) > 10<sup>8</sup>, throw a *RangeError* exception.
1. Perform ? CheckISODaysRange(_isoDate_).
1. Let _utcEpochNanoseconds_ be GetUTCEpochNanoseconds(_isoDateTime_).
1. Let _possibleEpochNs_ be ? GetPossibleEpochNanoseconds(_timeZone_, _isoDateTime_).
1. For each element _candidate_ of _possibleEpochNs_, do
Expand Down
Loading