[Datetime-SIG] Calendar vs timespan calculations...
Alexander Belopolsky
alexander.belopolsky at gmail.com
Sat Aug 1 16:36:54 CEST 2015
On Sat, Aug 1, 2015 at 1:16 AM, Tim Peters <tim.peters at gmail.com> wrote:
>> With my proposal, a naive datetime t is ambiguous in timezone tz if
>>
>> tz.utcoffset(t) < tz.utcoffset(t.replace(first=False))
>>
>> or "is this an invalid (missing) time?"
>
> Unless I'm missing your intent entirely, that's a fine illustration of
> my "The logic is bound to be annoying enough that we'd want to
> concentrate it in tzstrict". The problem I see is that the expression
> you gave can never be true.
You are absolutely right and this is the intent. The challenge that
I tried to solve was that local-to-global function (G(t)) can have 0, 1 or 2
values if defined as mathematical inverse of the global-to-local (L(u))
function. (Purists would say that this means that local-to-global
is not a function, but I find it convenient to say that a function has
multiple values when it returns a variable-length list.) At the same
time, I wanted naive code
u = G(t)
to (a) work for all values of t; (b) produce correct result when L(u) = t
has only one solution; (c) produce one of the "correct: results when
L(u) = t has two solutions; and (d) produce "useful" result when L(u) = t
has no solutions.
This ruled out the obvious design where G(t) would return [], [u] or [u0, u1]
because all naive code that used u = G(t) would have to be rewritten as
u = G(t)[0]
and you would still face an index error when t is in the gap. (I've recently
learned this useful terminology: the interval of non-existent local times that
occurs when you move the clock forward is called a "gap" and the the interval
of ambiguous local times that occurs when you move the clock back is called
a "fold".)
The other solution was to give G(t) an additional argument so that you could
specify the index into the returned list upfront:
def xG(t, which=0).
return G(t)[which]
this makes the naive u = xG(t) code work in 99.99% of the cases, but you still
face an occasional index error.
So how do you represent three outcomes [], [u] or [u0, u1] in a way that xG(t)
always works? My solution:
[] -> [u1, u0]
[u] -> [u, u]
[u0, u1] -> [u0, u1]
Note that this solution satisfies all my design criteria including
(d). The results
produced from the time in a gap are "useful" because the default xG(t) result
is what most people mean when they specify the time in the gap: they do it
because they are unaware of the time change and expect 02:30 AM to be 150
minutes after midnight not knowing that it will be called 03:30 AM. The other
solution is also useful because it allows you to detect the time in the gap
without calling L(u) on the result.
More information about the Datetime-SIG
mailing list