[Datetime-SIG] Calendar vs timespan calculations...
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)
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
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).
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