[Python-Dev] Interop between datetime and mxDateTime

Tim Peters tim.one@comcast.net
Tue, 14 Jan 2003 23:40:21 -0500


[Guido]
> So is the epoch -- only POSIX requires it to be 1-1-1970.  I think the
> C standard doesn't constrain this at all (it doesn't even have to be a
> numeric type).

That's almost all so -- time_t and clock_t are constrained to be of
"arithmetic types" by C99, meaning they must be integers (of some size) or
floats (of some size).  This is good for Python, because timemodule.c
blithely casts time_t to double, and so does datetimemodule.c.  The range
and precision are left implementation-defined.

> In fact, non-posix systems are allowed to incorporate leap seconds
> into their ticks, which makes it hard to understand how ticks could be
> computed except by converting to local time first (a problem in
> itself) and then using mktime().

It depends on what "ticks" means.  If we take ticks to mean what POSIX
defines "seconds since the epoch" to mean, then I can easily generate a
POSIX timestamp without using platform C functions at all.  The formula for
"seconds since the epoch" is given explicitly in the POSIX docs:

    tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
    (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
    ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400

While POSIX explicitly refuses to define the relationship for years before
1970, or for negative "seconds since the epoch" values, extending the
formula to cover those things is trivial (it's enough to convert the
timedelta dt - datetime(1970, 1, 1) to seconds).  POSIX also explicitly
warns that

    The relationship between the actual time of day and the current
    value for seconds since the Epoch is unspecified.

which is partly a consequence of that the POSIX formula doesn't allow for
leap seconds, but that leap seconds are part of the definition of UTC.

The other meaning for "ticks" is whatever the platform means by it.
mxDateTime does cater to boxes that account for leap seconds -- Marc-Andre
checks whether 1986-12-31 23:59:59 UTC maps to 536457599 (POSIX) or
536457612 (leap seconds) ticks, and fiddles accordingly, falling back to
platform C functions (IIRC) on non-POSIX boxes.  datetime squashes leap
seconds out of existence *when it can detect them*, though.

If there's any hope for a common base API here, I expect it has to follow
the POSIX definition, platform quirks be damned.