Subject: Re: [calsify] Subtraction vs. DST disambiguation

From: Michael H Deckers <[email-masked]>
Date: Sat, 3 Oct 2020 13:57:56 +0000

On 2020-09-30 21:50, Justin Grant wrote:

> We previously
> agreed that, in order to make subtraction reversible with subsequent
> addition of the same value, we'd reverse the order of operations so with
> subtraction of a positive duration (or adding a negative duration) the time
> portion would be subtracted first, and then the date portion.

     If I understand you correctly, you want to ensure that
          ( Δ - 1 month) + 1 month = Δ
     for any date Δ.

     This is impossible to achieve with the "usual" expectations,
     for instance, that ( Δ - 1 month) is a date in February
     when Δ is a date in March (because you have only 28 or 29
     different dates in February, but 31 dates in March, so that
     such a subtraction of 1 month from dates in March can never
     be injective).

     Of course, there are group operations on the set of dates,
     such as adding and subtracting integral multiples of days
     or weeks.

     And on the set of datetimes (= date plus time of day), there
     are group operations with multiples of formal time units such as
     months so that the subtraction of 1 month maps the set of
     datetimes in the interval
         [2020-03-01T00:00:00..2020-04-01T00:00:00]
     bijectively onto the interval
         [2020-02-01T00:00:00..2020-03-01T00:00:00]
     (eg, as in the subtraction of fractions of months in Oracle SQL);
     but the result of such a subtraction from a date (with time of day
     00:00:00) is in general no longer a date. Do you intend to
     specify such an operation?

     HTH.

     Michael Deckers.

---

From: "Neil Jenkins" <[email-masked]>
Date: Mon, 05 Oct 2020 09:59:11 +1100

On Thu, 1 Oct 2020, at 07:50, Justin Grant wrote:
> For example: `2020-03-09T02:30-07:00[America/Los_Angeles]` -` P1D`
> The result is `2020-03-08T03:30-07:00[America/Los_Angeles]`
> And if I add `P1D` to that result, I get `2020-03-09T03:30-07:00[America/Los_Angeles]`, which is one hour later than my original time.  It's not reversible.
> 
> I'm not sure there's any way to avoid this problem. We could choose to reverse the disambiguation behavior and pick the later offset, but that doesn't solve the reversibility problem, because we'd just get a one-hour-earlier result instead of a one-hour-later one.

Yes, thinking about this it seems obvious that you cannot make it fully reversible, because around DST changes you can have:

X + D = Z and
Y + D = Z

Therefore Z - D could be either X or Y depending on your choice of algorithm. For ease of implementation therefore, I'd recommend keeping the normal disambiguation behaviour so at least this is consistent!

> It'd also introduce interesting behavior where the same result in nominal time is resolved to a different result in exact time depending on whether a subtraction or an addition was being performed. 

True.

> There's also another, more obscure problem: in rare cases time zone discontinuities can be a full day long, e.g. Samoa's 2011 switch to opposite sides of the International Date Line where `2011-12-30` was skipped. In that case, I could get into an infinite loop while subtracting `P1D` from `2011-12-31T12:00+14:00[Pacific/Apia]` because after subtracting one day in nominal time, we'd add that one day right back to end up with the same result:  noon on Dec 31.
> 
> Note that this is only an issue when subtracting full days, because subtracting times will always use exact time. 
> 
> Anyone have any ideas for how we should handle this case?

This is such an edge case, I'd be mainly concerned about making sure the algorithm was well specified enough to not enter an infinite loop, with a note to the effect it may not produce what is considered a "correct" answer…

Neil.