5

Assume that I have a timezone-less datetime object:

import datetime
import pytz
fmt = "%Y-%m-%d %H:%M:%S %Z%z"
dtUnaware = datetime.datetime(1979,2,20,6)
print(dtUnaware.strftime(fmt))

This yields:

1979-02-20 06:00:00 

So far, so good. Now, I want to assign a timezone to this object. It seems like I could use either datetime.replace or pytz.localize.

First:

dtAware1 = dtUnaware.replace(tzinfo=pytz.timezone('Asia/Jerusalem'))
print(dtAware1.strftime(fmt))

returns: 1979-02-20 06:00:00 LMT+0221. Secondly:

dtAware2 = pytz.timezone('Asia/Jerusalem').localize(dtUnaware, is_dst=None)
print(dtAware2.strftime(fmt))

returns 1979-02-20 06:00:00 IST+0200.

What's wrong with the first method? It seems to assign a wrong timezone. Am I doing something wrong?

Dror
  • 12,174
  • 21
  • 90
  • 160

2 Answers2

1

From Pytz documentation : This library differs from the documented Python API for tzinfo implementations; if you want to create local wallclock times you need to use the localize() method documented in this document... Unfortunately these issues cannot be resolved without modifying the Python datetime implementation (see PEP-431)

My reading of that is that a pytz timezone is not exactly the same thing as a standard timezone. If you had a genuine timezone, first method should be good, but you have not.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
1

There is a flaw in the datetime API: when you assign a timezone to it, the timezone is not given the opportunity to know the date and time it should be configured for. The historical database that pytz uses goes back a long way, often to periods when the timezone name or offset were different than the ones in use today. Without being given the chance to adjust to a specific date period, the details of the timezone may be wrong.

Using localize is the way around this problem, since both the date and timezone are available within the function at the same time.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • a good explanation. It might be worth mentioning `localize()`'s `is_dst` parameter that handles ambiguous and non-existent local times. Also `normalize()` method could be used after `localize()` for non-existent local time. – jfs Jan 30 '15 at 01:14