Skip to content
Closed
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
63 changes: 27 additions & 36 deletions spec/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -525,42 +525,33 @@ <h1>
</dd>
</dl>
<emu-alg>
1. If _calendar_ is *"iso8601"*, then
1. Let _sign_ be -CompareISODate(_one_, _two_).
1. If _sign_ = 0, return ZeroDateDuration().
1. Let _years_ be 0.
1. If _largestUnit_ is ~year~, then
1. Let _candidateYears_ be _sign_.
1. Repeat, while ISODateSurpasses(_sign_, _one_.[[Year]] + _candidateYears_, _one_.[[Month]], _one_.[[Day]], _two_) is *false*,
1. Set _years_ to _candidateYears_.
1. Set _candidateYears_ to _candidateYears_ + _sign_.
1. Let _months_ be 0.
1. If _largestUnit_ is ~year~ or _largestUnit_ is ~month~, then
1. Let _candidateMonths_ be _sign_.
1. Let _intermediate_ be BalanceISOYearMonth(_one_.[[Year]] + _years_, _one_.[[Month]] + _candidateMonths_).
1. Repeat, while ISODateSurpasses(_sign_, _intermediate_.[[Year]], _intermediate_.[[Month]], _one_.[[Day]], _two_) is *false*,
1. Set _months_ to _candidateMonths_.
1. Set _candidateMonths_ to _candidateMonths_ + _sign_.
1. Set _intermediate_ to BalanceISOYearMonth(_intermediate_.[[Year]], _intermediate_.[[Month]] + _sign_).
1. Set _intermediate_ to BalanceISOYearMonth(_one_.[[Year]] + _years_, _one_.[[Month]] + _months_).
1. Let _constrained_ be ! RegulateISODate(_intermediate_.[[Year]], _intermediate_.[[Month]], _one_.[[Day]], ~constrain~).
1. Let _weeks_ be 0.
1. If _largestUnit_ is ~week~, then
1. Let _candidateWeeks_ be _sign_.
1. Set _intermediate_ to BalanceISODate(_constrained_.[[Year]], _constrained_.[[Month]], _constrained_.[[Day]] + 7 × _candidateWeeks_).
1. Repeat, while ISODateSurpasses(_sign_, _intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]], _two_) is *false*,
1. Set _weeks_ to _candidateWeeks_.
1. Set _candidateWeeks_ to _candidateWeeks_ + sign.
1. Set _intermediate_ to BalanceISODate(_intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]] + 7 × _sign_).
1. Let _days_ be 0.
1. Let _candidateDays_ be _sign_.
1. Set _intermediate_ to BalanceISODate(_constrained_.[[Year]], _constrained_.[[Month]], _constrained_.[[Day]] + 7 × _weeks_ + _candidateDays_).
1. Repeat, while ISODateSurpasses(_sign_, _intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]], _two_) is *false*,
1. Set _days_ to _candidateDays_.
1. Set _candidateDays_ to _candidateDays_ + _sign_.
1. Set _intermediate_ to BalanceISODate(_intermediate_.[[Year]], _intermediate_.[[Month]], _intermediate_.[[Day]] + _sign_).
1. Return ! CreateDateDurationRecord(_years_, _months_, _weeks_, _days_).
1. Return an implementation-defined Date Duration Record as described above.
1. Let _sign_ be -CompareISODate(_one_, _two_).
1. If _sign_ = 0, return ZeroDateDuration().
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double-check that my signs are correct and not negated.

  1. If one < two:
    1. CompareISODate(one, two) == -1, so sign = 1
    2. Inside the loop, we increment the duration by 1
    3. The loop condition checks CompareISODate(intermediate, two):
      1. The first time, intermediate is one, so the return value is -1, which does not equal sign, so the loop runs
      2. At some point after that, intermediate will be greater than two, at which point the return value is 1, the loop terminates, and the duration is decremented back to the value before the excess occurred
      3. Note: If intermediate and two are ever equal, the loop will run one last time, and the value of duration that caused the two values to be equal will become the resolved duration
  2. If one > two:
    1. CompareISODate(one, two) == 1, so sign == -1
    2. (all other steps should still work, except with signs flipped)

1. Let _duration_ be ! CreateDateDurationRecord(0, 0, 0, 0).
1. If _largestUnit_ is ~year~, then
1. Let _intermediate_ be _one_.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_intermediate_ needs to be initialized to something that is on the same side of _two_ as _one_ is, so that the body of the loop runs at least once. I pick _one_ since it always satisfies that criterion.

1. Repeat, while CompareISODate(_intermediate_, _two_) != _sign_,
1. Set _duration_.[[Years]] to _duration_.[[Years]] + _sign_.
1. Set _intermediate_ to ! CalendarDateAdd(_calendar_, _one_, _duration_, ~constrain~).
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might need to refactor CalendarDateAdd in order to make it infallible. I guess it's possible that some dates really close to the boundary would resolve to intermediates that are out of bounds, but I don't want those to cause exceptions to be thrown.

1. Set _duration_.[[Years]] to _duration_.[[Years]] - _sign_.
1. If _largestUnit_ is ~year~ or _largestUnit_ is ~month~, then
1. Let _intermediate_ be _one_.
1. Repeat, while CompareISODate(_intermediate_, _two_) != _sign_,
1. Set _duration_.[[Months]] to _duration_.[[Months]] + _sign_.
1. Set _intermediate_ to ! CalendarDateAdd(_calendar_, _one_, _duration_, ~constrain~).
1. Set _duration_.[[Months]] to _duration_.[[Months]] - _sign_.
1. If _largestUnit_ is ~week~, then
1. Let _intermediate_ be _one_.
1. Repeat, while CompareISODate(_intermediate_, _two_) != _sign_,
1. Set _duration_.[[Weeks]] to _duration_.[[Weeks]] + _sign_.
1. Set _intermediate_ to ! CalendarDateAdd(_calendar_, _one_, _duration_, ~constrain~).
1. Set _duration_.[[Weeks]] to _duration_.[[Weeks]] - _sign_.
1. Let _intermediate_ be _one_.
1. Repeat, while CompareISODate(_intermediate_, _two_) != _sign_,
1. Set _duration_.[[Days]] to _duration_.[[Days]] + _sign_.
1. Set _intermediate_ to ! CalendarDateAdd(_calendar_, _one_, _duration_, ~constrain~).
1. Set _duration_.[[Days]] to _duration_.[[Days]] - _sign_.
1. Return ! _duration_.
</emu-alg>
</emu-clause>

Expand Down