[Python-Dev] Interop between datetime and mxDateTime (original) (raw)

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.