Skip to content

Commit ff80068

Browse files
committed
Editorial: Refactor ISODateSurpasses parallel to NonISODateSurpasses
See tc39/proposal-intl-era-monthcode#101. This changes the general outline of ISODateSurpasses so that it parallels the outline of NonISODateSurpasses in the Intl Era Monthcode proposal as proposed in the PR. Also refactors the polyfill code, but keeps the optimizations we already had regarding not passing weeks and days to ISODateSurpasses and not (yet) adapting the polyfill code to use this algorithm in non-ISO8601 calculations.
1 parent 9e63759 commit ff80068

File tree

2 files changed

+65
-30
lines changed

2 files changed

+65
-30
lines changed

polyfill/lib/calendar.mjs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,19 +132,27 @@ function calendarDateWeekOfYear(id, isoDate) {
132132
return { week: woy, year: yow };
133133
}
134134

135-
function ISODateSurpasses(sign, baseDate, isoDate2, years, months) {
136-
const yearMonth = ES.BalanceISOYearMonth(baseDate.year + years, baseDate.month + months);
137-
let y1 = yearMonth.year;
138-
let m1 = yearMonth.month;
139-
let d1 = baseDate.day;
140-
if (y1 !== isoDate2.year) {
141-
if (sign * (y1 - isoDate2.year) > 0) return true;
142-
} else if (m1 !== isoDate2.month) {
143-
if (sign * (m1 - isoDate2.month) > 0) return true;
144-
} else if (d1 !== isoDate2.day) {
145-
if (sign * (d1 - isoDate2.day) > 0) return true;
135+
function CompareSurpasses(sign, year, month, day, target) {
136+
if (year !== target.year) {
137+
if (sign * (year - target.year) > 0) return true;
138+
} else if (month !== target.month) {
139+
// Skip the monthCode case that is in the spec, as we are currently not
140+
// using this operation in non-iso8601 calculations
141+
if (sign * (month - target.month) > 0) return true;
142+
} else if (day !== target.day) {
143+
if (sign * (day - target.day) > 0) return true;
146144
}
147-
return false;
145+
}
146+
147+
function ISODateSurpasses(sign, baseDate, isoDate2, years, months) {
148+
const y0 = baseDate.year + years;
149+
if (CompareSurpasses(sign, y0, baseDate.month, baseDate.day, isoDate2)) return true;
150+
if (months === 0) return false;
151+
const m0 = baseDate.month + months;
152+
const monthsAdded = ES.BalanceISOYearMonth(y0, m0);
153+
return CompareSurpasses(sign, monthsAdded.year, monthsAdded.month, baseDate.day, isoDate2);
154+
// Skip the weeks and days addition in the spec, as we currently optimize that
155+
// out in iso8601 date difference calculation
148156
}
149157

150158
function addDaysISO(isoDate, days) {

spec/plaindate.html

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,38 @@ <h1>
691691
</emu-alg>
692692
</emu-clause>
693693

694+
<emu-clause id="sec-temporal-comparesurpasses" type="abstract operation">
695+
<h1>
696+
CompareSurpasses (
697+
_sign_: -1 or 1,
698+
_year_: an integer,
699+
_monthOrCode_: an integer or a month code,
700+
_day_: an integer,
701+
_target_: a Calendar Fields Record,
702+
): a Boolean
703+
</h1>
704+
<dl class="header">
705+
<dt>description</dt>
706+
<dd>
707+
The return value indicates whether the calendar date formed by _year_, _monthOrCode_, and _day_, which need not exist, surpasses _target_ in the direction denoted by _sign_.
708+
</dd>
709+
</dl>
710+
<emu-alg>
711+
1. If _year__target_.[[Year]], then
712+
1. If _sign_ × (_year_ - _target_.[[Year]]) > 0, return *true*.
713+
1. Else if _monthOrCode_ is a month code and _monthOrCode_ is not _target_.[[MonthCode]], then
714+
1. If _sign_ > 0, then
715+
1. If _monthOrCode_ is lexicographically greater than _target_.[[MonthCode]], return *true*.
716+
1. Else,
717+
1. If _target_.[[MonthCode]] is lexicographically greater than _monthOrCode_, return *true*.
718+
1. Else if _monthOrCode_ is an integer and _monthOrCode__target_.[[Month]], then
719+
1. If _sign_ × (_monthOrCode_ - _target_.[[Month]]) > 0, return *true*.
720+
1. Else if _day__target_.[[Day]], then
721+
1. If _sign_ × (_day_ - _target_.[[Day]]) > 0, return *true*.
722+
1. Return *false*.
723+
</emu-alg>
724+
</emu-clause>
725+
694726
<emu-clause id="sec-temporal-isodatesurpasses" type="abstract operation">
695727
<h1>
696728
ISODateSurpasses (
@@ -712,24 +744,19 @@ <h1>
712744
</dd>
713745
</dl>
714746
<emu-alg>
715-
1. Let _yearMonth_ be BalanceISOYearMonth(_baseDate_.[[Year]] + _years_, _baseDate_.[[Month]] + _months_).
716-
1. If _weeks_ is not 0 or _days_ is not 0, then
717-
1. Let _regulatedDate_ be ! RegulateISODate(_yearMonth_.[[Year]], _yearMonth_.[[Month]], _baseDate_.[[Day]], ~constrain~).
718-
1. Let _balancedDate_ be BalanceISODate(_regulatedDate_.[[Year]], _regulatedDate_.[[Month]], _regulatedDate_.[[Day]] + 7 * _weeks_ + _days_).
719-
1. Let _y1_ be _balancedDate_.[[Year]].
720-
1. Let _m1_ be _balancedDate_.[[Month]].
721-
1. Let _d1_ be _balancedDate_.[[Day]].
722-
1. Else,
723-
1. Let _y1_ be _yearMonth_.[[Year]].
724-
1. Let _m1_ be _yearMonth_.[[Month]].
725-
1. Let _d1_ be _baseDate_.[[Day]].
726-
1. If _y1__isoDate2_.[[Year]], then
727-
1. If _sign_ × (_y1_ - _isoDate2_.[[Year]]) > 0, return *true*.
728-
1. Else if _m1__isoDate2_.[[Month]], then
729-
1. If _sign_ × (_m1_ - _isoDate2_.[[Month]]) > 0, return *true*.
730-
1. Else if _d1__isoDate2_.[[Day]], then
731-
1. If _sign_ × (_d1_ - _isoDate2_.[[Day]]) > 0, return *true*.
732-
1. Return *false*.
747+
1. Let _parts_ be CalendarISOToDate(*"iso8601"*, _baseDate_).
748+
1. Let _target_ be CalendarISOToDate(*"iso8601"*, _isoDate2_).
749+
1. Let _y0_ be _parts_.[[Year]] + _years_.
750+
1. If CompareSurpasses(_sign_, _y0_, _parts_.[[MonthCode]], _parts_.[[Day]], _target_) is *true*, return *true*.
751+
1. If _months_ = 0, return *false*.
752+
1. Let _m0_ be _parts_.[[Month]] + _months_.
753+
1. Let _monthsAdded_ be BalanceISOYearMonth(_y0_, _m0_).
754+
1. If CompareSurpasses(_sign_, _monthsAdded_.[[Year]], _monthsAdded_.[[Month]], _parts_.[[Day]], _target_) is *true*, return *true*.
755+
1. If _weeks_ = 0 and _days_ = 0, return *false*.
756+
1. Let _regulatedDate_ be ! RegulateISODate(_monthsAdded_.[[Year]], _monthsAdded_.[[Month]], _parts_.[[Day]], ~constrain~).
757+
1. Let _daysInWeek_ be 7.
758+
1. Let _balancedDate_ be BalanceISODate(_regulatedDate_.[[Year]], _regulatedDate_.[[Month]], _regulatedDate_.[[Day]] + _daysInWeek_ * _weeks_ + _days_).
759+
1. Return CompareSurpasses(_sign_, _balancedDate_.[[Year]], _balancedDate_.[[Month]], _balancedDate_.[[Day]], _target_).
733760
</emu-alg>
734761
<emu-note>
735762
<p>This operation intentionally uses overflow ~constrain~ when regulating the year-month. As a result, adding the duration returned by `.since` or `.until` to _baseDate_ may cause a *RangeError* exception when _overflow_ is ~reject~.</p>

0 commit comments

Comments
 (0)