From aa2fc13de532df4374c60b379712e4fcbb17cd40 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 6 Nov 2020 16:34:39 -0800 Subject: [PATCH] Specify ZonedDateTime.until() and ZonedDateTime.since(). See: #569 --- spec/zoneddatetime.html | 89 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index b8e151e103..0ad03b05e1 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -673,8 +673,18 @@

Temporal.ZonedDateTime.prototype.until ( _other_ [ , _options_ ] )

1. Let _roundingMode_ be ? ToTemporalRoundingMode(_options_). 1. Let _maximum_ be ! MaximumTemporalDurationRoundingIncrement(_smallestUnit_). 1. Let _roundingIncrement_ be ? ToTemporalRoundingIncrement(_options_, _maximum_, *false*). - 1. TODO. - 1. Return ? CreateTemporalDuration(TODO). + 1. If _largestUnit_ is not one of *"years"*, *"months"*, *"weeks"*, or *"days"*, then + 1. Let _differenceNs_ be ? DifferenceInstant(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_). + 1. Let _balanceResult_ be ! BalanceDuration(0, 0, 0, 0, 0, 0, _differenceNs_, _largestUnit_). + 1. Let _result_ be the new Record { [[Years]]: 0, [[Months]]: 0, [[Weeks]]: 0, [[Days]]: _balanceResult_.[[Days]], [[Hours]]: _balanceResult_.[[Hours]], [[Minutes]]: _balanceResult_.[[Minutes]], [[Seconds]]: _balanceResult_.[[Seconds]], [[Milliseconds]]: _balanceResult_.[[Milliseconds]], [[Microseconds]]: _balanceResult_.[[Microseconds]], [[Nanoseconds]]: _balanceResult_.[[Nanoseconds]] }. + 1. Else, + 1. If ? TimeZoneEquals(_zonedDateTime_.[[TimeZone]], _other_.[[TimeZone]]) is *false*, then + 1. Throw a *RangeError* exception. + 1. Let _difference_ be ? DifferenceZonedDateTime(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _zonedDateTime_.[[TimeZone]], _zonedDateTime_.[[Calendar]], _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_, _zonedDateTime_). + 1. Let _instant_ be ? CreateTemporalInstant(_zonedDateTime_.[[Nanoseconds]]). + 1. Let _relativeTo_ be ? GetTemporalDateTimeFor(_zonedDateTime_.[[TimeZone]], _instant_, _zonedDateTime_.[[Calendar]]). + 1. Let _result_ be ? RoundDuration(_difference_.[[Years]], _difference_.[[Months]], _difference_.[[Weeks]], _difference_.[[Days]], _difference_.[[Hours]], _difference_.[[Minutes]], _difference_.[[Seconds]], _difference_.[[Milliseconds]], _difference_.[[Microseconds]], _difference_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_). + 1. Return ? CreateTemporalDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _result_.[[Hours]], _result_.[[Minutes]], _result_.[[Seconds]], _result_.[[Milliseconds]], _result_.[[Microseconds]], _result_.[[Nanoseconds]]). @@ -699,8 +709,18 @@

Temporal.ZonedDateTime.prototype.since ( _other_ [ , _options_ ] )

1. Set _roundingMode_ to ! NegateTemporalRoundingMode(_roundingMode_). 1. Let _maximum_ be ! MaximumTemporalDurationRoundingIncrement(_smallestUnit_). 1. Let _roundingIncrement_ be ? ToTemporalRoundingIncrement(_options_, _maximum_, *false*). - 1. TODO. - 1. Return ? CreateTemporalDuration(TODO). + 1. If _largestUnit_ is not one of *"years"*, *"months"*, *"weeks"*, or *"days"*, then + 1. Let _differenceNs_ be ? DifferenceInstant(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_). + 1. Let _balanceResult_ be ! BalanceDuration(0, 0, 0, 0, 0, 0, _differenceNs_, _largestUnit_). + 1. Let _result_ be the new Record { [[Years]]: 0, [[Months]]: 0, [[Weeks]]: 0, [[Days]]: _balanceResult_.[[Days]], [[Hours]]: _balanceResult_.[[Hours]], [[Minutes]]: _balanceResult_.[[Minutes]], [[Seconds]]: _balanceResult_.[[Seconds]], [[Milliseconds]]: _balanceResult_.[[Milliseconds]], [[Microseconds]]: _balanceResult_.[[Microseconds]], [[Nanoseconds]]: _balanceResult_.[[Nanoseconds]] }. + 1. Else, + 1. If ? TimeZoneEquals(_zonedDateTime_.[[TimeZone]], _other_.[[TimeZone]]) is *false*, then + 1. Throw a *RangeError* exception. + 1. Let _difference_ be ? DifferenceZonedDateTime(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _zonedDateTime_.[[TimeZone]], _zonedDateTime_.[[Calendar]], _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_, _zonedDateTime_). + 1. Let _instant_ be ? CreateTemporalInstant(_zonedDateTime_.[[Nanoseconds]]). + 1. Let _relativeTo_ be ? GetTemporalDateTimeFor(_zonedDateTime_.[[TimeZone]], _instant_, _zonedDateTime_.[[Calendar]]). + 1. Let _result_ be ? RoundDuration(_difference_.[[Years]], _difference_.[[Months]], _difference_.[[Weeks]], _difference_.[[Days]], _difference_.[[Hours]], _difference_.[[Minutes]], _difference_.[[Seconds]], _difference_.[[Milliseconds]], _difference_.[[Microseconds]], _difference_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_). + 1. Return ? CreateTemporalDuration(−_result_.[[Years]], −_result_.[[Months]], −_result_.[[Weeks]], −_result_.[[Days]], −_result_.[[Hours]], −_result_.[[Minutes]], −_result_.[[Seconds]], −_result_.[[Milliseconds]], −_result_.[[Microseconds]], −_result_.[[Nanoseconds]]). @@ -1303,5 +1323,66 @@

AddZonedDateTime ( _epochNanoseconds_, _timeZone_, _calendar_, _years_, _mon 1. Return ! AddInstant(_intermediateInstant_.[[Nanoseconds]], _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_). + + +

AdjustDayRelativeTo ( _dateDifference_, _direction_, _largestUnit_, _relativeTo_ )

+

+ The abstract operation AdjustDayRelativeTo adjusts _dateDifference_ by one day in the given _direction_, balancing it up to _largestUnit_ relative to the given Temporal.ZonedDateTime instance _relativeTo_. + The time units of _dateDifference_ are ignored, and the returned difference will have time units that are all zero. +

+ + 1. Assert: _direction_ is 1 or −1. + 1. Let _instant_ be ? CreateTemporalInstant(_relativeTo_.[[Nanoseconds]]). + 1. Let _relativeDateTime_ be ? GetTemporalDateTimeFor(_relativeTo_.[[TimeZone]], _instant_, _relativeTo_.[[Calendar]]). + 1. Let _oneDayEarlier_ be ? AddDateTime(_relativeDateTime_.[[ISOYear]], _relativeDateTime_.[[ISOMonth]], _relativeDateTime_.[[ISODay]], _relativeDateTime_.[[ISOHour]], _relativeDateTime_.[[ISOMinute]], _relativeDateTime_.[[ISOSecond]], _relativeDateTime_.[[ISOMillisecond]], _relativeDateTime_.[[ISOMicrosecond]], _relativeDateTime_.[[ISONanosecond]], _relativeTo_.[[Calendar]], _dateDifference_.[[Years]], _dateDifference_.[[Months]], _dateDifference_.[[Weeks]], _dateDifference_.[[Days]] + _direction_, 0, 0, 0, 0, 0, 0, *"constrain"*). + 1. Let _difference_ be ? DifferenceDateTime(_relativeDateTime_.[[ISOYear]], _relativeDateTime_.[[ISOMonth]], _relativeDateTime_.[[ISODay]], _relativeDateTime_.[[ISOHour]], _relativeDateTime_.[[ISOMinute]], _relativeDateTime_.[[ISOSecond]], _relativeDateTime_.[[ISOMillisecond]], _relativeDateTime_.[[ISOMicrosecond]], _relativeDateTime_.[[ISONanosecond]], _oneDayEarlier_.[[ISOYear]], _oneDayEarlier_.[[ISOMonth]], _oneDayEarlier_.[[ISODay]], _oneDayEarlier_.[[ISOHour]], _oneDayEarlier_.[[ISOMinute]], _oneDayEarlier_.[[ISOSecond]], _oneDayEarlier_.[[ISOMillisecond]], _oneDayEarlier_.[[ISOMicrosecond]], _oneDayEarlier_.[[ISONanosecond]], _calendar_, _largestUnit_). + 1. Return ? RoundDuration(_difference_.[[Years]], _difference_.[[Months]], _difference_.[[Weeks]], _difference_.[[Days]], _difference_.[[Hours]], _difference_.[[Minutes]], _difference_.[[Seconds]], _difference_.[[Milliseconds]], _difference_.[[Microseconds]], _difference_.[[Nanoseconds]], 1, *"days"*, *"ceil"*, _relativeDateTime_). + +
+ + +

DifferenceZonedDateTime ( _ns1_, _ns2_, _timeZone_, _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_ )

+

+ The abstract operation DifferenceZonedDateTime computes the difference between two exact times expressed in nanoseconds since the Unix epoch, and rounds the result according to the given parameters, taking calendar reckoning and time zone offset changes into account. +

+ + 1. Let _nsDifference_ be _ns2_ − _ns1_. + 1. If _nsDifference_ is 0, then + 1. Return the new Record { [[Years]]: 0, [[Months]]: 0, [[Weeks]]: 0, [[Days]]: 0, [[Hours]]: 0, [[Minutes]]: 0, [[Seconds]]: 0, [[Milliseconds]]: 0, [[Microseconds]]: 0, [[Nanoseconds]]: 0 }. + 1. Let _direction_ be ! Sign(_nsDifference_). + 1. Let _startInstant_ be ? CreateInstant(_ns1_). + 1. Let _startDateTime_ be ? GetTemporalDateTimeFor(_timeZone_, _startInstant_, _calendar_). + 1. Let _endInstant_ be ? CreateInstant(_ns2_). + 1. Let _endDateTime_ be ? GetTemporalDateTimeFor(_timeZone_, _endInstant_, _calendar_). + 1. Let _dateDifference_ be ? DifferenceDateTime(_startDateTime_.[[ISOYear]], _startDateTime_.[[ISOMonth]], _startDateTime_.[[ISODay]], _startDateTime_.[[ISOHour]], _startDateTime_.[[ISOMinute]], _startDateTime_.[[ISOSecond]], _startDateTime_.[[ISOMillisecond]], _startDateTime_.[[ISOMicrosecond]], _startDateTime_.[[ISONanosecond]], _endDateTime_.[[ISOYear]], _endDateTime_.[[ISOMonth]], _endDateTime_.[[ISODay]], _endDateTime_.[[ISOHour]], _endDateTime_.[[ISOMinute]], _endDateTime_.[[ISOSecond]], _endDateTime_.[[ISOMillisecond]], _endDateTime_.[[ISOMicrosecond]], _endDateTime_.[[ISONanosecond]], _calendar_, _largestUnit_). + 1. Let _intermediateNs_ be ? AddZonedDateTime(_ns1_, _timeZone_, _calendar_, _dateDifference_.[[Years]], _dateDifference_.[[Months]], _dateDifference_.[[Weeks]], _dateDifference_.[[Days]], 0, 0, 0, 0, 0, 0, *"constrain"*). + 1. If _direction_ = 1, then + 1. Repeat, while ! DurationSign(_dateDifference_.[[Years]], _dateDifference_.[[Months]], _dateDifference_.[[Weeks]], _dateDifference_.[[Days]], 0, 0, 0, 0, 0, 0) = 1 and _intermediateNs_ > _ns2_, + 1. Set _dateDifference_ to ? AdjustDayRelativeTo(_dateDifference_, −1, _largestUnit_, _relativeTo_). + 1. Set _intermediateNs_ to ? AddZonedDateTime(_ns1_, _timeZone_, _calendar_, _dateDifference_.[[Years]], _dateDifference_.[[Months]], _dateDifference_.[[Weeks]], _dateDifference_.[[Days]], 0, 0, 0, 0, 0, 0, *"constrain"*). + 1. Let _dayLengthNs_ be 0. + 1. Let _timeRemainderNs_ be 0. + 1. Let _done_ be *false*. + 1. Repeat, while _done_ is *false*, + 1. Let _oneDayFartherDuration_ be ? AdjustDayRelativeTo(_dateDifference_, _direction_, _largestUnit_, _relativeTo_). + 1. Let _oneDayFartherNs_ be ? AddZonedDateTime(_ns1_, _timeZone, _calendar_, _oneDayFartherDuration_.[[Years]], _oneDayFartherDuration_.[[Months]], _oneDayFartherDuration_.[[Weeks]], _oneDayFartherDuration_.[[Days]], 0, 0, 0, 0, 0, 0, *"constrain"*). + 1. Set _dayLengthNs_ to _oneDayFartherNs_ − _intermediateNs_. + 1. Set _timeRemainderNs_ to _ns2_ − _intermediateNs_. + 1. If (_timeRemainderNs_ − _dayLengthNs_) × _direction_ ≥ 0, then + 1. Set _dateDifference_ to _oneDayFartherDuration_. + 1. Set _intermediateNs_ to _oneDayFartherNs_. + 1. Else, + 1. Set _done_ to *true*. + 1. If _timeRemainderNs_ = 0, or _smallestUnit_ is one of *"years"*, *"months"*, *"weeks"*, or *"days"*, then + 1. Return the new Record { [[Years]]: _dateDifference_.[[Years]], [[Months]]: _dateDifference_.[[Months]], [[Weeks]]: _dateDifference_.[[Weeks]], [[Days]]: _dateDifference_.[[Days]], [[Hours]]: 0, [[Minutes]]: 0, [[Seconds]]: 0, [[Milliseconds]]: 0, [[Microseconds]]: 0, [[Nanoseconds]]: _timeRemainderNs_ }. + 1. Let _roundedTimeRemainderNs_ be ? DifferenceInstant(_intermediateNs_, _ns2_, _roundingIncrement_, _smallestUnit_, _roundingMode_). + 1. Let _timeDifference_ be ! BalanceDuration(0, 0, 0, 0, 0, 0, _roundedTimeRemainderNs_, *"hours"*). + 1. If (_roundedTimeRemainderNs_ − _dayLengthNs_) × _direction_ ≥ 0, then + 1. Set _dateDifference_ to ? AdjustDayRelativeTo(_dateDifference_, _direction_, _largestUnit_, _relativeTo_). + 1. Set _roundedTimeRemainderNs_ to _roundedTimeRemainderNs_ − _dayLengthNs_. + 1. 1. Return the new Record { [[Years]]: _dateDifference_.[[Years]], [[Months]]: _dateDifference_.[[Months]], [[Weeks]]: _dateDifference_.[[Weeks]], [[Days]]: _dateDifference_.[[Days]], [[Hours]]: 0, [[Minutes]]: 0, [[Seconds]]: 0, [[Milliseconds]]: 0, [[Microseconds]]: 0, [[Nanoseconds]]: _roundedTimeRemainderNs_ }. + 1. Return the new Record { [[Years]]: _dateDifference_.[[Years]], [[Months]]: _dateDifference_.[[Months]], [[Weeks]]: _dateDifference_.[[Weeks]], [[Days]]: _dateDifference_.[[Days]], [[Hours]]: _timeDifference_.[[Hours]], [[Minutes]]: _timeDifference_.[[Minutes]], [[Seconds]]: _timeDifference_.[[Seconds]], [[Milliseconds]]: _timeDifference_.[[Milliseconds]], [[Microseconds]]: _timeDifference_.[[Microseconds]], [[Nanoseconds]]: _timeDifference_.[[Nanoseconds]] }. + +