Puzzled with Time Server conversion problems?

Malcolm Tredinnick malcolmt at smart.net.au
Mon Oct 4 03:12:29 EDT 1999


On Mon, Oct 04, 1999 at 02:44:43AM +0000, Benjamin Schollnick wrote:
[...snip...]
> 	I'm using Pythons time module, (specifically) time.time() to
> generate the time information.  Even though time is specified to : 
> "return the time
> as a floating point number expressed in seconds since the epoch, in 
> UTC", it doesn't
> "match up" with the RFC results even when the 1900 vs 1970 date is 
> taken into effect.
> 
> 	The RFC states that "The time is the number of seconds since 00:00 @ 
> 1900 Jan 1.
> 
> 	From my experimentation is GMTIME:
> 
> python GMTIME 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
> Jan 1, 1980	- 3,155,550,800.0		2,524,421,600

I assume there is a typo here, since the correct value for Jan 1, 1980
should be 2,524,521,600 seconds as far as I can work out (100 000
seconds more than the number written).

> I don't see how python's Jan 1, 1980 calcuation can exceed the RFC's 
> calculation, unless the
> calculation is returning *NON-LINEAR* results, which doesn't make 
> sense if it's the # of secs since
> Jan xxxx.

I agree. I can't understand your Python numbers at all. There is a
problem with your calculation routine (see below), but it shouldnt'
give these non-linear results. I don't have access to Python on any
sort of Windows box, so I can't verify the results you got there, but
certainly nothing like that is happening under Linux for me.

> 
> Also, I can't duplicate the RFC 868 values if I manually perform the 
> calculations.
> 
> My "big question", is simple:
> 
> 	Can anyone suggest a way to convert from pythons time.time() to the 
> RFC date(s)?
[... lots'o stuff deleted ...]

> import time
> #
> #       Constants
> #
> #secs_in_year    = 31536000      # 365*24*60*60
> secs_in_year    = 365.1666666666667 * 24*60*60
                        ^^^^^^^^^^^^
Huh?? Firstly, since 0.166666... = 1/6, this is saying that leap years occur
every six years. On my side of the world at least, we try to have them
every four years or so. :-)

Secondly, even if you replace this number with 365.25 (I know it's not
precisely correct, but it's near enough for my purposes here), it will
onyl give the right answer one year out of four. This is because
although the time it takes the Earth to do a lap around the Sun is
more or less 365.25 days (minus a little bit), the Julian calendar
operates on the principle that each year is exactly 365 days, except
for every fourth year, which is 366 days (except for every 100th year
which is 365 days, except for every 400th year which is 366 days).

So to do the correct computations, you need to set secs_in_year to
365*24*3600 and add on the amount 24*3600 for every leap year that
has occurred from 1900 until the present day (or from 1968 until the
present year, if you are using the Jan 1, 1970 epoch --- I choose
1968, rather than 1970 so that a simple integer division will give
the correct answer).

To conclude, here is a corrected version of the manual calculation
code. I have, in passing, fixed one other error, which is that to work
out the number of seconds from the beginning of the year until the
current day, you should use (Julian Day - 1), not just Julian Day.
This code assumes a 1/1/1970 epoch - just add the appropriate big
number is you want to work from 1/1/1900. :-)

Cheers,
Malcolm Tredinnick


import time

#
# Set test_time to some number of seconds after the epoch
#
# For example, I use 1 Jan 1980
test_time = 315532800.0

secs_per_day = 24.0 * 60 * 60
secs_per_year = 365.0 * secs_per_day

# timetuple is 9 elements:
#  (yr, mnth, day, hr, min, sec,
#   D.of.week, Julian day, daylight.savings)
timetuple = time.gmtime(test_time)

print timetuple

# Work out basic number of seconds untils 1 Jan.
total = secs_per_year * (timetuple[0] - 1970)

# Correct for leap years. The division computes the number of leap
# years that have occurred after 1968 and *before* this year
# (hence the timetuple[0]-1 bit)
total = total + (timetuple[0] - 1 - 1968)/4 * secs_per_day

# Add up to current day (the -1 is because 1 Jan has julian day=1
# and we don't want to add anything in that case).
total = total + (timetuple[7] - 1) * secs_per_day

# Add number of seconds for current time
total = total + timetuple[5] + timetuple[4]*60.0 + timetuple[3]*3600.0

# The number of seconds is now be contained in total 
# (and should, of course, be the same as test_time)

print test_time
print total




More information about the Python-list mailing list