unexpected results converting timezones in python

PythonDatetimeTimezonePytz

Python Problem Overview


I'm trying to understand why I'm getting these results when converting time zones to UTC:

In [74]: d1 = datetime(2007, 12, 5, 6, 30,tzinfo=pytz.timezone('US/Pacific'))
In [75]: d1
Out[75]: datetime.datetime(2007, 12, 5, 6, 30, tzinfo=<DstTzInfo 'US/Pacific' LMT-1 day, **16:07:00 STD**>)
In [76]: d1.astimezone(pytz.utc)
Out[76]: datetime.datetime(2007, 12, 5, 14, 23, tzinfo=<UTC>)

Why did 6:30am become 2:23pm?

On the other hand, if I use the following approach, I get the expected result:

In [90]: d2 = datetime(2007, 12, 5, 6, 30)
In [91]: uspac = pytz.timezone('US/Pacific')
In [92]: d2_aware = uspac.localize(d2)
In [94]: d2_aware.astimezone(pytz.utc)
Out[94]: datetime.datetime(2007, 12, 5, 14, 30, tzinfo=<UTC>)

Python Solutions


Solution 1 - Python

What I got is just a workaround, the simple rule is Never create datetime with timezone info by using datetime().

This sample would give you a hint for this. As you see, you could avoid the unexpected difference, once and only you make "naive" datetime (it is, datetime without timezone info) and then localize it (it is not applied when you create datetime on UTC though) :

import pytz
from datetime import datetime

# make Jan 1 on PDT -> UTC
pdt = pytz.timezone("America/Los_Angeles")
pdtnow1 = datetime(2014,1,1, tzinfo=pdt)
pdtnow2 = pdt.localize(datetime(2014,1,1))
pytz.utc.normalize(pdtnow1)
# > datetime.datetime(2014, 1, 1, 7, 53, tzinfo=<UTC>)
pytz.utc.normalize(pdtnow2)
# > datetime.datetime(2014, 1, 1, 8, 0, tzinfo=<UTC>)

# make Jan 1 on UTC -> PDT
utcnow1 = datetime(2014,1,1, tzinfo=pytz.utc)
utcnow2 = pytz.utc.localize(datetime(2014,1,1))
pdt.normalize(utcnow1)
# > datetime.datetime(2013, 12, 31, 16, 0, 
# > tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
pdt.normalize(utcnow2)
# > datetime.datetime(2013, 12, 31, 16, 0, 
# > tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

Solution 2 - Python

From the partial documentation: http://pytz.sourceforge.net/#localized-times-and-date-arithmetic

> Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones. [...] It is safe for timezones without daylight saving transitions though, such as UTC. [...] The preferred way of dealing with times is to always work in UTC, converting to localtime only when generating output to be read by humans.

Solution 3 - Python

Unfortunately, creating timezone aware dates using this method doesn't work.

If you are using Django, they have a utility function, make_aware, that does this correctly.

from django.utils.timezone import make_aware
from pytz import timezone

unaware_datetime = datetime(2007, 12, 5)
local_datetime = make_aware(datetime(2007, 12, 5))
specific_datetime = make_aware(datetime(2007, 12, 5), timezone("Australia/Melbourne"))

If you're not using Django, then the source code for the make_aware function may give you inspiration.

Solution 4 - Python

I'm revisiting some questions about date and time to see if some of the newer libraries prove more helpful in situations like this (or not). [pendulum][1] is one that stores timezone with date and time, making it particularly valuable in situations such as this.

>>> import pendulum
>>> d1 = pendulum.datetime(2007,12,5,6,30, tzinfo='US/Pacific')
>>> d1
<Pendulum [2007-12-05T06:30:00-08:00]>
>>> d1.timezone
<Timezone [US/Pacific]>
>>> d1.astimezone(tz='UTC')
<Pendulum [2007-12-05T14:30:00+00:00]>

Lots of other sweet features too. [1]: https://pendulum.eustace.io/docs/

Solution 5 - Python

Print d2_aware before .astimezone and you see PST-1 (Pacific Standard Time) but in first example you have LMT-1 (Local Mean Time) - and probably it can give 7 minutes difference.

But I don't know why pytz use different timezones.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjxstanfordView Question on Stackoverflow
Solution 1 - PythonKenialView Answer on Stackoverflow
Solution 2 - Pythonuser3834473View Answer on Stackoverflow
Solution 3 - PythonShadowView Answer on Stackoverflow
Solution 4 - PythonBill BellView Answer on Stackoverflow
Solution 5 - PythonfurasView Answer on Stackoverflow