Puzzled with Time Server conversion problems?

Malcolm Tredinnick malcolmt at smart.net.au
Mon Oct 4 13:09:55 EDT 1999


OK, I think I can clear up most of the problems now -- two of which I
should have noticed on my first pass through the message. Apologies
for any time wasted. :-)

On Mon, Oct 04, 1999 at 10:11:21AM +0000, Benjamin Schollnick wrote:
[ ...snip... ]
> > 	From my experimentation is GMTIME:
> > 
> > python MKTIME calcs				RFC 868
> > (Base 1970, Jan 1)		          (Base Jan 1, 1900)
> > Jan 1, 1970	- 18,000.0			2,208,988,800
> > Jan 1, 1976	- 189,320,400.0			2,398,291,200
                     ^^^^^
A typo. This should be 189,302,400.0

> > Jan 1, 1980	- 3,155,550,800.0		2,524,521,600 (CORRECTION)
                  ^^^^^^^^^^^^^^^
Another typo. There are too many 5's in this number. Get rid of one of
the fives and the number is only out by the systematic error I mention
below (making it is sensibly incorrect, rather than insanely so).

[ ...more stuff deleted... ]
> I simply:
> 
> >>> import time
> >>> print time.gmtime(0)
> (1970, 1, 1, 0, 0, 0, 3, 1, 0)
> >>> print time.mktime(1970, 1,1,0,0,0,3,1,0)
> 18000.0
> >>> print time.mktime(1980, 1,1,0,0,0,3,1,0)
> 315550800.0
>

The problem here is that mktime() assumes the tuple you are passing it
is in the local timezone (i.e. mktime() undoes the localtime()
function, rather than the gmtime() function). I should have realised
this is what you were doing when I saw that magic 18000 number and
your email address. That represents the number of seconds that have to
be added to a local time to get the equivalent UTC (or GMT) time (i.e.
you are 6 hours *behind* UTC).

In relation to your original problem, however, this should not be a
problem, since time.time() returns the number of seconds since the
epoch in UTC, so you simply need to add the number of seconds between
1/1/1900 and 1/1/1970 (2,208,988,800) to get the value in RFC 868
format.

As an aside, to get your example above to work, you need to be a
little "devious", otherwise you get bitten by daylight savings time as
well as timezones. :-)

To explain, suppose timetuple is 9 element tuple representing
something returned by time.gmtime(), for example. Then, if you are
*not* in daylight savings time, the correct number of seconds is

time.mktime(timetuple) - time.timezone

However, if you are in daylight savings time, you need to use

time.mktime(timetuple) - time.altzone

To determine if you are in daylight savings time or not for a random
date, you should look at the last component of the tuple returned by
time.localtime(). Conveniently enough, time.mktime() ignores the
daylight savings flag, so you can just feed the number it returns back
into time.localtime() to get a new tuple and test its last component.
If the last component is zero, use time.timezone, otherwise use
time.altzone .

(Of course, I can write that last paragraph with confidence now - but
I just spent five or ten minutes going bananas while I tried to work
out was going wrong. In Australia, 1/1/1980 is in daylight savings
time, so until I noticed that pesky last component I was adding the
wrong correction to the time.mktime() result. Interestingly, 1/1/1970
is *not* in daylight savings time according to my machine -- although
I believe that in this case the computer is in error, rather than
reality being wrong. Northern Hemisphere residents may not notice that
error so quickly, unless they test a less "pretty" date like 1 July,
or something.)

Cheers,
Malcolm Tredinnick





More information about the Python-list mailing list