Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python astimezone() unexpected result

Given a variable containing the datetime of 2000-01-01 00:01 in Paris timezone (UTC+2 in winter afaik):

datetime.datetime(2000, 1, 1, 0, 1, tzinfo=pytz.timezone('Europe/Paris'))

I expected the conversion to UTC to result in a datetime of 1999-12-31 22:01, but got instead:

datetime.datetime(2000, 1, 1, 0, 1, tzinfo=pytz.timezone('Europe/Paris')).astimezone(pytz.utc)
datetime.datetime(1999, 12, 31, 23, 52, tzinfo=<UTC>)

What am I missing?

like image 537
jpic Avatar asked Oct 19 '25 17:10

jpic


1 Answers

Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones.

>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt)
'2002-10-27 12:00:00 LMT+0020'

It is safe for timezones without daylight saving transitions though, such as UTC:

>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=pytz.utc).strftime(fmt)
'2002-10-27 12:00:00 UTC+0000'

As you'll notice:

>>> datetime.datetime(2000, 1, 1, 0, 1, tzinfo=pytz.timezone('Europe/Paris'))
datetime.datetime(2000, 1, 1, 0, 1, tzinfo=<DstTzInfo 'Europe/Paris' LMT+0:09:00 STD>)

"LMT+0:09:00 STD"…?! That's a historical offset, not a current standard.

The timezone bundles (containing all historical offsets since forever) returned by pytz aren't handled correctly by datetime, and it chooses some random (well, the first probably) offset instead of the offset pertinent to the actual time. Arguably, since it needs to interpret the time correctly first it cannot choose the right offset by time from the timezone bundle.

This library only supports two ways of building a localized time. The first is to use the localize() method provided by the pytz library. This is used to localize a naive datetime (datetime with no timezone information):

>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
>>> print(loc_dt.strftime(fmt))
2002-10-27 06:00:00 EST-0500 

The second way of building a localized time is by converting an existing localized time using the standard astimezone() method:

>>> ams_dt = loc_dt.astimezone(amsterdam)
>>> ams_dt.strftime(fmt)
'2002-10-27 12:00:00 CET+0100'

http://pytz.sourceforge.net

like image 138
deceze Avatar answered Oct 22 '25 05:10

deceze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!