[python-win32] time/datetime module wierdness on some windows7/XP PCs
raf
raf at raf.org
Thu Jul 26 12:15:36 CEST 2012
Vernon Cole wrote:
> Dear raf:
> Yes, time zones in the python time module are known to be somewhat messed
> up. Mark Hammond and I went several rounds while trying to create a test
> for the "python time" capabilities in adodbapi. When a test worked for me
> in North America, it was almost guaranteed to fail for him in antipodes.
that's sad :-( time.localtime() should effectively just be a tiny
wrapper around the standard C library function, localtime(), and my
demonstration code works fine for everyone else but me so i don't think
this is a problem with python's time module or the standard C library.
it's more likely to be some wierdness with these windows hosts in
particular. or cosmic rays. or higgs bosons. :-)
> The problems seem to be deep in the standard library code. We finally
> concluded that we would just document the problems with "time" and suggest
> that everyone use "datetime", which is considerably more capable. Time zone
> aware datetime objects seemed to work perfectly. (Are you _sure_ that
> datetime.datetime.now() was messing up in your situation?)
yes, i'm sure. that's how i noticed these issues in the first place. logfiles
with timestamps jumping backwards and forwards many hours several times a day.
the timestamps came from datetime.datetime.now().isoformat('T').
> Jason Coombs contributed the "win32timezone" module to pywin32 which makes
> use of the extensive time zone support in the Windows registry. Look it
> up in your pywin32 documentation. You might be especially interested in
> win32timezone.now(). If I understand what you are looking for, the return
> value of win32api.GetTimeZoneInformation() might give you the correct
> answer.
>
> So, in answer to your question "how to fix it", I would suggest that you
> start with:
> >>>import win32timezone, datetime
>
> Please report back if that does not work.
> --
> Vernon Cole
the following code:
#!/usr/bin/env python
import win32api, win32con, win32timezone, datetime, time
print('GetTimeZoneInformation = %r' % (win32api.GetTimeZoneInformation(),))
print('TIME_ZONE_ID_STANDARD = %r' % win32con.TIME_ZONE_ID_STANDARD)
print('TIME_ZONE_ID_DAYLIGHT = %r' % win32con.TIME_ZONE_ID_DAYLIGHT)
print('TIME_ZONE_ID_UNKNOWN = %r' % win32con.TIME_ZONE_ID_UNKNOWN)
print('win32timezone.now = %r' % win32timezone.now())
print('datetime.now = %r' % datetime.datetime.now())
print('localtime = %r' % time.localtime())
produces:
GetTimeZoneInformation = (1, (-600, u'AUS Eastern Standard Time',
<PyTime:1/04/2000 3:00:00 AM>, 0, u'AUS Eastern Daylight Time',
<PyTime:1/10/2000 2:00:00 AM>, -60))
TIME_ZONE_ID_STANDARD = 1
TIME_ZONE_ID_DAYLIGHT = 2
TIME_ZONE_ID_UNKNOWN = 0
win32timezone.now = datetime.datetime(2012, 7, 26, 19, 47, 54, 235000,
tzinfo=TimeZoneInfo(u'AUS Eastern Standard Time'))
datetime.now = datetime.datetime(2012, 7, 26, 10, 47, 54, 235000)
localtime = time.struct_time(tm_year=2012, tm_mon=7, tm_mday=26,
tm_hour=10, tm_min=47, tm_sec=54, tm_wday=3, tm_yday=208, tm_isdst=1)
so that does work when datetime.datetime.now() and time.localtime() don't.
i've already replaced all uses of datetime.datetime.now() and time.localtime()
with code to get the local time from a nearby linux host when necessary
but i can change that to use the above methods.
Many thanks,
raf
> On Wed, Jul 25, 2012 at 12:00 AM, <raf at raf.org> wrote:
>
> > hi,
> >
> > i've just noticed the following wierdness with the time and datetime
> > modules
> > (python-2.6.2 and python-2.7.3) on three windows7 hosts and one windowsxp
> > host (but not another xp host) and i'm wondering if anyone else has
> > encountered this and knows how to fix it.
> >
> > the first problem is that time.timezone contains 0 instead of
> > the usual -36000 (for Australia/Sydney).
> >
> > the second problem is that time.localtime(...).is_dst is wrong.
> > time.tzname is also wrong but i care less about that.
> >
> > the demonstration code and output is below. i can fake the
> > time.timezone being absent but i can't see any good way to
> > deal with localtime not knowing when it's daylight savings.
> > it appears to think it's DST when it isn't and vice versa.
> >
> > this all worked before the upgrades to the new windows7 hosts.
> > the xp host that also exhibits the problem has recently had
> > its PSU, MB, CPU and RAM replaced but the HDD remains the same.
> > the xp host that doesn't exhibit the problem has all old hardware.
> > so the common factor seems to be new hardware rather than
> > specifically windows7.
> >
> > the third problem is that datetime.datetime.now() (and time.strftime() and
> > time.localtime() and presumably time.time()) don't always return the
> > current time. sometimes they do. sometimes the "current time" jumps back
> > usually 9 hours for a while and then returns to normal. note that the
> > current time that windows displays to the user is always correct. it's just
> > python's idea of the current time that is wrong.
> >
> > all hosts have the correct timezone (i.e. Australia/Sydney or rather
> > "(GMT +10:00) Canberra, Melbourne, Sydney" with automatic DST adjustment)
> > and automatic time synchronisation.
> >
> > all hosts have the hardware clock in the local timezone and windows
> > doesn't have the RealTimeIsUniversal=1 registry entry so it knows
> > that the hardware clock is in the local timezone. so there's no
> > confusion there.
> >
> > any help would be appreciated.
> >
> > cheers,
> > raf
> >
> > #!/usr/bin/env python
> > import time
> > print('time.timezone = %r (should be -36000)' % time.timezone)
> > print('time.tzname = %r (should be (\'EST\', \'EST\' or similar))' %
> > (time.tzname,))
> > print('dst in june = %r (should be 0 (for Australia/Sydney))' %
> > time.localtime(time.mktime((2012, 6, 1, 0, 0, 0, 0, 0, -1))).tm_isdst)
> > print('dst in december = %r (should be 1 (for Australia/Sydney))' %
> > time.localtime(time.mktime((2012, 12, 1, 0, 0, 0, 0, 0, -1))).tm_isdst)
> >
> > # Windows XP Professional Service Pack 3 (correct)
> > # time.timezone = -36000 (should be -36000)
> > # time.tzname = ('AUS Eastern Standard Time', 'AUS Eastern Daylight Time')
> > (should be ('EST', 'EST') or similar)
> > # dst in june = 0 (should be 0 (for Australia/Sydney))
> > # dst in december = 1 (should be 1 (for Australia/Sydney))
> >
> > # Windows 7 and Windows XP Professional Service Pack 3 (incorrect)
> > # time.timezone = 0 (should be -36000)
> > # time.tzname = ('Aus', 'tra') (should be ('EST', 'EST') or similar)
> > # dst in june = 1 (should be 0 (for Australia/Sydney))
> > # dst in december = 0 (should be 1 (for Australia/Sydney))
More information about the python-win32
mailing list