From d5337fe155c2e867e9962a107a622e617e739a37 Mon Sep 17 00:00:00 2001 From: Aditi Date: Thu, 9 Mar 2023 20:31:32 +0530 Subject: [PATCH] Change date AOs to accept mathematical values --- spec/abstractops.html | 113 ++++++++++++++++++++++++++++++++++++++++++ spec/calendar.html | 24 ++++----- spec/duration.html | 8 ++- spec/intl.html | 13 ++--- spec/plaindate.html | 15 +++--- spec/timezone.html | 6 +-- 6 files changed, 139 insertions(+), 40 deletions(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index d561e46b19..dbbf41ae32 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -29,6 +29,119 @@

IterableToListOfType ( _items_, _elementTypes_ )

+ +

+ ISODateToEpochDays ( + _year_: an integer, + _month_: an integer, + _date_: an integer, + ): an integer +

+
+
description
+
It calculates a number of days.
+
+ + 1. Let _ym_ be _year_ + (floor(_month_) / 12). + 1. Let _mn_ be _month_ modulo 12. + 1. Find a time value _t_ such that EpochTimeToEpochYear(_t_) is _ym_, EpochTimeToMonthInYear(_t_) is _mn_, and EpochTimeToDate(_t_) is 1. + 1. Return ℝ(Day(_t_)) + _date_ - 1. + + This operation corresponds to ECMA-262 operation MakeDay(_year_, _month_, _date_). It calculates the result in mathematical values instead of Number values. These two operations would be unified when https://github.com/tc39/ecma262/issues/1087 is fixed. +
+ + +

+ EpochDaysToEpochMs ( + _day_: an integer, + _time_: an integer, + ): an integer +

+
+
description
+
It calculates a number of milliseconds.
+
+ + 1. Return _day_ × ℝ(msPerDay) + _time_. + + This operation corresponds to ECMA-262 operation MakeDate(_date_, _time_). It calculates the result in mathematical values instead of Number values. These two operations would be unified when https://github.com/tc39/ecma262/issues/1087 is fixed. +
+ + +

Year Number

+

ECMAScript uses a proleptic Gregorian calendar to map a day number to a year number and to determine the month and date within that year. In this calendar, leap years are precisely those which are (divisible by 4) and ((not divisible by 100) or (divisible by 400)). The number of days in year number _y_ is therefore defined by

+ + MathematicalDaysInYear(_y_) + = 365 if ((_y_) modulo 4) ≠ 0 + = 366 if ((_y_) modulo 4) = 0 and ((_y_) modulo 100) ≠ 0 + = 365 if ((_y_) modulo 100) = 0 and ((_y_) modulo 400) ≠ 0 + = 366 if ((_y_) modulo 400) = 0 + +

All non-leap years have 365 days with the usual number of days per month and leap years have an extra day in February. The day number of the first day of year _y_ is given by:

+ EpochDayNumberForYear(_y_) = 365 × (_y_ - 1970) + floor((_y_ - 1969) / 4) - floor((_y_ - 1901) / 100) + floor((_y_ - 1601) / 400) +

The time of the start of a year is:

+ EpochTimeForYear(_y_) = ℝ(msPerDay) × EpochDayNumberForYear(_y_) +

A time value determines a year by:

+ EpochTimeToEpochYear(_t_) = the largest integral Number _y_ (closest to +∞) such that EpochTimeForYear(_y_) ≤ _t_ +

The leap-year function is 1 for a time within a leap year and otherwise is 0:

+ + MathematicalInLeapYear(_t_) + = 0 if MathematicalDaysInYear(EpochTimeToEpochYear(_t_)) is 365 + = 1 if MathematicalDaysInYear(EpochTimeToEpochYear(_t_)) is 366 + + These operations correspond to ECMA-262 operations DaysInYear(_y_), DayFromYear(_y_), TimeFromYear(_y_), YearFromTime(_t_). They calculate the result in mathematical values instead of Number values. These operations would be unified when https://github.com/tc39/ecma262/issues/1087 is fixed. +
+ + +

Month Number

+

Months are identified by an integer in the inclusive interval from 0 to 11. The mapping EpochTimeToMonthInYear(_t_) from a time value _t_ to a month number is defined by:

+ + EpochTimeToMonthInYear(_t_) + = 0 if 0 ≤ EpochTimeToDayInYear(_t_) < 31 + = 1 if 31 ≤ EpochTimeToDayInYear(_t_) < 59 + MathematicalInLeapYear(_t_) + = 2 if 59 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 90 + MathematicalInLeapYear(_t_) + = 3 if 90 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 120 + MathematicalInLeapYear(_t_) + = 4 if 120 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 151 + MathematicalInLeapYear(_t_) + = 5 if 151 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 181 + MathematicalInLeapYear(_t_) + = 6 if 181 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 212 + MathematicalInLeapYear(_t_) + = 7 if 212 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 243 + MathematicalInLeapYear(_t_) + = 8 if 243 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 273 + MathematicalInLeapYear(_t_) + = 9 if 273 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 304 + MathematicalInLeapYear(_t_) + = 10 if 304 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 334 + MathematicalInLeapYear(_t_) + = 11 if 334 + MathematicalInLeapYear(_t_) ≤ EpochTimeToDayInYear(_t_) < 365 + MathematicalInLeapYear(_t_) + +

where

+ EpochTimeToDayInYear(_t_) = ℝ(Day(_t_)) - EpochDayNumberForYear(EpochTimeToEpochYear(_t_)) +

A month value of 0 specifies January; 1 specifies February; 2 specifies March; 3 specifies April; 4 specifies May; 5 specifies June; 6 specifies July; 7 specifies August; 8 specifies September; 9 specifies October; 10 specifies November; and 11 specifies December. Note that EpochTimeToMonthInYear(0) = 0, corresponding to Thursday, 1 January 1970.

+ These operations correspond to ECMA-262 operations MonthFromTime(_t_) and DayWithinYear(_y_). They calculate the result in mathematical values instead of Number values. These operations would be unified when https://github.com/tc39/ecma262/issues/1087 is fixed. +
+ +

Date Number

+

A date number is identified by a mathematical value in the inclusive interval from 1 to 31. The mapping EpochTimeToDate(_t_) from a time value _t_ to a date number is defined by:

+ + EpochTimeToDate(_t_) + = EpochTimeToDayInYear(_t_) + 1 if EpochTimeToMonthInYear(_t_) is 0 + = EpochTimeToDayInYear(_t_) - 30 if EpochTimeToMonthInYear(_t_) is 1 + = EpochTimeToDayInYear(_t_) - 58 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 2 + = EpochTimeToDayInYear(_t_) - 89 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 3 + = EpochTimeToDayInYear(_t_) - 119 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 4 + = EpochTimeToDayInYear(_t_) - 150 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 5 + = EpochTimeToDayInYear(_t_) - 180 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 6 + = EpochTimeToDayInYear(_t_) - 211 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 7 + = EpochTimeToDayInYear(_t_) - 242 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 8 + = EpochTimeToDayInYear(_t_) - 272 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 9 + = EpochTimeToDayInYear(_t_) - 303 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 10 + = EpochTimeToDayInYear(_t_) - 333 - MathematicalInLeapYear(_t_) if EpochTimeToMonthInYear(_t_) is 11 + + This operation corresponds to ECMA-262 operation DateFromTime(_t_). It calculates the result in mathematical values instead of Number values. These operations would be unified when https://github.com/tc39/ecma262/issues/1087 is fixed. +
+ +

Week Day

+

The weekday for a particular time _t_ is defined as

+ EpochTimeToWeekDay(_t_) =(ℝ(Day(_t_)) + 4) modulo 7 +

A weekday value of 0 specifies Sunday; 1 specifies Monday; 2 specifies Tuesday; 3 specifies Wednesday; 4 specifies Thursday; 5 specifies Friday; and 6 specifies Saturday. Note that EpochTimeToWeekDay(0) = 4, corresponding to Thursday, 1 January 1970.

+ This operation corresponds to ECMA-262 operation WeekDay(_t_). It calculates the result in mathematical values instead of Number values. These operations would be unified when https://github.com/tc39/ecma262/issues/1087 is fixed. +

GetOptionsObject ( _options_ )

diff --git a/spec/calendar.html b/spec/calendar.html index 561fe653fe..1d5d5d7d22 100644 --- a/spec/calendar.html +++ b/spec/calendar.html @@ -651,7 +651,7 @@

1. If _month_ is 1, 3, 5, 7, 8, 10, or 12, return 31. 1. If _month_ is 4, 6, 9, or 11, return 30. 1. Assert: _month_ is 2. - 1. Return 28 + ℝ(InLeapYear(TimeFromYear(𝔽(_year_)))). + 1. Return 28 + MathematicalInLeapYear(EpochTimeForYear(_year_)). @@ -683,11 +683,11 @@

1. Let _dayOfJan1st_ be ToISODayOfWeek(_year_, 1, 1). 1. If _dayOfJan1st_ is _friday_, then 1. Return the Year-Week Record { [[Week]]: _maxWeekNumber_, [[Year]]: _year_ - 1 }. - 1. If _dayOfJan1st_ is _saturday_, and InLeapYear(TimeFromYear(𝔽(_year_ - 1))) is *1*𝔽, then + 1. If _dayOfJan1st_ is _saturday_, and MathematicalInLeapYear(EpochTimeForYear(_year_ - 1)) is 1, then 1. Return the Year-Week Record { [[Week]]: _maxWeekNumber_. [[Year]]: _year_ - 1 }. 1. Return the Year-Week Record { [[Week]]: _maxWeekNumber_ - 1, [[Year]]: _year_ - 1 }. 1. If _week_ is _maxWeekNumber_, then - 1. Let _daysInYear_ be DaysInYear(𝔽(_year_)). + 1. Let _daysInYear_ be MathematicalDaysInYear(_year_). 1. Let _daysLaterInYear_ be _daysInYear_ - _dayOfYear_. 1. Let _daysAfterThursday_ be _thursday_ - _dayOfWeek_. 1. If _daysLaterInYear_ < _daysAfterThursday_, then @@ -844,9 +844,8 @@

1. Assert: IsValidISODate(_year_, _month_, _day_) is *true*. - 1. Let _epochDays_ be MakeDay(𝔽(year), 𝔽(month - 1), 𝔽(day)). - 1. Assert: _epochDays_ is finite. - 1. Return ℝ(DayWithinYear(MakeDate(_epochDays_, *+0*𝔽))) + 1. + 1. Let _epochDays_ be ISODateToEpochDays(year, month - 1, day). + 1. Return EpochTimeToDayInYear(EpochDaysToEpochMs(_epochDays_, 0)) + 1. @@ -864,11 +863,10 @@

1. Assert: IsValidISODate(_year_, _month_, _day_) is *true*. - 1. Let _epochDays_ be MakeDay(𝔽(year), 𝔽(month - 1), 𝔽(day)). - 1. Assert: _epochDays_ is finite. - 1. Let _dayOfWeek_ be WeekDay(MakeDate(_epochDays_, *+0*𝔽)). - 1. If _dayOfWeek_ = *+0*𝔽, return 7. - 1. Return ℝ(_dayOfWeek_). + 1. Let _epochDays_ be ISODateToEpochDays(year, month - 1, day). + 1. Let _dayOfWeek_ be EpochTimeToWeekDay(EpochDaysToEpochMs(_epochDays_, 0)). + 1. If _dayOfWeek_ = 0, return 7. + 1. Return _dayOfWeek_. @@ -1294,7 +1292,7 @@

Temporal.Calendar.prototype.daysInYear ( _temporalDateLike_ )

1. Assert: _calendar_.[[Identifier]] is *"iso8601"*. 1. If Type(_temporalDateLike_) is not Object or _temporalDateLike_ does not have an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], or [[InitializedTemporalYearMonth]] internal slot, then 1. Set _temporalDateLike_ to ? ToTemporalDate(_temporalDateLike_). - 1. Return DaysInYear(𝔽(_temporalDateLike_.[[ISOYear]])). + 1. Return 𝔽(MathematicalDaysInYear(_temporalDateLike_.[[ISOYear]])).
@@ -1332,7 +1330,7 @@

Temporal.Calendar.prototype.inLeapYear ( _temporalDateLike_ )

1. Assert: _calendar_.[[Identifier]] is *"iso8601"*. 1. If Type(_temporalDateLike_) is not Object or _temporalDateLike_ does not have an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], or [[InitializedTemporalYearMonth]] internal slot, then 1. Set _temporalDateLike_ to ? ToTemporalDate(_temporalDateLike_). - 1. If InLeapYear(TimeFromYear(𝔽(_temporalDateLike_.[[ISOYear]]))) is *1*𝔽, return *true*. + 1. If MathematicalInLeapYear(EpochTimeForYear(_temporalDateLike_.[[ISOYear]])) is 1, return *true*. 1. Return *false*. diff --git a/spec/duration.html b/spec/duration.html index c60905bffb..74718c15e2 100644 --- a/spec/duration.html +++ b/spec/duration.html @@ -1549,11 +1549,9 @@

If _earlier_ is later than _later_, then the result is negative. - 1. Let _epochDays1_ be MakeDay(𝔽(_earlier_.[[ISOYear]]), 𝔽(_earlier_.[[ISOMonth]] - 1), 𝔽(_earlier_.[[ISODay]])). - 1. Assert: _epochDays1_ is finite. - 1. Let _epochDays2_ be MakeDay(𝔽(_later_.[[ISOYear]]), 𝔽(_later_.[[ISOMonth]] - 1), 𝔽(_later_.[[ISODay]])). - 1. Assert: _epochDays2_ is finite. - 1. Return ℝ(_epochDays2_) - ℝ(_epochDays1_). + 1. Let _epochDays1_ be ISODateToEpochDays(_earlier_.[[ISOYear]], _earlier_.[[ISOMonth]] - 1, _earlier_.[[ISODay]]). + 1. Let _epochDays2_ be ISODateToEpochDays(_later_.[[ISOYear]], _later_.[[ISOMonth]] - 1, _later_.[[ISODay]]). + 1. Return _epochDays2_ - _epochDays1_. diff --git a/spec/intl.html b/spec/intl.html index d97066e5fd..eb1c1d425f 100644 --- a/spec/intl.html +++ b/spec/intl.html @@ -1033,14 +1033,7 @@

ToLocalTime ( _t_, _calendar_, _timeZone_ )

- [[RelatedYear]] - *undefined* - - - [[YearName]] - *undefined* - - +

ToLocalTime ( _t_, _calendar_, _timeZone_ )

[[Month]] `MonthFromTime(tz)` specified in ES2023's Month Number @@ -2172,7 +2165,7 @@

Temporal.Calendar.prototype.daysInYear ( _temporalDateLike_ )

1. If Type(_temporalDateLike_) is not Object or _temporalDateLike_ does not have an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], or [[InitializedTemporalYearMonth]] internal slot, then 1. Set _temporalDateLike_ to ? ToTemporalDate(_temporalDateLike_). 1. If _calendar_.[[Identifier]] is *"iso8601"*, then - 1. Return DaysInYear(𝔽(_temporalDateLike_.[[ISOYear]])). + 1. Return 𝔽(MathematicalDaysInYear(_temporalDateLike_.[[ISOYear]])). 1. Let _daysInYear_ be ! CalendarDateDaysInYear(_calendar_.[[Identifier]], _temporalDateLike_). 1. Return 𝔽(_daysInYear_). @@ -2209,7 +2202,7 @@

Temporal.Calendar.prototype.inLeapYear ( _temporalDateLike_ )

1. If Type(_temporalDateLike_) is not Object or _temporalDateLike_ does not have an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], or [[InitializedTemporalYearMonth]] internal slot, then 1. Set _temporalDateLike_ to ? ToTemporalDate(_temporalDateLike_). 1. If _calendar_.[[Identifier]] is *"iso8601"*, then - 1. If InLeapYear(TimeFromYear(𝔽(_temporalDateLike_.[[ISOYear]]))) is *1*𝔽, then + 1. If MathematicalInLeapYear(EpochTimeForYear(_temporalDateLike_.[[ISOYear]])) is 1, then 1. Let _inLeapYear_ be *true*. 1. Else, 1. Let _inLeapYear_ be *false*. diff --git a/spec/plaindate.html b/spec/plaindate.html index d5845b0e89..66b2671c3d 100644 --- a/spec/plaindate.html +++ b/spec/plaindate.html @@ -809,11 +809,9 @@

1. Return ! CreateDateDurationRecord(_years_, _months_, 0, _days_). 1. Else, 1. Assert: _largestUnit_ is *"day"* or *"week"*. - 1. Let _epochDays1_ be MakeDay(𝔽(_y1_), 𝔽(_m1_ - 1), 𝔽(_d1_)). - 1. Assert: _epochDays1_ is finite. - 1. Let _epochDays2_ be MakeDay(𝔽(_y2_), 𝔽(_m2_ - 1), 𝔽(_d2_)). - 1. Assert: _epochDays2_ is finite. - 1. Let _days_ be ℝ(_epochDays2_) - ℝ(_epochDays1_). + 1. Let _epochDays1_ be ISODateToEpochDays(_y1_, _m1_ - 1, _d1_). + 1. Let _epochDays2_ be ISODateToEpochDays(_y2_, _m2_ - 1, _d2_). + 1. Let _days_ be _epochDays2_ - _epochDays1_. 1. Let _weeks_ be 0. 1. If _largestUnit_ is *"week"*, then 1. Set _weeks_ to truncate(_days_ / 7). @@ -891,10 +889,9 @@

BalanceISODate ( - 1. Let _epochDays_ be MakeDay(𝔽(_year_), 𝔽(_month_ - 1), 𝔽(_day_)). - 1. Assert: _epochDays_ is finite. - 1. Let _ms_ be MakeDate(_epochDays_, *+0*𝔽). - 1. Return CreateISODateRecord(ℝ(YearFromTime(_ms_)), ℝ(MonthFromTime(_ms_)) + 1, ℝ(DateFromTime(_ms_))). + 1. Let _epochDays_ be ISODateToEpochDays(_year_, _month_ - 1, _day_). + 1. Let _ms_ be EpochDaysToEpochMs(_epochDays_, 0). + 1. Return CreateISODateRecord(EpochTimeToEpochYear(_ms_), EpochTimeToMonthInYear(_ms_) + 1, EpochTimeToDate(_ms_)). diff --git a/spec/timezone.html b/spec/timezone.html index 2d8f948799..fb700b5022 100644 --- a/spec/timezone.html +++ b/spec/timezone.html @@ -420,9 +420,9 @@

1. Assert: ! IsValidEpochNanoseconds(ℤ(_epochNanoseconds_)) is *true*. 1. Let _remainderNs_ be _epochNanoseconds_ modulo 106. 1. Let _epochMilliseconds_ be 𝔽((_epochNanoseconds_ - _remainderNs_) / 106). - 1. Let _year_ be ℝ(! YearFromTime(_epochMilliseconds_)). - 1. Let _month_ be ℝ(! MonthFromTime(_epochMilliseconds_)) + 1. - 1. Let _day_ be ℝ(! DateFromTime(_epochMilliseconds_)). + 1. Let _year_ be ! EpochTimeToEpochYear(_epochMilliseconds_). + 1. Let _month_ be ! EpochTimeToMonthInYear(_epochMilliseconds_) + 1. + 1. Let _day_ be ! EpochTimeToDate(_epochMilliseconds_). 1. Let _hour_ be ℝ(! HourFromTime(_epochMilliseconds_)). 1. Let _minute_ be ℝ(! MinFromTime(_epochMilliseconds_)). 1. Let _second_ be ℝ(! SecFromTime(_epochMilliseconds_)).