You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rewrite Add, Until, and ToISO on top of narrower calendar-dependent AOs
Capitalize "Boolean"
RegulateNonISOYearMonth => ConstrainMonthCodeToArithmeticalMonth
Change unqualified _month_ to _arithmeticalMonth_
Label a few things as "positive integer"
fromIsoDate, toIsoDate
@@ -828,7 +828,7 @@ contributors: Google, Ecma International
828
828
</h1>
829
829
<dl class="header">
830
830
<dt>description</dt>
831
-
<dd>It produces the year relative to the epoch year (the arithmetic year) for a given set of era, eraYear for a calendar that has eras.</dd>
831
+
<dd>It produces the year relative to the epoch year (the arithmetic year) for a given set of _era_, _eraYear_ in _calendar_, a calendar that includes an era named _era_.</dd>
832
832
</dl>
833
833
<emu-alg>
834
834
1. Let _era_ be CanonicalizeEraInCalendar(_calendar_, _era_).
@@ -981,6 +981,169 @@ contributors: Google, Ecma International
_calendar_: a calendar type that is not *"iso8601"*,
988
+
_year_: an integer,
989
+
_arithmeticalMonth_: a positive integer,
990
+
_day_: an integer,
991
+
): either a normal completion containing an ISO Date Record or a throw completion
992
+
</h1>
993
+
<dl class="header">
994
+
<dt>description</dt>
995
+
<dd>
996
+
It returns an ISO Date Record that, when converted to a Calendar Date Record with _calendar_ (for example, with CalendarISOToDate), contains the given _year_, _arithmeticalMonth_, and _day_ values in its [[Year]], [[Month]], and [[Day]] fields. If this is not possible, a RangeError is thrown.
997
+
</dd>
998
+
</dl>
999
+
<p>It performs the following steps when called:</p>
1000
+
<emu-alg>
1001
+
1. If _year_, _arithmeticalMonth_, and _day_ do not form a valid date in _calendar_, throw a RangeError exception.
1002
+
1. Return a calendar-dependent ISO Date Record as described above.
_calendar_: a calendar type that is not *"iso8601"*,
1049
+
_year_: an integer,
1050
+
_arithmeticalMonth_: an integer,
1051
+
_day_: an integer,
1052
+
): a Record with fields [[Year]] (an integer), [[Month]] (an integer), and [[Day]] (an integer)
1053
+
</h1>
1054
+
<dl class="header">
1055
+
<dt>description</dt>
1056
+
<dd>
1057
+
It interprets the given _year_ and potentially out-of-range _arithmeticalMonth_ and _day_ as arithmetical values in the given _calendar_ and returns in-range values by overflowing out-of-range _arithmeticalMonth_ or _day_ values into the next-highest unit.
1058
+
This date may be outside the range given by ISODateTimeWithinLimits.
1059
+
</dd>
1060
+
</dl>
1061
+
<p>It performs the following steps when called:</p>
1062
+
<emu-alg>
1063
+
1. Let _resolvedYear_ be _year_.
1064
+
1. Let _resolvedMonth_ be _arithmeticalMonth_.
1065
+
1. Let _monthsInYear_ be CalendarMonthsInYear(_calendar_, _resolvedYear_).
1066
+
1. Repeat, while _resolvedMonth_ ≤ 0,
1067
+
1. Set _resolvedYear_ to _resolvedYear_ - 1.
1068
+
1. Set _monthsInYear_ to CalendarMonthsInYear(_calendar_, _resolvedYear_).
1069
+
1. Set _resolvedMonth_ to _resolvedMonth_ + _monthsInYear_.
1070
+
1. Repeat, while _resolvedMonth_ > _monthsInYear_,
1071
+
1. Set _resolvedMonth_ to _resolvedMonth_ - _monthsInYear_.
1072
+
1. Set _resolvedYear_ to _resolvedYear_ + 1.
1073
+
1. Set _monthsInYear_ to CalendarMonthsInYear(_calendar_, _resolvedYear_).
1074
+
1. Let _resolvedDay_ be _day_.
1075
+
1. Let _daysInMonth_ be CalendarDaysInMonth(_calendar_, _resolvedYear_, _resolvedMonth_).
1076
+
1. Repeat, while _resolvedDay_ ≤ 0,
1077
+
1. Set _resolvedMonth_ to _resolvedMonth_ - 1.
1078
+
1. If _resolvedMonth_ is 0, then
1079
+
1. Set _resolvedYear_ to _resolvedYear_ - 1.
1080
+
1. Set _monthsInYear_ to CalendarMonthsInYear(_calendar_, _resolvedYear_).
1081
+
1. Set _resolvedMonth_ to _monthsInYear_.
1082
+
1. Set _daysInMonth_ to CalendarDaysInMonth(_calendar_, _resolvedYear_, _resolvedMonth_).
1083
+
1. Set _resolvedDay_ to _day_ + _daysInMonth_.
1084
+
1. Repeat, while _resolvedDay_ > _daysInMonth_,
1085
+
1. Set _resolvedDay_ to _resolvedDay_ - _daysInMonth_.
1086
+
1. Set _resolvedMonth_ to _resolvedMonth_ + 1.
1087
+
1. If _resolvedMonth_ > _monthsInYear_, then
1088
+
1. Set _resolvedYear_ to _resolvedYear_ + 1.
1089
+
1. Set _monthsInYear_ to CalendarMonthsInYear(_calendar_, _resolvedYear_).
1090
+
1. Set _resolvedMonth_ to 1.
1091
+
1. Set _daysInMonth_ to CalendarDaysInMonth(_calendar_, _resolvedYear_, _resolvedMonth_).
1092
+
1. Return the Record { [[Year]]: _resolvedYear_, [[Month]]: _resolvedMonth_, [[Day]]: _resolvedDay_ }.
_calendar_: a calendar type that is not *"iso8601"*,
1100
+
_sign_: -1 or 1,
1101
+
_fromIsoDate_: an ISO Date Record,
1102
+
_toIsoDate_: an ISO Date Record,
1103
+
_years_: an integer,
1104
+
_months_: an integer,
1105
+
_weeks_: an integer,
1106
+
_days_: an integer,
1107
+
): a Boolean
1108
+
</h1>
1109
+
<dl class="header">
1110
+
<dt>description</dt>
1111
+
<dd>
1112
+
The return value indicates whether the date _date1_, the result of adding the duration denoted by _years_, _months_, _weeks_, and _days_ to _fromIsoDate_ in the calendar system denoted by _calendar_, surpasses _toIsoDate_ in the direction denoted by _sign_.
1113
+
If _weeks_ and _days_ are both zero, then _date1_ need not exist (for example, it could be February 30).
1114
+
</dd>
1115
+
</dl>
1116
+
<p>It performs the following steps when called:</p>
1117
+
<emu-alg>
1118
+
1. Let _parts_ be CalendarISOToDate(_calendar_, _fromIsoDate_).
1119
+
1. Let _y0_ be _parts_.[[Year]] + _years_.
1120
+
1. Let _m0_ be MonthCodeToOrdinal(_calendar_, _y0_, ! ConstrainMonthCode(_calendar_, _y0_, _parts_.[[MonthCode]], ~constrain~)).
1121
+
1. Let _endOfMonth_ be BalanceNonISODate(_calendar_, _y0_, _m0_ + _months_ + 1, 0).
1122
+
1. Let _baseDay_ be _parts_.[[Day]].
1123
+
1. If _weeks_ is not 0 or _days_ is not 0, then
1124
+
1. If _baseDay_ < _endOfMonth_.[[Day]], then
1125
+
1. Let _regulatedDay_ be _baseDay_.
1126
+
1. Else,
1127
+
1. Let _regulatedDay_ be _endOfMonth_.[[Day]].
1128
+
1. Let _balancedDate_ be BalanceNonISODate(_calendar_, _endOfMonth_.[[Year]], _endOfMonth_.[[Month]], _regulatedDay_ + 7 * _weeks_ + _days_).
1129
+
1. Let _y1_ be _balancedDate_.[[Year]].
1130
+
1. Let _m1_ be _balancedDate_.[[Month]].
1131
+
1. Let _d1_ be _balancedDate_.[[Day]].
1132
+
1. Else,
1133
+
1. Let _y1_ be _endOfMonth_.[[Year]].
1134
+
1. Let _m1_ be _endOfMonth_.[[Month]].
1135
+
1. Let _d1_ be _baseDay_.
1136
+
1. Let _calDate2_ be CalendarISOToDate(_calendar_, _toIsoDate_).
@@ -997,23 +1160,22 @@ contributors: Google, Ecma International
997
1160
It may throw a *RangeError* exception if _overflow_ is ~reject~ and the resulting month or day would need to be clamped in order to form a valid date in _calendar_.
998
1161
</dd>
999
1162
</dl>
1000
-
<p>The behaviour is implementation-defined, but all calendars follow the general steps given here, which is a generalization of the precise algorithm specified in CalendarDateAdd for *"iso8601"*.</p>
1163
+
<p>All calendars follow the steps given here, which is a generalization of the precise algorithm specified in CalendarDateAdd for *"iso8601"*.</p>
1001
1164
<p>This definition supersedes the definition provided in <emu-xref href="#sec-temporal-nonisodateadd"></emu-xref>.</p>
1002
1165
<p>It performs the following steps when called:</p>
1003
1166
<emu-alg>
1004
-
1. Let _calendarDate_ be CalendarISOToDate(_calendar_, _isoDate_).
1005
-
1. Add _duration_.[[Years]] to _calendarDate_ without changing any less-significant fields.
1006
-
1. If YearContainsMonthCode(_calendar_, _calendarDate_.[[Year]], _calendarDate_.[[MonthCode]]) is *false*, then
1007
-
1. NOTE: This only happens in lunisolar calendars.
1008
-
1. Set _calendarDate_.[[MonthCode]] to ! ConstrainMonthCode(_calendar_, _calendarDate_.[[Year]], _calendarDate_.[[MonthCode]], ~constrain~).
1009
-
1. Set _calendarDate_.[[Month]] to MonthCodeToOrdinal(_calendar_, _calendarDate_.[[Year]], _calendarDate_.[[MonthCode]]).
1010
-
1. Add _duration_.[[Months]] to _calendarDate_, balancing _calendarDate_ if it goes over a year boundary.
1011
-
1. If the date described by _calendarDate_ does not exist, then
1167
+
1. Let _parts_ be CalendarISOToDate(_calendar_, _isoDate_).
1168
+
1. Let _y0_ be _parts_.[[Year]] + _duration_.[[Years]].
1169
+
1. Let _m0_ be MonthCodeToOrdinal(_calendar_, _y0_, ! ConstrainMonthCode(_calendar_, _y0_, _parts_.[[MonthCode]], ~constrain~)).
1170
+
1. Let _endOfMonth_ be BalanceNonISODate(_calendar_, _y0_, _m0_ + _duration_.[[Months]] + 1, 0).
1171
+
1. Let _baseDay_ be _parts_.[[Day]].
1172
+
1. If _endOfMonth_.[[Day]] < _baseDay_, then
1012
1173
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
1013
-
1. If _calendarDate_.[[MonthCode]] is a valid month code for _calendarDate_.[[Year]], but the date described by _calendarDate_ does not exist, set _calendarDate_.[[Day]] to the closest day in the same month. If there are two equally-close dates in the same month, pick the later one.
1014
-
1. (This step does not apply to any currently supported calendars.) If the date described by _calendarDate_ still does not exist, set _calendarDate_ to the closest date in the same year. If there are two equally-close dates in that year, pick the later one.
1015
-
1. Add _duration_.[[Weeks]] and _duration_.[[Days]] to _calendarDate_, balancing _calendarDate_ if it goes over a month or year boundary.
1016
-
1. Let _result_ be ? CalendarDateToISO(_calendar_, _calendarDate_, _overflow_).
1174
+
1. Let _regulatedDay_ be _endOfMonth_.[[Day]].
1175
+
1. Else,
1176
+
1. Let _regulatedDay_ be _baseDay_.
1177
+
1. Let _balancedDate_ be BalanceNonISODate(_calendar_, _endOfMonth_.[[Year]], _endOfMonth_.[[Month]], _regulatedDay_ + 7 * _duration_.[[Weeks]] + _duration_.[[Days]]).
1178
+
1. Let _result_ be ? CalendarDateArithmeticalToISO(_calendar_, _balancedDate_.[[Year]], _balancedDate_.[[Month]], _balancedDate_.[[Day]]).
1017
1179
1. If ISODateWithinLimits(_result_) is *false*, throw a *RangeError* exception.
1018
1180
1. Return _result_.
1019
1181
</emu-alg>
@@ -1035,19 +1197,36 @@ contributors: Google, Ecma International
1035
1197
No fields larger than _largestUnit_ will be non-zero in the resulting Date Duration Record.
1036
1198
</dd>
1037
1199
</dl>
1038
-
<p>The algorithm is implementation-defined, but all calendars follow the general steps given here, which is a generalization of the precise algorithm specified in CalendarDateUntil for *"iso8601"*.</p>
1200
+
<p>All calendars follow the steps given here, which is a generalization of the precise algorithm specified in CalendarDateUntil for *"iso8601"*.</p>
1039
1201
<p>This definition supersedes the definition provided in <emu-xref href="#sec-temporal-nonisodateuntil"></emu-xref>.</p>
1040
1202
<p>It performs the following steps when called:</p>
1041
1203
<emu-alg>
1204
+
1. Let _sign_ be -CompareISODate(_one_, _two_).
1205
+
1. If _sign_ = 0, return ZeroDateDuration().
1206
+
1. Let _years_ be 0.
1042
1207
1. If _largestUnit_ is ~year~, then
1043
-
1. Add (without constraining) as many years as possible to _one_, in the direction from _one_ to _two_, without surpassing _two_. "Surpassing" here (and in all steps below) means to compare years numerically, then month codes lexicographically, then days numerically; if any of them exceed _two_ in the direction from _one_ to _two_, then _two_ is surpassed.
1044
-
1. Constrain _one_ to a real year and month, not taking day into account. This step only matters for lunisolar calendars.
1045
-
1. If _largestUnit_ is ~year~ or ~month~, then
1046
-
1. Add (without constraining) as many months as possible to _one_ without surpassing _two_.
1047
-
1. Constrain _one_ to a real year, month, and day.
1048
-
1. If _largestUnit_ is ~week~, add as many weeks as possible to _one_ without surpassing _two_.
1049
-
1. Add as many days as possible to _one_ until it is equal to _two_.
1050
-
1. Return a Date Duration Record of the number of years, months, weeks, and days added.
1208
+
1. Let _candidateYears_ be _sign_.
1209
+
1. Repeat, while NonISODateSurpasses(_calendar_, _sign_, _one_, _two_, _candidateYears_, 0, 0, 0) is *false*,
1210
+
1. Set _years_ to _candidateYears_.
1211
+
1. Set _candidateYears_ to _candidateYears_ + _sign_.
1212
+
1. Let _months_ be 0.
1213
+
1. If _largestUnit_ is ~year~ or _largestUnit_ is ~month~, then
1214
+
1. Let _candidateMonths_ be _sign_.
1215
+
1. Repeat, while NonISODateSurpasses(_calendar_, _sign_, _one_, _two_, _years_, _candidateMonths_, 0, 0) is *false*,
1216
+
1. Set _months_ to _candidateMonths_.
1217
+
1. Set _candidateMonths_ to _candidateMonths_ + _sign_.
1218
+
1. Let _weeks_ be 0.
1219
+
1. If _largestUnit_ is ~week~, then
1220
+
1. Let _candidateWeeks_ be _sign_.
1221
+
1. Repeat, while NonISODateSurpasses(_calendar_, _sign_, _one_, _two_, _years_, _months_, _candidateWeeks_, 0) is *false*,
1222
+
1. Set _weeks_ to _candidateWeeks_.
1223
+
1. Set _candidateWeeks_ to _candidateWeeks_ + sign.
1224
+
1. Let _days_ be 0.
1225
+
1. Let _candidateDays_ be _sign_.
1226
+
1. Repeat, while NonISODateSurpasses(_calendar_, _sign_, _one_, _two_, _years_, _months_, _weeks_, _candidateDays_) is *false*,
1227
+
1. Set _days_ to _candidateDays_.
1228
+
1. Set _candidateDays_ to _candidateDays_ + _sign_.
@@ -1087,8 +1266,13 @@ contributors: Google, Ecma International
1087
1266
1. Let _ordinalMonth_ be _fields_.[[Month]].
1088
1267
1. Let _day_ be _fields_.[[Day]].
1089
1268
1. Assert: _day_ is not ~unset~.
1090
-
1. If the date described by _calendar_, _arithmeticYear_, _ordinalMonth_, and _day_ does not exist, set _day_ to the closest day in the same month. If there are two equally-close dates in the same month, pick the later one.
1091
-
1. Return an implementation-defined ISO Date Record that corresponds to the date described by _calendar_, _arithmeticYear_, _ordinalMonth_, and _day_.
1269
+
1. Let _daysInMonth_ be CalendarDaysInMonth(_calendar_, _arithmeticYear_, _ordinalMonth_).
1270
+
1. If _daysInMonth_ ≤ _day_, then
1271
+
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
0 commit comments