[issue9063] TZ examples in datetime.rst are incorrect

New submission from Alexander Belopolsky <belopolsky@users.sourceforge.net>: With python started at the root of the source tree and TZ=US/Eastern in the environment,
Note that according to my understanding of the long comment at the end of datetimemodule.c, zone conversion from UTC is a well defined operation unless there is a bug in tzinfo subclass implementation. ---------- assignee: docs@python components: Documentation messages: 108462 nosy: belopolsky, docs@python priority: normal severity: normal stage: needs patch status: open title: TZ examples in datetime.rst are incorrect versions: Python 2.7, Python 3.2 _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: The result given when Eastern tzinfo object is used is clearly wrong. The timezone shift should not change the actual time, but
x == x.astimezone(Eastern) False
while
x == x.astimezone(Local) True
---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: Let's establish what is the correct wall clock sequence around EDT to EST transition:
x = datetime(2010, 11, 7, 5)
s = (x - datetime(1970, 1, 1))//timedelta(seconds=1)
However, neither Local nor Eastern tzinfo instance is capable of reproducing this sequence:
for i in range(-3600, 5000, 1200): ... print(datetime.fromtimestamp(s + i, Eastern).strftime('%c %z %Z'))
Sun Nov 7 00:00:00 2010 -0400 EDT Sun Nov 7 00:20:00 2010 -0400 EDT Sun Nov 7 00:40:00 2010 -0400 EDT Sun Nov 7 01:00:00 2010 -0500 EST Sun Nov 7 01:20:00 2010 -0500 EST Sun Nov 7 01:40:00 2010 -0500 EST Sun Nov 7 01:00:00 2010 -0500 EST Sun Nov 7 01:20:00 2010 -0500 EST
for i in range(-3600, 5000, 1200): ... print(datetime.fromtimestamp(s + i, Local).strftime('%c %z %Z'))
Sun Nov 7 00:00:00 2010 -0400 EDT Sun Nov 7 00:20:00 2010 -0400 EDT Sun Nov 7 00:40:00 2010 -0400 EDT Sun Nov 7 01:00:00 2010 -0400 EDT Sun Nov 7 01:20:00 2010 -0400 EDT Sun Nov 7 01:40:00 2010 -0400 EDT Sun Nov 7 02:00:00 2010 -0500 EST Sun Nov 7 02:20:00 2010 -0500 EST ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: There is nothing we can do about misreporting of UTC offset. Unlike time tuples, datetime objects do not store the DST flag and thus have no means to disambiguate between standard and DST during the hour after the clock is set back for DST to standard transition. Nevertheless, dt = datetime.fromtimestamp(t) is a well defined operation, it is dt.dst() and dt.utcoffset() which are not so well defined. According to the comment at the end of Modules/datetimemodule.c, in order for the default implementation of tzinfo.fromutc() to operate correctly, the concrete implementation of tzinfo.dst(dt) must treat dt that falls into the ambiguous hour (where it can be ether DST or standard time) as the standard time. This is precisely what is done in the implementation of USTimeZone class. The Local class, however, relies on mktime to choose between DST and standard and apparently, at least on OSX, mktime does not do what Python's tzinfo.fromutc() expects. The attached patch for Doc/includes/tzinfo-examples.py fixes this problem by passing is_dst=0 instead of -1 to mktime and also adds __repr__ to LocalTimezone class. With this patch,
which is correct and consistent with Easter timezone:
---------- keywords: +patch nosy: +mark.dickinson stage: needs patch -> commit review type: -> behavior Added file: http://bugs.python.org/file17892/issue9063.diff _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Changes by Rodrigo Bernardo Pimentel <rbp@isnomore.net>: ---------- nosy: +rbp _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: Committed in r87463 (3.2), r87464 (2.7) and r87465 (3.1). ---------- resolution: -> fixed stage: commit review -> committed/rejected status: open -> closed versions: +Python 3.1 _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: The result given when Eastern tzinfo object is used is clearly wrong. The timezone shift should not change the actual time, but
x == x.astimezone(Eastern) False
while
x == x.astimezone(Local) True
---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: Let's establish what is the correct wall clock sequence around EDT to EST transition:
x = datetime(2010, 11, 7, 5)
s = (x - datetime(1970, 1, 1))//timedelta(seconds=1)
However, neither Local nor Eastern tzinfo instance is capable of reproducing this sequence:
for i in range(-3600, 5000, 1200): ... print(datetime.fromtimestamp(s + i, Eastern).strftime('%c %z %Z'))
Sun Nov 7 00:00:00 2010 -0400 EDT Sun Nov 7 00:20:00 2010 -0400 EDT Sun Nov 7 00:40:00 2010 -0400 EDT Sun Nov 7 01:00:00 2010 -0500 EST Sun Nov 7 01:20:00 2010 -0500 EST Sun Nov 7 01:40:00 2010 -0500 EST Sun Nov 7 01:00:00 2010 -0500 EST Sun Nov 7 01:20:00 2010 -0500 EST
for i in range(-3600, 5000, 1200): ... print(datetime.fromtimestamp(s + i, Local).strftime('%c %z %Z'))
Sun Nov 7 00:00:00 2010 -0400 EDT Sun Nov 7 00:20:00 2010 -0400 EDT Sun Nov 7 00:40:00 2010 -0400 EDT Sun Nov 7 01:00:00 2010 -0400 EDT Sun Nov 7 01:20:00 2010 -0400 EDT Sun Nov 7 01:40:00 2010 -0400 EDT Sun Nov 7 02:00:00 2010 -0500 EST Sun Nov 7 02:20:00 2010 -0500 EST ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: There is nothing we can do about misreporting of UTC offset. Unlike time tuples, datetime objects do not store the DST flag and thus have no means to disambiguate between standard and DST during the hour after the clock is set back for DST to standard transition. Nevertheless, dt = datetime.fromtimestamp(t) is a well defined operation, it is dt.dst() and dt.utcoffset() which are not so well defined. According to the comment at the end of Modules/datetimemodule.c, in order for the default implementation of tzinfo.fromutc() to operate correctly, the concrete implementation of tzinfo.dst(dt) must treat dt that falls into the ambiguous hour (where it can be ether DST or standard time) as the standard time. This is precisely what is done in the implementation of USTimeZone class. The Local class, however, relies on mktime to choose between DST and standard and apparently, at least on OSX, mktime does not do what Python's tzinfo.fromutc() expects. The attached patch for Doc/includes/tzinfo-examples.py fixes this problem by passing is_dst=0 instead of -1 to mktime and also adds __repr__ to LocalTimezone class. With this patch,
which is correct and consistent with Easter timezone:
---------- keywords: +patch nosy: +mark.dickinson stage: needs patch -> commit review type: -> behavior Added file: http://bugs.python.org/file17892/issue9063.diff _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Changes by Rodrigo Bernardo Pimentel <rbp@isnomore.net>: ---------- nosy: +rbp _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________

Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment: Committed in r87463 (3.2), r87464 (2.7) and r87465 (3.1). ---------- resolution: -> fixed stage: commit review -> committed/rejected status: open -> closed versions: +Python 3.1 _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue9063> _______________________________________
participants (2)
-
Alexander Belopolsky
-
Rodrigo Bernardo Pimentel