#16899 closed Bug (fixed)
Wrong offset for Europe/Moscow
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Core (Other) | Version: | 1.3 |
Severity: | Normal | Keywords: | timezone |
Cc: | iigor12 | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hello everybody!
in file source:/django/branches/releases/1.3.X/django/utils/tzinfo.py#L40 I see these code:
59 def _isdst(self, dt): 60 tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1) 61 try: 62 stamp = time.mktime(tt) 63 except (OverflowError, ValueError): 64 # 32 bit systems can't handle dates after Jan 2038, and certain 65 # systems can't handle dates before ~1901-12-01: 66 # 67 # >>> time.mktime((1900, 1, 13, 0, 0, 0, 0, 0, 0)) 68 # OverflowError: mktime argument out of range 69 # >>> time.mktime((1850, 1, 13, 0, 0, 0, 0, 0, 0)) 70 # ValueError: year out of range 71 # 72 # In this case, we fake the date, because we only care about the 73 # DST flag. 74 tt = (2037,) + tt[1:] 75 stamp = time.mktime(tt) 76 tt = time.localtime(stamp) 77 return tt.tm_isdst > 0
It's using in
40 def utcoffset(self, dt): 41 if self._isdst(dt): 42 return timedelta(seconds=-time.altzone) 43 else: 44 return timedelta(seconds=-time.timezone)
and make wrong value for Europe/Moscow. time.altzone contains proper value.
Why isn't time.daylight checked rather than _isdst?
$ export | grep TZ TZ=Europe/Moscow $ python >>> import time >>> time.tzname ('MSK', 'MSK') >>> time.tzname, time.timezone, time.altzone (('MSK', 'MSK'), -10800, -14400) >>> time.localtime(time.mktime((2011, 9, 21, 14, 5, 10, 2, 0, -1))).tm_isdst 0 >>> time.daylight 1 >>>
Change History (6)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
BTW, return datetime.fromtimestamp(stamp) - datetime.utcfromtimestamp(stamp) work only on system with /usr/share/zoneinfo/. Not on windows.
may be, using pytz as alternative.
comment:3 by , 13 years ago
Cc: | added |
---|
Same bug.
it's a strange time.zoninfo/altzone behaviour. http://blogs.gnome.org/jamesh/2006/12/31/python-timetimezone-timealtzone-edge-case/
comment:4 by , 13 years ago
Triage Stage: | Unreviewed → Accepted |
---|
Why isn't time.daylight checked rather than _isdst?
The reason for not checking time.daylight
is that time.daylight
will always be True
if the local time zone has DST — no matter if DST currently applies or not. But here, we want to check if a specific date is or isn't in the DST period. See http://bugs.python.org/issue7229 for a long discussion about improving Python's documentation of this flag.
Proper way to get offset, as I understood (...)
The first comment in http://bugs.python.org/issue1647654 backs your idea — and also handles days.
The code you're quoting was initially copy-pasted from Python's documentation — search "Example tzinfo classes" in http://docs.python.org/library/datetime. However, some bugs in these examples have been reported and fixed, in particular http://bugs.python.org/issue9063, but the patches haven't been backported to Django.
I'm accepting this ticket to:
- backport the fixes in Python's documentation — Django's implementation has significantly diverged;
- review our implementation of
utcoffset
, in the light of the discussions in Python's bug tracker; this is a complex topic, and it's easy to make mistakes...
comment:6 by , 13 years ago
Note that I have only fixed the issue originally described in this ticket.
I intend to review django.utils.tzinfo
in the context of my work on #2626.
Proper way to get offset, as I understood