Re: [Datetime-SIG] PEP-431/495

Stuart Bishop <stuart@stuartbishop.net> writes: ...
the complexities and slowdowns of timeline arithmetic. While not changing the behaviour of datetime at all, we could get cats and dogs living together by just clarifying what it actually is.
An *observation*: the local timezone -- the only timezone with a variable utc offset in _stdlib -- behaves like pytz_: # start with the same utc time utc_time = datetime(2015, 10, 25, 1, tzinfo=timezone.utc) stdlib_time = utc_time.astimezone() # stdlib local time pytz_time = utc_time.astimezone(tzlocal.get_localzone()) dateutil_time = utc_time.astimezone(dateutil.tz.tzlocal()) All times are consistent so far. Perform the same operations:
stdlib_time - timedelta(seconds=1) datetime.datetime(2015, 10, 25, 1, 59, 59, tzinfo=datetime.timezone(datetime.timedelta(0, 3600), 'CET')) pytz_time - timedelta(seconds=1) datetime.datetime(2015, 10, 25, 1, 59, 59, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>) dateutil_time - timedelta(seconds=1) datetime.datetime(2015, 10, 25, 1, 59, 59, tzinfo=tzlocal())
Get different results. The times are the same but utc offset are different:
(stdlib_time - timedelta(seconds=1)).utcoffset() datetime.timedelta(0, 3600) (pytz_time - timedelta(seconds=1)).utcoffset() datetime.timedelta(0, 3600) (dateutil_time - timedelta(seconds=1)).utcoffset() #XXX different datetime.timedelta(0, 7200)
It is expected for arithmetic in the presense of DST transitions. Here's the standard fix:
(stdlib_time - timedelta(seconds=1)).astimezone() datetime.datetime(2015, 10, 25, 2, 59, 59, tzinfo=datetime.timezone(datetime.timedelta(0, 7200), 'CEST')) (pytz_time - timedelta(seconds=1)).astimezone(tzlocal.get_localzone()) datetime.datetime(2015, 10, 25, 2, 59, 59, tzinfo=<DstTzInfo 'Europe/Paris' CEST+2:00:00 DST>) (dateutil_time - timedelta(seconds=1)).astimezone(dateutil.tz.tzlocal()) #XXX different datetime.datetime(2015, 10, 25, 1, 59, 59, tzinfo=tzlocal()) datetime(2015, 10, 25, 1, 59, 59, tzinfo=dateutil.tz.tzlocal()).strftime('%Z%z') 'CEST+0200'
Now the all timezones are the same but the times are different. pytz recommends normalize() method instead of astimezone() here:
tzlocal.get_localzone().normalize(pytz_time - timedelta(seconds=1)) datetime.datetime(2015, 10, 25, 2, 59, 59, tzinfo=<DstTzInfo 'Europe/Paris' CEST+2:00:00 DST>)
The result is the same in this case. It is a _fact_. It is how python behaves now on my platform. To try it yourself, add this at the top: import os import time from datetime import datetime, timezone, timedelta os.environ['TZ'] = 'Europe/Paris' time.tzset() import dateutil.tz import tzlocal # get local timezone as pytz tzinfo

On Thu, Aug 27, 2015 at 10:38 AM, Akira Li <4kir4.1i@gmail.com> wrote:
An *observation*: the local timezone -- the only timezone with a variable utc offset in _stdlib -- behaves like pytz_:
# start with the same utc time utc_time = datetime(2015, 10, 25, 1, tzinfo=timezone.utc) stdlib_time = utc_time.astimezone() # stdlib local time pytz_time = utc_time.astimezone(tzlocal.get_localzone())
I have no idea where you get tzlocal from, but I can assure you that there is no such thing in the standard library. What we do have is an option to call .astimezone() without a tzinfo argument and get an aware datetime instance with tzinfo set to a fixed offset timezone. In this respect, .astimezone() is indeed similar to pytz's localize()/normalize(), but it is much simpler.

On Thu, Aug 27, 2015 at 10:38 AM, Akira Li <4kir4.1i@gmail.com> wrote:
pytz recommends normalize() method instead of astimezone() here:
tzlocal.get_localzone().normalize(pytz_time - timedelta(seconds=1)) datetime.datetime(2015, 10, 25, 2, 59, 59, tzinfo=<DstTzInfo 'Europe/Paris' CEST+2:00:00 DST>)
The result is the same in this case.
It is a _fact_. It is how python behaves now on my platform.
Isn't it surprising that when you use two different libraries according to their respective specifications you get the same correct result!
participants (2)
-
Akira Li
-
Alexander Belopolsky