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

Replace BalanceISODate(Time) and rearrange time zone offset checks #3014

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
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
38 changes: 11 additions & 27 deletions spec/abstractops.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,28 +108,6 @@ <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 Expand Up @@ -624,13 +602,11 @@ <h1>
1. Return the Record { [[PlainRelativeTo]]: _plainDate_, [[ZonedRelativeTo]]: *undefined* }.
1. Let _calendar_ be ? GetTemporalCalendarIdentifierWithISODefault(_value_).
1. Let _fields_ be ? PrepareCalendarFields(_calendar_, _value_, « ~year~, ~month~, ~month-code~, ~day~ », « ~hour~, ~minute~, ~second~, ~millisecond~, ~microsecond~, ~nanosecond~, ~offset~, ~time-zone~ », «»).
1. Let _result_ be ? InterpretTemporalDateTimeFields(_calendar_, _fields_, ~constrain~).
1. Let _isoDateTime_ be ? InterpretTemporalDateTimeFields(_calendar_, _fields_, ~constrain~).
1. Let _timeZone_ be _fields_.[[TimeZone]].
1. Let _offsetString_ be _fields_.[[Offset]].
1. If _offsetString_ is ~unset~, then
1. Set _offsetBehaviour_ to ~wall~.
1. Let _isoDate_ be _result_.[[ISODate]].
1. Let _time_ be _result_.[[Time]].
1. Else,
1. If _value_ is not a String, throw a *TypeError* exception.
1. Let _result_ be ? ParseISODateTime(_value_, « |TemporalDateTimeString[+Zoned]|, |TemporalDateTimeString[~Zoned]| »).
Expand All @@ -650,14 +626,22 @@ <h1>
1. Set _calendar_ to ? CanonicalizeCalendar(_calendar_).
1. Let _isoDate_ be CreateISODateRecord(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]]).
1. Let _time_ be _result_.[[Time]].
1. If _time_ is ~start-of-day~, then
1. If _timeZone_ is not ~unset~, then
1. Assert: _offsetBehaviour_ is ~wall~.
1. Let _epochNanoseconds_ be ? GetStartOfDay(_timeZone_, _isoDate_).
1. Let _zonedRelativeTo_ be ! CreateTemporalZonedDateTime(_epochNanoseconds_, _timeZone_, _calendar_).
1. Return the Record { [[PlainRelativeTo]]: *undefined*, [[ZonedRelativeTo]]: _zonedRelativeTo_ }.
1. Set _time_ to MidnightTimeRecord().
1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_isoDate_, _time_).
1. If _timeZone_ is ~unset~, then
1. Let _plainDate_ be ? CreateTemporalDate(_isoDate_, _calendar_).
1. Let _plainDate_ be ? CreateTemporalDate(_isoDateTime_.[[ISODate]], _calendar_).
1. Return the Record { [[PlainRelativeTo]]: _plainDate_, [[ZonedRelativeTo]]: *undefined* }.
1. If _offsetBehaviour_ is ~option~, then
1. Let _offsetNs_ be ! ParseDateTimeUTCOffset(_offsetString_).
1. Else,
1. Let _offsetNs_ be 0.
1. Let _epochNanoseconds_ be ? InterpretISODateTimeOffset(_isoDate_, _time_, _offsetBehaviour_, _offsetNs_, _timeZone_, ~compatible~, ~reject~, _matchBehaviour_).
1. Let _epochNanoseconds_ be ? InterpretISODateTimeOffset(_isoDateTime_, _offsetBehaviour_, _offsetNs_, _timeZone_, ~compatible~, ~reject~, _matchBehaviour_).
1. Let _zonedRelativeTo_ be ! CreateTemporalZonedDateTime(_epochNanoseconds_, _timeZone_, _calendar_).
1. Return the Record { [[PlainRelativeTo]]: *undefined*, [[ZonedRelativeTo]]: _zonedRelativeTo_ }.
</emu-alg>
Expand Down
12 changes: 6 additions & 6 deletions spec/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,8 @@ <h1>
1. If _calendar_ is *"iso8601"*, then
1. Let _intermediate_ be BalanceISOYearMonth(_isoDate_.[[Year]] + _duration_.[[Years]], _isoDate_.[[Month]] + _duration_.[[Months]]).
1. Set _intermediate_ to ? RegulateISODate(_intermediate_.[[Year]], _intermediate_.[[Month]], _isoDate_.[[Day]], _overflow_).
1. Let _d_ be _intermediate_.[[Day]] + _duration_.[[Days]] + 7 × _duration_.[[Weeks]].
1. Let _result_ be BalanceISODate(_intermediate_.[[Year]], _intermediate_.[[Month]], _d_).
1. Let _days_ be _duration_.[[Days]] + 7 × _duration_.[[Weeks]].
1. Let _result_ be AddDaysToISODate(_intermediate_, _days_).
1. Else,
1. Let _result_ be an implementation-defined ISO Date Record, or throw a *RangeError* exception, as described below.
1. If ISODateWithinLimits(_result_) is *false*, throw a *RangeError* exception.
Expand Down Expand Up @@ -547,18 +547,18 @@ <h1>
1. Let _weeks_ be 0.
1. If _largestUnit_ is ~week~, then
1. Let _candidateWeeks_ be _sign_.
1. Set _intermediate_ to BalanceISODate(_constrained_.[[Year]], _constrained_.[[Month]], _constrained_.[[Day]] + 7 × _candidateWeeks_).
1. Set _intermediate_ to AddDaysToISODate(_constrained_, 7 × _candidateWeeks_).
1. Repeat, while ISODateSurpasses(_sign_, _intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]], _two_) is *false*,
1. Set _weeks_ to _candidateWeeks_.
1. Set _candidateWeeks_ to _candidateWeeks_ + sign.
1. Set _intermediate_ to BalanceISODate(_intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]] + 7 × _sign_).
1. Set _intermediate_ to AddDaysToISODate(_intermediate_, 7 × _sign_).
1. Let _days_ be 0.
1. Let _candidateDays_ be _sign_.
1. Set _intermediate_ to BalanceISODate(_constrained_.[[Year]], _constrained_.[[Month]], _constrained_.[[Day]] + 7 × _weeks_ + _candidateDays_).
1. Set _intermediate_ to AddDaysToISODate(_constrained_, 7 × _weeks_ + _candidateDays_).
1. Repeat, while ISODateSurpasses(_sign_, _intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]], _two_) is *false*,
1. Set _days_ to _candidateDays_.
1. Set _candidateDays_ to _candidateDays_ + _sign_.
1. Set _intermediate_ to BalanceISODate(_intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]] + _sign_).
1. Set _intermediate_ to AddDaysToISODate(_intermediate_, _sign_).
1. Return ! CreateDateDurationRecord(_years_, _months_, _weeks_, _days_).
1. Return an implementation-defined Date Duration Record as described above.
</emu-alg>
Expand Down
9 changes: 7 additions & 2 deletions spec/duration.html
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,7 @@ <h1>
1. Else if _unit_ is ~week~, then
1. Let _yearsMonths_ be ! AdjustDateDurationRecord(_duration_.[[Date]], 0, 0).
1. Let _weeksStart_ be ? CalendarDateAdd(_calendar_, _isoDateTime_.[[ISODate]], _yearsMonths_, ~constrain~).
1. Let _weeksEnd_ be BalanceISODate(_weeksStart_.[[Year]], _weeksStart_.[[Month]], _weeksStart_.[[Day]] + _duration_.[[Date]].[[Days]]).
1. Let _weeksEnd_ be AddDaysToISODate(_weeksStart_, _duration_.[[Date]].[[Days]]).
1. Let _untilResult_ be CalendarDateUntil(_calendar_, _weeksStart_, _weeksEnd_, ~week~).
1. Let _weeks_ be RoundNumberToIncrement(_duration_.[[Date]].[[Weeks]] + _untilResult_.[[Weeks]], _increment_, ~trunc~).
1. Let _r1_ be _weeks_.
Expand All @@ -1638,6 +1638,8 @@ <h1>
1. Let _startEpochNs_ be GetUTCEpochNanoseconds(_startDateTime_).
1. Let _endEpochNs_ be GetUTCEpochNanoseconds(_endDateTime_).
1. Else,
1. If ISODateTimeWithinLimits(_startDateTime_) is *false*, throw a *RangeError* exception.
1. If ISODateTimeWithinLimits(_endDateTime_) is *false*, throw a *RangeError* exception.
1. Let _startEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _startDateTime_, ~compatible~).
1. Let _endEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _endDateTime_, ~compatible~).
1. If _sign_ is 1, then
Expand Down Expand Up @@ -1692,8 +1694,10 @@ <h1>
<emu-alg>
1. Let _start_ be ? CalendarDateAdd(_calendar_, _isoDateTime_.[[ISODate]], _duration_.[[Date]], ~constrain~).
1. Let _startDateTime_ be CombineISODateAndTimeRecord(_start_, _isoDateTime_.[[Time]]).
1. Let _endDate_ be BalanceISODate(_start_.[[Year]], _start_.[[Month]], _start_.[[Day]] + _sign_).
1. If ISODateTimeWithinLimits(_startDateTime_) is *false*, throw a *RangeError* exception.
1. Let _endDate_ be AddDaysToISODate(_start_, _sign_).
1. Let _endDateTime_ be CombineISODateAndTimeRecord(_endDate_, _isoDateTime_.[[Time]]).
1. If ISODateTimeWithinLimits(_endDateTime_) is *false*, throw a *RangeError* exception.
1. Let _startEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _startDateTime_, ~compatible~).
1. Let _endEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _endDateTime_, ~compatible~).
1. Let _daySpan_ be TimeDurationFromEpochNanosecondsDifference(_endEpochNs_, _startEpochNs_).
Expand Down Expand Up @@ -1798,6 +1802,7 @@ <h1>
1. If _timeZone_ is ~unset~, then
1. Let _endEpochNs_ be GetUTCEpochNanoseconds(_endDateTime_).
1. Else,
1. If ISODateTimeWithinLimits(_endDateTime_) is *false*, throw a *RangeError* exception.
1. Let _endEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _endDateTime_, ~compatible~).
1. Let _beyondEnd_ be _nudgedEpochNs_ - _endEpochNs_.
1. If _beyondEnd_ &lt; 0, let _beyondEndSign_ be -1; else if _beyondEnd_ > 0, let _beyondEndSign_ be 1; else let _beyondEndSign_ be 0.
Expand Down
7 changes: 4 additions & 3 deletions spec/instant.html
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,10 @@ <h1>
1. Assert: Either _parsed_.[[TimeZone]].[[OffsetString]] is not ~empty~ or _parsed_.[[TimeZone]].[[Z]] is *true*, but not both.
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. Perform ? CheckISODaysRange(_balanced_.[[ISODate]]).
1. Let _epochNanoseconds_ be GetUTCEpochNanoseconds(_balanced_).
1. Let _isoDate_ be CreateISODateRecord(_parsed_.[[Year]], _parsed_.[[Month]], _parsed_.[[Day]]).
1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_isoDate_, _time_).
1. If ISODateTimeWithinLimits(_isoDateTime_) is *false*, throw a *RangeError* exception.
1. Let _epochNanoseconds_ be GetUTCEpochNanoseconds(_isoDateTime_) - _offsetNanoseconds_.
1. If IsValidEpochNanoseconds(_epochNanoseconds_) is *false*, throw a *RangeError* exception.
1. Return ! CreateTemporalInstant(_epochNanoseconds_).
</emu-alg>
Expand Down
13 changes: 6 additions & 7 deletions spec/plaindate.html
Original file line number Diff line number Diff line change
Expand Up @@ -773,23 +773,22 @@ <h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-balanceisodate" type="abstract operation">
<emu-clause id="sec-temporal-adddaystoisodate" type="abstract operation">
<h1>
BalanceISODate (
_year_: an integer,
_month_: an integer,
_day_: an integer,
AddDaysToISODate (
_isoDate_: an ISO Date Record,
_days_: an integer,
): an ISO Date Record
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It converts the given _year_, _month_, and _day_ into a valid calendar date in the ISO 8601 calendar as given by IsValidISODate, by overflowing out-of-range _month_ or _day_ values into the next-highest unit.
It adds _days_ to _isoDate_ into a valid calendar date in the ISO 8601 calendar as given by IsValidISODate, by overflowing out-of-range month or day values into the next-highest unit.
This date may be outside the range given by ISODateTimeWithinLimits.
</dd>
</dl>
<emu-alg>
1. Let _epochDays_ be ISODateToEpochDays(_year_, _month_ - 1, _day_).
1. Let _epochDays_ be ISODateToEpochDays(_isoDate_.[[Year]], _isoDate_.[[Month]] - 1, _isoDate_.[[Day]]) + _days_.
1. Let _ms_ be EpochDaysToEpochMs(_epochDays_, 0).
1. Return CreateISODateRecord(EpochTimeToEpochYear(_ms_), EpochTimeToMonthInYear(_ms_) + 1, EpochTimeToDate(_ms_)).
</emu-alg>
Expand Down
29 changes: 2 additions & 27 deletions spec/plaindatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -836,31 +836,6 @@ <h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-balanceisodatetime" type="abstract operation">
<h1>
BalanceISODateTime (
_year_: an integer,
_month_: an integer,
_day_: an integer,
_hour_: an integer,
_minute_: an integer,
_second_: an integer,
_millisecond_: an integer,
_microsecond_: an integer,
_nanosecond_: an integer,
): an ISO Date-Time Record
</h1>
<dl class="header">
<dt>description</dt>
<dd></dd>
</dl>
<emu-alg>
1. Let _balancedTime_ be BalanceTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_).
1. Let _balancedDate_ be BalanceISODate(_year_, _month_, _day_ + _balancedTime_.[[Days]]).
1. Return CombineISODateAndTimeRecord(_balancedDate_, _balancedTime_).
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-createtemporaldatetime" type="abstract operation">
<h1>
CreateTemporalDateTime (
Expand Down Expand Up @@ -942,7 +917,7 @@ <h1>
<emu-alg>
1. Assert: ISODateTimeWithinLimits(_isoDateTime_) is *true*.
1. Let _roundedTime_ be RoundTime(_isoDateTime_.[[Time]], _increment_, _unit_, _roundingMode_).
1. Let _balanceResult_ be BalanceISODate(_isoDateTime_.[[ISODate]].[[Year]], _isoDateTime_.[[ISODate]].[[Month]], _isoDateTime_.[[ISODate]].[[Day]] + _roundedTime_.[[Days]]).
1. Let _balanceResult_ be AddDaysToISODate(_isoDateTime_.[[ISODate]], _roundedTime_.[[Days]]).
1. Return CombineISODateAndTimeRecord(_balanceResult_, _roundedTime_).
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -971,7 +946,7 @@ <h1>
1. Let _dateSign_ be CompareISODate(_isoDateTime2_.[[ISODate]], _isoDateTime1_.[[ISODate]]).
1. Let _adjustedDate_ be _isoDateTime2_.[[ISODate]].
1. If _timeSign_ = -_dateSign_, then
1. Set _adjustedDate_ to BalanceISODate(_adjustedDate_.[[Year]], _adjustedDate_.[[Month]], _adjustedDate_.[[Day]] + _timeSign_).
1. Set _adjustedDate_ to AddDaysToISODate(_adjustedDate_, _timeSign_).
1. Set _timeDuration_ to ? Add24HourDaysToTimeDuration(_timeDuration_, -_timeSign_).
1. Let _dateLargestUnit_ be LargerOfTwoTemporalUnits(~day~, _largestUnit_).
1. Let _dateDifference_ be CalendarDateUntil(_calendar_, _isoDateTime1_.[[ISODate]], _adjustedDate_, _dateLargestUnit_).
Expand Down
2 changes: 1 addition & 1 deletion spec/plainyearmonth.html
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ <h1>
1. If _sign_ &lt; 0, then
1. Let _oneMonthDuration_ be ! CreateDateDurationRecord(0, 1, 0, 0).
1. Let _nextMonth_ be ? CalendarDateAdd(_calendar_, _intermediateDate_, _oneMonthDuration_, ~constrain~).
1. Let _date_ be BalanceISODate(_nextMonth_.[[Year]], _nextMonth_.[[Month]], _nextMonth_.[[Day]] - 1).
1. Let _date_ be AddDaysToISODate(_nextMonth_, -1).
1. Assert: ISODateWithinLimits(_date_) is *true*.
1. Else,
1. Let _date_ be _intermediateDate_.
Expand Down
Loading
Loading