36

I'm trying to convert timezone aware datetime object to UTC and then back to it's original timezone. I have a following snippet

t = datetime(
    2013, 11, 22, hour=11, minute=0,
    tzinfo=pytz.timezone('Europe/Warsaw')
)

now in ipython:

In [18]: t
Out[18]: datetime.datetime(
    2013, 11, 22, 11, 0, tzinfo=<DstTzInfo 'Europe/Warsaw' WMT+1:24:00 STD>
)

and now let's try to do conversion to UTC and back. I would expect to have the same representation as:

In [19]: t.astimezone(pytz.utc).astimezone(pytz.timezone('Europe/Warsaw'))
Out[19]: datetime.datetime(
    2013, 11, 22, 10, 36, tzinfo=<DstTzInfo 'Europe/Warsaw' CET+1:00:00 STD>
)

Yet we see that Out[18] and Out[19] differ. What's going on?

3
  • 1
    Django stores datetimes naive database wise. If you handle that case, have a look here to convert dates to the timezone you need: docs.djangoproject.com/en/dev/topics/i18n/timezones/#usage
    – Jingo
    Commented Aug 30, 2013 at 21:06
  • whether Django stores naive datetimes of not is controlled by the USE_TZ setting. If that is True then Django treats datetimes in forms etc as being in the current timezone and stores them in the db converted to UTC.
    – Anentropic
    Commented Feb 18, 2014 at 13:32
  • 2
    Could you specify the "mind blowing behaviour" further? I don't like clickbait on StackExchange Commented Mar 14, 2018 at 15:17

1 Answer 1

73

The documentation http://pytz.sourceforge.net/ states "Unfortunately using the tzinfo argument of the standard datetime constructors 'does not work' with pytz for many timezones." The code:

t = datetime(
    2013, 5, 11, hour=11, minute=0,
    tzinfo=pytz.timezone('Europe/Warsaw')
)

doesn't work according to this, instead you should use the localize method:

t = pytz.timezone('Europe/Warsaw').localize(
        datetime(2013, 5, 11, hour=11, minute=0))
1
  • 27
    Python datetime module assumes a timezone object has a constant UTC offset. Pytz timezone objects have varying UTC offsets (because daylight savings times as well as historical timezone changes). When you use pytz's localize() it can pick up the right offset for that particular date. When you use datetime's replace(tzinfo==) you end up with the oldest UTC offset for that timezone in the database. Commented Jun 17, 2014 at 14:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.