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

RFC 5545 vs DST questions for IETF calendar standards ("calext") group #702

Closed
justingrant opened this issue Jun 24, 2020 · 5 comments
Closed
Labels
zoned-type Part of the effort for a type with timestamp+timezone
Milestone

Comments

@justingrant
Copy link
Collaborator

justingrant commented Jun 24, 2020

#700 Get contact info (@littledan do you know?) for IETF calendar standards group to ask them questions about RFC 5545 corner cases.

What's the best way to contact the IETF calext working group who are the owners of the successor specs to RFC 5545 (iCalendar)? I'm asking because #700 has a few questions below about corner cases in RFC 5545 that the calext working group may have insights about.

1) How to handle DST-ambiguous local times when adding/subtracting RFC 5545 durations?

RFC 5545 says:

The duration of a week or a day depends on its position in the calendar. In the case of discontinuities in the time scale, such as the change from standard time to daylight time and back, the computation of the exact duration requires the subtraction or addition of the change of duration of the discontinuity.

Translating this into Temporal terms, it means that RFC5545-compliant math should add/subtract date units using DateTime math, but should add/subtract time units using Absolute math. A naive implementation could be something like this:

function plusRfc5545(absolute, timeZone, duration, options) {
  const dateTime = absolute.inTimeZone(timeZone);
  const {timeDuration, dateDuration} = splitDuration(duration);
  const intermediateDateTime = dateTime.plus(dateDuration); 
  const intermediateAbsolute = intermediate.inTimeZone(timeZone, options);
  const final = intermediateAbsolute.plus (timeDuration);
  return final;
}

The problem is that intermediate.inTimeZone(timeZone, options) will do disambiguation in the middle of the duration, which seems really confusing for users who likely expect disambiguation to only happen at the endpoint.

The best solution I could think of for this problem is:

  • Do all addition in DateTime-land (using the RFC5455-required largest-units-first order of operations)
  • Convert to Absolute at the end (applying DST disambiguation if needed)
  • Look back and compare the tz offset of the endpoint with the tz offset of the endpoint minus the time duration (treated as an absolute time duration this time to avoid another DateTime round-trip).
  • If the offsets are different, then there was a transition during the time-only portion of the duration. Adjust the resulting Absolute to undo the impact of the transition.

Is this an acceptable solution according to RFC 5545? If not, what would be an acceptable solution that avoids disambiguating inside a duration?

I also asked here: https://stackoverflow.com/questions/62564881

2) "Undo Undo"

The proposed solution above, if it's acceptable, has another problem: what should happen if the transition is so close to the endpoint that applying the adjustment causes the Absolute to move back across the transition in the opposite direction, thus negating the need for the adjustment in the first place? The current implementation simply ignores the adjustment in that case because it will be a no-op.

Is this OK?

3) Order of operations for subtraction: same or reverse from addition?

When adding durations to a date/time value, RFC 5455 mandates the order of operations: largest units first. But what about subtraction or adding negative durations? Should subtraction also use largest-units-first? @pipobscure has argued (convincingly, IMHO) that making subtraction OOO the reverse of addition is helpful because then addition and subtraction will be reversible, e.g. A - D + D => A. If we follow this recommendation, will it cause incompatibilities with other RFC 5545 implementations? Or are longer-than-one-day negative durations such an uncommon use case in calendar applications that we could safely implement reverse OOO for subtraction without breaking things?

4) Order of operations for calculating differences between date/time values in an iCalendar-compliant way.

When adding durations to a date/time value, RFC 5455 mandates the order of operations: largest units first. But what about calculating differences between date/time values in order to produce a duration? Is order of operations also required to go largest-first here too?

5) Differences vs. DST discontinuity

When calculating differences between UTC values more than one day apart, how to handle the case where the date portion of the difference ends inside a DST discontinuity? Like above, it seems confusing to apply disambiguation in the middle of the duration. The best alternative I've found is to try two different "paths" through the calculation, like this:

  • i. Calculate the DateTime difference
  • ii. Split it into a date and time difference. If the time difference is zero, then we're done.
  • iii. Otherwise, try two "paths" to get to the result
  • iv. Path 1 starts from this, subtracts the date duration, converts to Absolute, and finally subtracts the time duration.
  • v. Path 2 starts from other, adds the date duration, converts to Absolute, and finally adds the time duration.
  • vi. Pick the path where the intermediate Absolute isn't ambiguous, or in the (amazingly unlikely outside test automation) case that they're both ambiguous, arbitrarily pick Path 1.

This seems hacky but I think it avoids the problem. But is this OK according to RFC 5545?

Regardless, is there a better solution that would match RFC 5545 expected behavior?

@ptomato
Copy link
Collaborator

ptomato commented Aug 12, 2020

@justingrant Want to summarize the answers we got here, and then close this issue?

@justingrant
Copy link
Collaborator Author

Yep, this is on my list to resolve over the next week. Need to review the proposed algorithms for plus/minus and difference from Neil Jenkins (IETF/JSCalendar). The issue is how to handle DST ambiguity around the border between the date portion and time portion of the duration.

@ptomato ptomato added this to the Stable API milestone Aug 27, 2020
@ptomato
Copy link
Collaborator

ptomato commented Sep 17, 2020

@justingrant What's left to discuss on this issue? Are there any open design decisions?

@ptomato
Copy link
Collaborator

ptomato commented Oct 1, 2020

Meeting, Oct. 1: No other design decisions to be made right now, we'll keep this issue open pending the ongoing discussions about calendar spec.

@ptomato
Copy link
Collaborator

ptomato commented Jan 14, 2021

This can be closed now, I think.

@ptomato ptomato closed this as completed Jan 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
zoned-type Part of the effort for a type with timestamp+timezone
Projects
None yet
Development

No branches or pull requests

3 participants