[Zope3-dev] Can we remove ZopeLegacy for now?

Tim Peters tim@zope.com
Sat, 16 Mar 2002 02:20:38 -0500


[Guido]
> My first guess is that they all [ECMAScript, C99, Common Lisp] figured
> out that tzoffset alone isn't enough when you want to do time
> calculations, and that the problem had something to do with DST, but
> then stopped thinking about it further (perhaps hampered by a US-
> centric view).

I find that hard to swallow.  C99 in particular is an ISO standard as well,
and had an international crew working on it for a decade.  C99 doesn't
attempt to cover date arithmetic, though, beyond the limitations of
traditional time_t.

> The tm_isdst flag in C's struct tm is useful to disambiguate an
> ambiguous local time (the hour in the transition out of DST occurs
> twice because the clock is set back).

It's also useful to let the user know whether or not the language thinks DST
*is* in effect at a given time.  tmx goes on to let the user know exactly
how much of a DST offset the language believes is in effect.  Those are
important pieces of discoverability, IMO, especially since there's no
accepted standard for answering these questions.

> But the use of the DST offset that it holds in struct tmx is unclear,

I expect they were careful not to over-define it.  In effect, it's just an
additional offset field, in addition to the tmx.tm_zone and tmx.tm_leapsecs
offset fields.  It has just a little defined semantics.

> and even the combination of tm_zone and tm_isdst isn't enough to
> unambiguously determine the DST transition points (unless you are
> in the US).

Sorry, I don't know what you mean by that -- but I am in the US <wink>.
Still, I don't imagine there's a DST situation in the world messier than
Indiana's:

    [from http://www.mccsc.edu/time.html]

    76 counties (including state capital Indianapolis) are in the
    Eastern Time Zone but do not change to Daylight time in April;
    instead they remain on Standard Time all year long;

    11 counties -- six near Chicago, IL, and five near Evansville, IN,
    are in the Central Time Zone and use both Central Standard and
    Central Daylight;

    five other counties -- two near Cincinnati, OH, and three near
    Louisville, KY -- are in the Eastern Time Zone but use both Eastern
    Standard and Eastern Daylight

And I don't imagine anyone is going to write a tzinfo object any better at
sorting out that mess than a struct tmx either:  in some places in Indiana,
"the time" depends on where you are, when you ask, which year you're asking
about, and who you ask.  In addition, it appears US law and Indiana law
disagree about the answers even so.

> Tzinfo objects can solve these problems because you can write a tzinfo
> object that implements any jurisdiction's timezone and DST rules and
> history.

I see nothing to stop you from doing the same via routines manipulating a
struct tmx, but with the latter's advantage of allowing to explicitly break
out the three distinct customary adjustments to UTC (time zone, DST
fiddling, and leap second fiddling).  The language itself says little about
how these fields can be used.

> See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo

The base code can't get in trouble because of this simply because our spec
declines to say anything about what this number means, beyond that it's
"seconds east of UTC".  I'm not sure that's enforcable-- or even
meaningful --in the absence of other defined semantics.  It reads more like
a hint about intent.

This is similar to how struct tmx avoids trouble:  lots of mechanism, little
policy.  I personally find it very confusing to call a combined offset
gimmick "a timezone", but so it goes (I was taught in grade school that
timezones are roughly based on a grid spaced 15 longitudinal degrees, and
not even the Wisconsin legislature had the power to shift the state's
position on the Earth at the same time it commanded the Sun to sleep an hour
longer <wink>).

Other confusions:

> datetimetz
> A subclass of datetime that adds an optional timezone info object.
> If the tzinfo object is None, this behaves identical to naive datetime.

datetimetz isn't mentioned again on this page.  In particular, there's
nothing about how a datetimetz acts if its tzinfo object is not None.
There's also no way specified to ask a datetimetz what its timezone info
object is.  IOW, so far it's got no defined semantics except in its
degenerate (tzinfo is None) case.

> tz.tzoffset(dt)
> given a datetime object, returns the timezone offset in seconds east
> of UTC (negative west of UTC) corresponding to that date and time

I believe we need to define a distinguished "I don't know" result, or
explicitly allow that this operation may raise a specific exception in that
case.

> tz.tzname(dt)
> given a datetime object, returns the timezone name to be used
> corresponding to that date and time

As above.

> Sample tzinfo classes:
>
>        class UTC:
>            "UTC"
>           def tzoffset(self, dt):
>                return 0
>           def tzname(self, dt):
>                return "UTC"

I assume it's just as valid to define this as, e.g.,

        class UTC:
            "UTC"
           def tzoffset(self, dt):
                return -42137    # ONLY CHANGE IS HERE
           def tzname(self, dt):
                return "UTC"

If it's not, scream at me, because then there's some hidden assumption about
the relationship between naive time and UTC.  Or is the rest of the spec
going to change to say that naive time *is* UTC (but stripped of leap
secconds)?  That assumption seems to underlie all the sample classes:  is it
a required assumption, or just a convenient assumption for purposes of
illustration?

BTW, I'm delighted to punt the nasty issues into the court of a vague
object.