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

Editorial: Various changes encountered while working on Duration math #2609

Merged
merged 5 commits into from
Jun 21, 2023
Merged
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
43 changes: 21 additions & 22 deletions polyfill/lib/duration.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -445,29 +445,28 @@ export class Duration {
}
const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits);

let { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } =
ES.RoundDuration(
GetSlot(this, YEARS),
GetSlot(this, MONTHS),
GetSlot(this, WEEKS),
GetSlot(this, DAYS),
GetSlot(this, HOURS),
GetSlot(this, MINUTES),
GetSlot(this, SECONDS),
GetSlot(this, MILLISECONDS),
GetSlot(this, MICROSECONDS),
GetSlot(this, NANOSECONDS),
increment,
unit,
roundingMode
);
const { seconds, milliseconds, microseconds, nanoseconds } = ES.RoundDuration(
0,
0,
0,
0,
0,
0,
GetSlot(this, SECONDS),
GetSlot(this, MILLISECONDS),
GetSlot(this, MICROSECONDS),
GetSlot(this, NANOSECONDS),
increment,
unit,
roundingMode
);
return ES.TemporalDurationToString(
years,
months,
weeks,
days,
hours,
minutes,
GetSlot(this, YEARS),
GetSlot(this, MONTHS),
GetSlot(this, WEEKS),
GetSlot(this, DAYS),
GetSlot(this, HOURS),
GetSlot(this, MINUTES),
seconds,
milliseconds,
microseconds,
Expand Down
4 changes: 2 additions & 2 deletions spec/abstractops.html
Original file line number Diff line number Diff line change
Expand Up @@ -1555,11 +1555,11 @@ <h1>
<h1>
ParseTemporalDurationString (
_isoString_: a String,
)
): either a normal completion containing a Duration Record, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It parses the argument as an ISO 8601 duration string and returns a Duration Record.</dd>
<dd>It parses the argument as an ISO 8601 duration string.</dd>
</dl>
<emu-note>The value of ToIntegerWithTruncation(*""*) is 0.</emu-note>
<emu-note>Use of mathematical values rather than approximations is important to avoid off-by-one errors with input like "PT46H66M71.50040904S".</emu-note>
Expand Down
77 changes: 30 additions & 47 deletions spec/duration.html
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,8 @@ <h1>Temporal.Duration.prototype.round ( _roundTo_ )</h1>
1. Let _maximum_ be ! MaximumTemporalDurationRoundingIncrement(_smallestUnit_).
1. If _maximum_ is not *undefined*, perform ? ValidateTemporalRoundingIncrement(_roundingIncrement_, _maximum_, *false*).
1. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _relativeTo_).
1. Let _roundResult_ be (? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_)).[[DurationRecord]].
1. Let _roundRecord_ be ? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_).
1. Let _roundResult_ be _roundRecord_.[[DurationRecord]].
1. If _relativeTo_ has an [[InitializedTemporalZonedDateTime]] internal slot, then
1. Set _roundResult_ to ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _roundResult_.[[Days]], _roundResult_.[[Hours]], _roundResult_.[[Minutes]], _roundResult_.[[Seconds]], _roundResult_.[[Milliseconds]], _roundResult_.[[Microseconds]], _roundResult_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_).
1. Let _balanceResult_ be ? BalanceTimeDurationRelative(_roundResult_.[[Days]], _roundResult_.[[Hours]], _roundResult_.[[Minutes]], _roundResult_.[[Seconds]], _roundResult_.[[Milliseconds]], _roundResult_.[[Microseconds]], _roundResult_.[[Nanoseconds]], _largestUnit_, _relativeTo_).
Expand Down Expand Up @@ -473,29 +474,7 @@ <h1>Temporal.Duration.prototype.total ( _totalOf_ )</h1>
1. If _balanceResult_ is ~negative overflow~, return *-∞*<sub>𝔽</sub>.
1. Assert: _balanceResult_ is a Time Duration Record.
1. Let _roundRecord_ be ? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _balanceResult_.[[Days]], _balanceResult_.[[Hours]], _balanceResult_.[[Minutes]], _balanceResult_.[[Seconds]], _balanceResult_.[[Milliseconds]], _balanceResult_.[[Microseconds]], _balanceResult_.[[Nanoseconds]], 1, _unit_, *"trunc"*, _relativeTo_).
1. Let _roundResult_ be _roundRecord_.[[DurationRecord]].
1. If _unit_ is *"year"*, then
1. Let _whole_ be _roundResult_.[[Years]].
1. Else if _unit_ is *"month"*, then
1. Let _whole_ be _roundResult_.[[Months]].
1. Else if _unit_ is *"week"*, then
1. Let _whole_ be _roundResult_.[[Weeks]].
1. Else if _unit_ is *"day"*, then
1. Let _whole_ be _roundResult_.[[Days]].
1. Else if _unit_ is *"hour"*, then
1. Let _whole_ be _roundResult_.[[Hours]].
1. Else if _unit_ is *"minute"*, then
1. Let _whole_ be _roundResult_.[[Minutes]].
1. Else if _unit_ is *"second"*, then
1. Let _whole_ be _roundResult_.[[Seconds]].
1. Else if _unit_ is *"millisecond"*, then
1. Let _whole_ be _roundResult_.[[Milliseconds]].
1. Else if _unit_ is *"microsecond"*, then
1. Let _whole_ be _roundResult_.[[Microseconds]].
1. Else,
1. Assert: _unit_ is *"nanosecond"*.
1. Let _whole_ be _roundResult_.[[Nanoseconds]].
1. Return 𝔽(_whole_ + _roundRecord_.[[Remainder]]).
1. Return 𝔽(_roundRecord_.[[Total]]).
</emu-alg>
</emu-clause>

Expand All @@ -514,8 +493,9 @@ <h1>Temporal.Duration.prototype.toString ( [ _options_ ] )</h1>
1. Let _smallestUnit_ be ? GetTemporalUnit(_options_, *"smallestUnit"*, ~time~, *undefined*).
1. If _smallestUnit_ is *"hour"* or *"minute"*, throw a *RangeError* exception.
1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_).
1. Let _result_ be (? RoundDuration(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_)).[[DurationRecord]].
1. Return ! TemporalDurationToString(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _result_.[[Hours]], _result_.[[Minutes]], _result_.[[Seconds]], _result_.[[Milliseconds]], _result_.[[Microseconds]], _result_.[[Nanoseconds]], _precision_.[[Precision]]).
1. Let _roundRecord_ be ? RoundDuration(0, 0, 0, 0, 0, 0, _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_).
1. Let _result_ be _roundRecord_.[[DurationRecord]].
1. Return ! TemporalDurationToString(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _result_.[[Seconds]], _result_.[[Milliseconds]], _result_.[[Microseconds]], _result_.[[Nanoseconds]], _precision_.[[Precision]]).
</emu-alg>
</emu-clause>

Expand Down Expand Up @@ -825,11 +805,11 @@ <h1>
_milliseconds_: an integer,
_microseconds_: an integer,
_nanoseconds_: an integer,
)
): either a normal completion containing a Duration Record, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It returns a Duration Record.</dd>
<dd></dd>
</dl>
<emu-alg>
1. If ! IsValidDuration(_years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_) is *false*, throw a *RangeError* exception.
Expand Down Expand Up @@ -1582,11 +1562,11 @@ <h1>
_mus2_: an integer,
_ns2_: an integer,
_relativeTo_: *undefined*, a Temporal.PlainDate, or a Temporal.ZonedDateTime,
)
): either a normal completion containing a Duration Record, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It adds the components of a second duration represented by _y2_ through _ns2_ to those of a first duration represented by _y1_ through _ns1_, and balances the duration relative to the given date _relativeTo_, to ensure that no mixed signs remain in the result. The result is returned as a Duration Record.</dd>
<dd>It adds the components of a second duration represented by _y2_ through _ns2_ to those of a first duration represented by _y1_ through _ns1_, and balances the duration relative to the given date _relativeTo_, to ensure that no mixed signs remain in the result.</dd>
</dl>
<emu-alg>
1. Let _largestUnit1_ be ! DefaultTemporalLargestUnit(_y1_, _mon1_, _w1_, _d1_, _h1_, _min1_, _s1_, _ms1_, _mus1_).
Expand Down Expand Up @@ -1707,11 +1687,15 @@ <h1>
_unit_: a String,
_roundingMode_: a String,
optional _relativeTo_: *undefined*, a Temporal.PlainDate, or a Temporal.ZonedDateTime,
)
): either a normal completion containing a Record with fields [[DurationRecord]] (a Duration Record) and [[Total]] (a mathematical value), or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It rounds a duration (denoted by _years_ through _nanoseconds_) according to the rounding parameters _unit_, _increment_, and _roundingMode_, and returns a Record with the Duration Record result in its [[DurationRecord]] field, as well as the remainder from the rounding operation in its [[Remainder]] field. For rounding involving calendar units, the _relativeTo_ parameter is required.</dd>
<dd>
It rounds a duration (denoted by _years_ through _nanoseconds_) according to the rounding parameters _unit_, _increment_, and _roundingMode_, and returns a Record with the Duration Record result in its [[DurationRecord]] field.
It also returns the total of the smallest unit before the rounding operation in its [[Total]] field, for use in `Temporal.Duration.prototype.total`.
For rounding involving calendar units, the _relativeTo_ parameter is required.
</dd>
</dl>
<emu-alg>
1. If _relativeTo_ is not present, set _relativeTo_ to *undefined*.
Expand Down Expand Up @@ -1740,7 +1724,7 @@ <h1>
1. Else,
1. Let _fractionalSeconds_ be _nanoseconds_ &times; 10<sup>-9</sup> + _microseconds_ &times; 10<sup>-6</sup> + _milliseconds_ &times; 10<sup>-3</sup> + _seconds_.
1. Assert: _fractionalDays_ is not used below.
1. Let _remainder_ be *undefined*.
1. Let _total_ be ~unset~.
1. If _unit_ is *"year"*, then
1. Let _yearsDuration_ be ! CreateTemporalDuration(_years_, 0, 0, 0, 0, 0, 0, 0, 0, 0).
1. If _calendar_ is an Object, then
Expand Down Expand Up @@ -1771,7 +1755,7 @@ <h1>
1. Let _oneYearDays_ be _moveResult_.[[Days]].
1. Let _fractionalYears_ be _years_ + _fractionalDays_ / abs(_oneYearDays_).
1. Set _years_ to RoundNumberToIncrement(_fractionalYears_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalYears_ - _years_.
1. Set _total_ to _fractionalYears_.
1. Set _months_ and _weeks_ to 0.
1. Else if _unit_ is *"month"*, then
1. Let _yearsMonths_ be ! CreateTemporalDuration(_years_, _months_, 0, 0, 0, 0, 0, 0, 0, 0).
Expand All @@ -1798,7 +1782,7 @@ <h1>
1. Set _oneMonthDays_ to _moveResult_.[[Days]].
1. Let _fractionalMonths_ be _months_ + _fractionalDays_ / abs(_oneMonthDays_).
1. Set _months_ to RoundNumberToIncrement(_fractionalMonths_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalMonths_ - _months_.
1. Set _total_ to _fractionalMonths_.
1. Set _weeks_ to 0.
1. Else if _unit_ is *"week"*, then
1. If _fractionalDays_ &lt; 0, let _sign_ be -1; else, let _sign_ be 1.
Expand All @@ -1818,43 +1802,42 @@ <h1>
1. Set _oneWeekDays_ to _moveResult_.[[Days]].
1. Let _fractionalWeeks_ be _weeks_ + _fractionalDays_ / abs(_oneWeekDays_).
1. Set _weeks_ to RoundNumberToIncrement(_fractionalWeeks_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalWeeks_ - _weeks_.
1. Set _total_ to _fractionalWeeks_.
1. Else if _unit_ is *"day"*, then
1. Set _days_ to RoundNumberToIncrement(_fractionalDays_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalDays_ - _days_.
1. Set _total_ to _fractionalDays_.
1. Else if _unit_ is *"hour"*, then
1. Let _fractionalHours_ be (_fractionalSeconds_ / 60 + _minutes_) / 60 + _hours_.
1. Set _hours_ to RoundNumberToIncrement(_fractionalHours_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalHours_ - _hours_.
1. Set _total_ to _fractionalHours_.
1. Set _minutes_, _seconds_, _milliseconds_, _microseconds_, and _nanoseconds_ to 0.
1. Else if _unit_ is *"minute"*, then
1. Let _fractionalMinutes_ be _fractionalSeconds_ / 60 + _minutes_.
1. Set _minutes_ to RoundNumberToIncrement(_fractionalMinutes_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalMinutes_ - _minutes_.
1. Set _total_ to _fractionalMinutes_.
1. Set _seconds_, _milliseconds_, _microseconds_, and _nanoseconds_ to 0.
1. Else if _unit_ is *"second"*, then
1. Set _seconds_ to RoundNumberToIncrement(_fractionalSeconds_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalSeconds_ - _seconds_.
1. Set _total_ to _fractionalSeconds_.
1. Set _milliseconds_, _microseconds_, and _nanoseconds_ to 0.
1. Else if _unit_ is *"millisecond"*, then
1. Let _fractionalMilliseconds_ be _nanoseconds_ &times; 10<sup>-6</sup> + _microseconds_ &times; 10<sup>-3</sup> + _milliseconds_.
1. Set _milliseconds_ to RoundNumberToIncrement(_fractionalMilliseconds_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalMilliseconds_ - _milliseconds_.
1. Set _total_ to _fractionalMilliseconds_.
1. Set _microseconds_ and _nanoseconds_ to 0.
1. Else if _unit_ is *"microsecond"*, then
1. Let _fractionalMicroseconds_ be _nanoseconds_ &times; 10<sup>-3</sup> + _microseconds_.
1. Set _microseconds_ to RoundNumberToIncrement(_fractionalMicroseconds_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalMicroseconds_ - _microseconds_.
1. Set _total_ to _fractionalMicroseconds_.
1. Set _nanoseconds_ to 0.
1. Else,
1. Assert: _unit_ is *"nanosecond"*.
1. Set _remainder_ to _nanoseconds_.
1. Set _total_ to _nanoseconds_.
1. Set _nanoseconds_ to RoundNumberToIncrement(_nanoseconds_, _increment_, _roundingMode_).
1. Set _remainder_ to _remainder_ - _nanoseconds_.
1. Let _duration_ be ? CreateDurationRecord(_years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_).
1. Return the Record {
[[DurationRecord]]: _duration_,
[[Remainder]]: _remainder_
[[Total]]: _total_
}.
</emu-alg>
</emu-clause>
Expand All @@ -1876,12 +1859,12 @@ <h1>
_unit_: a String,
_roundingMode_: a String,
_relativeTo_: *undefined*, a Temporal.PlainDate, or a Temporal.ZonedDateTime,
)
): either a normal completion containing a Duration Record, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It adjusts, if necessary, a duration that was rounded to a unit of hours or lower relative to a Temporal.ZonedDateTime, and returns the result as a Duration Record.
It adjusts, if necessary, a duration that was rounded to a unit of hours or lower relative to a Temporal.ZonedDateTime, and returns the result.
On a calendar day that is not 24 hours in length due to time zone offset changes, it is possible for a duration's time units to round up to exceed the day's length.
In this case, the days part of the duration is adjusted by one, and the time part is re-rounded.
</dd>
Expand Down
2 changes: 1 addition & 1 deletion spec/instant.html
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ <h1>
1. Let _microseconds_ be remainder(truncate(_difference_ / 1000), 1000).
1. Let _milliseconds_ be remainder(truncate(_difference_ / 10<sup>6</sup>), 1000).
1. Let _seconds_ be truncate(_difference_ / 10<sup>9</sup>).
1. Let _roundResult_ be ! RoundDuration(0, 0, 0, 0, 0, 0, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_, _roundingIncrement_, _smallestUnit_, _largestUnit_, _roundingMode_).
1. Let _roundResult_ be ! RoundDuration(0, 0, 0, 0, 0, 0, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_, _roundingIncrement_, _smallestUnit_, _roundingMode_).
1. Assert: _roundResult_.[[Days]] is 0.
1. Return ! BalanceTimeDuration(0, _roundResult_.[[Hours]], _roundResult_.[[Minutes]], _roundResult_.[[Seconds]], _roundResult_.[[Milliseconds]], _roundResult_.[[Microseconds]], _roundResult_.[[Nanoseconds]], _largestUnit_).
</emu-alg>
Expand Down
3 changes: 2 additions & 1 deletion spec/plaindate.html
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,8 @@ <h1>
1. Perform ! CreateDataPropertyOrThrow(_resolvedOptions_, *"largestUnit"*, _settings_.[[LargestUnit]]).
1. Let _result_ be ? CalendarDateUntil(_temporalDate_.[[Calendar]], _temporalDate_, _other_, _resolvedOptions_).
1. If _settings_.[[SmallestUnit]] is not *"day"* or _settings_.[[RoundingIncrement]] &ne; 1, then
1. Set _result_ to (? RoundDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], 0, 0, 0, 0, 0, 0, _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _temporalDate_)).[[DurationRecord]].
1. Let _roundRecord_ be ? RoundDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], 0, 0, 0, 0, 0, 0, _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _temporalDate_).
1. Set _result_ to _roundRecord_.[[DurationRecord]].
1. Return ! CreateTemporalDuration(_sign_ &times; _result_.[[Years]], _sign_ &times; _result_.[[Months]], _sign_ &times; _result_.[[Weeks]], _sign_ &times; _result_.[[Days]], 0, 0, 0, 0, 0, 0).
</emu-alg>
</emu-clause>
Expand Down
Loading