[Zope3-dev] Re: [Python-Dev] Holes in time

Guido van Rossum guido@python.org
Fri, 03 Jan 2003 17:04:18 -0500


> > The issue is, given an API that implements an
> > almost-but-not-quite-reversible function from local time to UTC,
> > how to invert that function.
> 
> I have to admit I've also had trouble following the discussion also, 
> until you described it that way.  Correct me if I'm wrong: you need the 
> inverse of a mathematical function.
> 
>    utc_time = f(local_time)
> 
> I'll represent the inverse as "g":
> 
>    local_time = g(utc_time)
> 
> The graph of "f" looks like an upward slope, but it has little holes and 
> overlaps at daylight savings boundaries.  The inverse is almost as 
> strange, with periodic small jumps up and down.

Yes, exactly.  The bizarre thing is that g() is a true function, with
a shape like this:

  . . . . . . . . . . . . . . . . * . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . * . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . * . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . * . . . . . . . . . . . . . . . . . . . . . .
u . . . . . . . . . . o . * . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . * . * . . . . . . . . . . . . . . . . . . . . . . . .
t . . . . . . . . * . * . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . * . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . * . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
q . . . . . * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
p . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . . * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
            A         B         C        D

Here the x-axis is UTC, and the y-axis is local time.  The 'o' points
are a feeble attempt at drawing the end points of a half-open
interval.  Points A and B mark vertical lines at the DST switch
points: DST is active between A and B (and again between C and D,
etc.).

This makes f(), its inverse, not quite a true function in the
mathematical sense: in [p, q) it has no value, and in [t, u) it is
two-valued.  (To see f()'s graph, just transpose the above graph in
your head. :-)

But our tzinfo implementation in fact implements f(), and makes it
into a real function by assigning some output value to inputs in [p,
q) and by picking one of the two possible output for inputs in the
range [u, v).

Now when we want to translate from UTC to local time, we have to
recover the parameters of g() by interpreting f()!

(There's more, but I don't want to spend all day writing this.)

> You'd like to use the time zone information provided by the C
> library in the computation of "f", but the C library doesn't quite
> provide all the information you need to compute "g" correctly.  With
> those requirements, your only hope of computing "g" is to make some
> assumptions about "f".

Yes, except the C library doesn't enter into it.

> That sounds perfectly reasonable, but may I suggest moving the 
> assumption by changing the interface of the tzinfo class.  The 
> utcoffset() method leads one to naively assume that functions f and g 
> can both depend reliably on utcoffset().  Instead, tzinfo might have two 
> methods, to_local(utc_date) and to_utc(local_date).  That way, the 
> tzinfo object encapsulates the madness.

This is similar to Tim's suggestion of letting the tzinfo subclass
implement fromutc().  We may have to do this.

> One downside is that then you can't expect normal programmers to write a 
> correct tzinfo based on the C libraries.  They'll never get it right. 
> :-)  It would have to be supplied with Python.

This is one of the reasons against it; we can't possibly supply
timezone implementations for every country, so we really need people
to write their own.

Maybe this is what Marc-Andre was hinting at: apparently mxDateTime
knows how to access the C library's timezone tables.

--Guido van Rossum (home page: http://www.python.org/~guido/)