From b5b1f0aba53627c2be6e6b4899fc12f4e4d7e911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Tue, 29 Oct 2024 08:30:37 +0100 Subject: [PATCH 1/6] Editorial: Add "local-offset time value" for time values with local time zone offset applied MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multiple operations define their inputs as "time values", but actually allow time values adjusted with a local time zone offset. Add "local-offset time value" which is a "time value" adjusted with a time zone offset. Time zone offsets are restricted to the exclusive range Β±86'400'000 milliseconds. --- spec.html | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/spec.html b/spec.html index 9eb1d1153d..b717bed3dc 100644 --- a/spec.html +++ b/spec.html @@ -32580,7 +32580,7 @@

Date Objects

Overview of Date Objects and Definitions of Abstract Operations

-

The following abstract operations operate on time values (defined in ). Note that, in every case, if any argument to one of these functions is *NaN*, the result will be *NaN*.

+

The following abstract operations operate on time values and local-offset time values. Note that, in every case, if any argument to one of these functions is *NaN*, the result will be *NaN*.

Time Values and Time Range

@@ -32589,6 +32589,7 @@

Time Values and Time Range

Time values do not account for UTC leap secondsβ€”there are no time values representing instants within positive leap seconds, and there are time values representing instants removed from the UTC timeline by negative leap seconds. However, the definition of time values nonetheless yields piecewise alignment with UTC, with discontinuities only at leap second boundaries and zero difference outside of leap seconds.

A Number can exactly represent all integers from -9,007,199,254,740,992 to 9,007,199,254,740,992 ( and ). A time value supports a slightly smaller range of -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds. This yields a supported time value range of exactly -100,000,000 days to 100,000,000 days relative to midnight at the beginning of 1 January 1970 UTC.

The exact moment of midnight at the beginning of 1 January 1970 UTC is represented by the time value *+0*𝔽.

+

An ECMAScript local-offset time value is a time value adjusted by a time zone offset. Time zone offsets are integers in the exclusive range -86,400,000 to 86,400,000.

In the proleptic Gregorian calendar, leap years are precisely those which are both divisible by 4 and either divisible by 400 or not divisible by 100.

The 400 year cycle of the proleptic Gregorian calendar contains 97 leap years. This yields an average of 365.2425 days per year, which is 31,556,952,000 milliseconds. Therefore, the maximum range a Number could represent exactly with millisecond precision is approximately -285,426 to 285,426 years relative to 1970. The smaller range supported by a time value as specified in this section is approximately -273,790 to 273,790 years relative to 1970.

@@ -32610,7 +32611,7 @@

Time-related Constants

Day ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number

@@ -32625,7 +32626,7 @@

TimeWithinDay ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the interval from *+0*𝔽 (inclusive) to msPerDay (exclusive)

@@ -32695,7 +32696,7 @@

YearFromTime ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number

@@ -32710,7 +32711,7 @@

DayWithinYear ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *+0*𝔽 to *365*𝔽

@@ -32723,7 +32724,7 @@

InLeapYear ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): *+0*𝔽 or *1*𝔽

@@ -32738,7 +32739,7 @@

MonthFromTime ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *+0*𝔽 to *11*𝔽

@@ -32767,7 +32768,7 @@

DateFromTime ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *1*𝔽 to *31*𝔽

@@ -32797,7 +32798,7 @@

WeekDay ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *+0*𝔽 to *6*𝔽

@@ -32812,7 +32813,7 @@

HourFromTime ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *+0*𝔽 to *23*𝔽

@@ -32827,7 +32828,7 @@

MinFromTime ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *+0*𝔽 to *59*𝔽

@@ -32842,7 +32843,7 @@

SecFromTime ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *+0*𝔽 to *59*𝔽

@@ -32857,7 +32858,7 @@

msFromTime ( - _t_: a finite time value, + _t_: a finite local-offset time value, ): an integral Number in the inclusive interval from *+0*𝔽 to *999*𝔽

@@ -33069,7 +33070,7 @@

SystemTimeZoneIdentifier ( ): a String

LocalTime ( _t_: a finite time value, - ): an integral Number + ): a local-offset time value

description
@@ -33094,7 +33095,7 @@

It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

-

Two different input time values _t_UTC are converted to the same local time tlocal at a negative time zone transition when there are repeated times (e.g. the daylight saving time ends or the time zone adjustment is decreased.).

+

Two different input time values _t_UTC are converted to the same local-offset time value tlocal at a negative time zone transition when there are repeated times (e.g. the daylight saving time ends or the time zone adjustment is decreased.).

LocalTime(UTC(_t_local)) is not necessarily always equal to _t_local. Correspondingly, UTC(LocalTime(_t_UTC)) is not necessarily always equal to _t_UTC.

@@ -33131,7 +33132,7 @@

1. Return _t_ - 𝔽(_offsetMs_).

- Input _t_ is nominally a time value but may be any Number value. + Input _t_ is nominally a local-offset time value but may be any Number value. The algorithm must not limit _t_ to the time value range, so that inputs corresponding with a boundary of the time value range can be supported regardless of local UTC offset. For example, the maximum time value is 8.64 Γ— 1015, corresponding with *"+275760-09-13T00:00:00Z"*. In an environment where the local time zone offset is ahead of UTC by 1 hour at that instant, it is represented by the larger input of 8.64 Γ— 1015 + 3.6 Γ— 106, corresponding with *"+275760-09-13T01:00:00+01:00"*. From e8051bb9815cf3bdb4f2a36730a91da2cdf8844b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Tue, 29 Oct 2024 08:37:34 +0100 Subject: [PATCH 2/6] Editorial: Handle too large inputs early in UTC Return `NaN` if `t` exceeds the "local time value" range, because operations called within `UTC` expect their arguments to be "local time values" and not arbitrarily large integers. --- spec.html | 1 + 1 file changed, 1 insertion(+) diff --git a/spec.html b/spec.html index b717bed3dc..cb2167fefb 100644 --- a/spec.html +++ b/spec.html @@ -33115,6 +33115,7 @@

1. If _t_ is not finite, return *NaN*. + 1. If abs(ℝ(_t_)) β‰₯ 8.64 Γ— 1015 + ℝ(msPerDay), return *NaN*. 1. Let _systemTimeZoneIdentifier_ be SystemTimeZoneIdentifier(). 1. If IsTimeZoneOffsetString(_systemTimeZoneIdentifier_) is *true*, then 1. Let _offsetNs_ be ParseTimeZoneOffsetString(_systemTimeZoneIdentifier_). From 917cf0cec374c059f6f06014deafddbdb11da0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Tue, 29 Oct 2024 08:48:24 +0100 Subject: [PATCH 3/6] Editorial: Restrict GetNamedTimeZoneOffsetNanoseconds return values less than 24 hours Fixes #3101 --- spec.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index cb2167fefb..d50f738053 100644 --- a/spec.html +++ b/spec.html @@ -32967,7 +32967,7 @@

GetNamedTimeZoneOffsetNanoseconds ( _timeZoneIdentifier_: a String, _epochNanoseconds_: a BigInt, - ): an integer + ): an integer in the exclusive interval from -8.64 Γ— 1013 to 8.64 Γ— 1013

@@ -33503,7 +33503,7 @@

ParseTimeZoneOffsetString ( _offsetString_: a String, - ): an integer + ): an integer in the exclusive interval from -8.64 Γ— 1013 to 8.64 Γ— 1013

description
From e4aec515b51dfc847f78a8ddae868a060c1c1875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Thu, 31 Oct 2024 08:55:21 +0100 Subject: [PATCH 4/6] Editorial: Narrow input and output types for MakeDay, MakeTime, and MakeDate --- spec.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec.html b/spec.html index d50f738053..82e9f92ef6 100644 --- a/spec.html +++ b/spec.html @@ -33162,7 +33162,7 @@

_min_: a Number, _sec_: a Number, _ms_: a Number, - ): a Number + ): an integral Number or *NaN*

description
@@ -33187,7 +33187,7 @@

_year_: a Number, _month_: a Number, _date_: a Number, - ): a Number + ): an integral Number or *NaN*

description
@@ -33209,9 +33209,9 @@

MakeDate ( - _day_: a Number, - _time_: a Number, - ): a Number + _day_: an integral Number or *NaN*, + _time_: an integral Number or *NaN*, + ): an integral Number or *NaN*

description
From 6d7452a49b5f11558e5a256453a3203135703d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Thu, 31 Oct 2024 09:03:26 +0100 Subject: [PATCH 5/6] Editorial: Narrow output type for TimeClip --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 82e9f92ef6..0db4a58794 100644 --- a/spec.html +++ b/spec.html @@ -33247,7 +33247,7 @@

TimeClip ( _time_: a Number, - ): a Number + ): a time value

description
From 03ddef504268287d2b8e1316e6ba5766e6634457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Thu, 31 Oct 2024 09:31:42 +0100 Subject: [PATCH 6/6] Fixup: Review suggestion from gibson042 --- spec.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 0db4a58794..8bde1aa5c8 100644 --- a/spec.html +++ b/spec.html @@ -32589,7 +32589,12 @@

Time Values and Time Range

Time values do not account for UTC leap secondsβ€”there are no time values representing instants within positive leap seconds, and there are time values representing instants removed from the UTC timeline by negative leap seconds. However, the definition of time values nonetheless yields piecewise alignment with UTC, with discontinuities only at leap second boundaries and zero difference outside of leap seconds.

A Number can exactly represent all integers from -9,007,199,254,740,992 to 9,007,199,254,740,992 ( and ). A time value supports a slightly smaller range of -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds. This yields a supported time value range of exactly -100,000,000 days to 100,000,000 days relative to midnight at the beginning of 1 January 1970 UTC.

The exact moment of midnight at the beginning of 1 January 1970 UTC is represented by the time value *+0*𝔽.

-

An ECMAScript local-offset time value is a time value adjusted by a time zone offset. Time zone offsets are integers in the exclusive range -86,400,000 to 86,400,000.

+

An ECMAScript local-offset time value is a time value adjusted by a time zone offset that is an integer number of milliseconds in the interval from -86,400,000 (exclusive) to 86,400,000 (exclusive). A local-offset time value represents a local date and time of day, specifically the UTC date and time of day corresponding an identical time value, ignoring range limits. For example, a local-offset time value of *60000*𝔽 represents time of day 00:01 on 1 January 1970, and could equivalently come from any of the following:

+
    +
  • local offset +00:00 = *+0*𝔽 at epoch time 1970-01-01T00:01Z = *60000*𝔽
  • +
  • local offset +01:00 = *3600000*𝔽 at epoch time 1969-12-31T23:01Z = 𝔽(-msPerHour + 60000) = *-3540000*𝔽
  • +
  • local offset -05:00 = 𝔽(-5 Γ— msPerHour) = *-18000000*𝔽 at epoch time 1970-01-01T05:01Z = 𝔽(5 Γ— msPerHour + 60000) = *18060000*𝔽
  • +

In the proleptic Gregorian calendar, leap years are precisely those which are both divisible by 4 and either divisible by 400 or not divisible by 100.

The 400 year cycle of the proleptic Gregorian calendar contains 97 leap years. This yields an average of 365.2425 days per year, which is 31,556,952,000 milliseconds. Therefore, the maximum range a Number could represent exactly with millisecond precision is approximately -285,426 to 285,426 years relative to 1970. The smaller range supported by a time value as specified in this section is approximately -273,790 to 273,790 years relative to 1970.