mktime() like function to produce GMT?
M.-A. Lemburg
mal at lemburg.com
Mon May 3 08:59:24 EDT 1999
Mark Nottingham wrote:
>
> M.-A. Lemburg wrote [referring to mktime_tz()]:
> > This doesn't always work. For one, time.timezone is set at
> > module init time and does not necessarily apply to the UTC
> > offset (depending on the platform). And second, mktime()
> > with DST set to 0 will not return a UTC time value on all
> > platforms: some implementations simply ignore the value
> > and recalculate it depending on the local time broken
> > down values.
>
> This explanation fits well. After looking around the linux code (and being
> somewhat shocked to learn that (according to them), it isn't POSIXly correct
> to accept a TZ env variable), this appears to be the case (although my grasp
> of linux internals is tenuous at best).
>
> > I've had much trouble with this in mxDateTime, but finally found
> > a rather well working trick that only relies on mktime()
> > producing correct local time values.
>
> Is it doable in Python-only (sorry, I've only taken a cursory glance over
> the mxDateTime module; it looks very elegant and functional, but I'd like to
> try and make the application use only standard library functions)?
You can try to use the Python prototype I hacked up to test
the hack (the documentation mentioned in the copyright notice
referrs to the mxDateTime documentation). It will be included
in the next mxDateTime release.
""" A timegm() emulation for platforms that do not provide that C lib
API.
This is the prototype I used to code the timegm() C emulation
in mxDateTime. It offers a little more than is really needed...
(c) Copyright Marc-Andre Lemburg; All Rights Reserved.
See the documentation for further information on copyrights,
or contact the author (mal at lemburg.com).
"""
from time import *
__debug__ = 0
def local_offset(ticks):
if __debug__:
print 'local:',localtime(ticks)
print 'GMT:',gmtime(ticks)
(localyear,localmonth,localday,
localhour,localminute,localsecond,
localwday,localyday,localdst) = localtime(ticks)
(gmyear,gmmonth,gmday,
gmhour,gmminute,gmsecond,
gmwday,gmyday,gmdst) = gmtime(ticks)
if gmday != localday:
localdate = localyear * 10000 + localmonth * 100 + localday
gmdate = gmyear * 10000 + gmmonth * 100 + gmday
if localdate < gmdate:
offset = -86400
else:
offset = 86400
else:
offset = 0
return (offset
+ (localhour - gmhour) * 3600
+ (localminute - gmminute) * 60
+ (localsecond - gmsecond))
def timegm(year,month,day,hour,minute,second,wday,yday,dst):
try:
ticks = mktime(year,month,day,hour,minute,second,wday,yday,-1)
return ticks + local_offset(ticks)
except OverflowError:
# Hmm, we may have stumbled into the "missing" hour during a
# DST switch...
ticks = mktime(year,month,day,0,0,0,wday,yday,-1)
offset = local_offset(ticks)
return (ticks + offset
+ 3600 * hour
+ 60 * minute
+ second)
def dst(ticks):
offset = local_offset(ticks)
for checkpoint in (-8640000,10000000,-20560000,20560000):
try:
reference = local_offset(ticks + checkpoint)
except OverflowError:
continue
if reference != offset:
break
if __debug__:
print 'given:',offset,'reference:',reference,'(checkpoint:',checkpoint,')'
return offset > reference
def _test():
t = 920710000
oops = 0
while 1:
x = apply(timegm,gmtime(t))
if x != t:
print 'Ooops:',gmtime(t),'t =',t,'diff =',x-t
oops = oops + 1
isdst = localtime(t)[-1]
if isdst != -1 and isdst != dst(t):
print 'Ooops: t =',t,'dst() =',dst(t),'isdst =',isdst
oops = oops + 1
try:
t = t + 10011
except OverflowError:
break
if not oops:
print 'Works.'
return 1
else:
print 'Got %i warnings.' % oops
return 0
if __name__ == '__main__':
_test()
--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: Y2000: 242 days left
Business: http://www.lemburg.com/
Python Pages: http://starship.python.net/crew/lemburg/
More information about the Python-list
mailing list