7

I'm writing a python script which contains two lines of code converting the date that got passed into the method to UTC time:

print "Timezone: %s" % get_localzone()
date = datetime.now(tz=get_localzone())
print "Local time: %s" % date
utc = pytz.utc
utc_date = date.astimezone(utc)
print "UTC date: %s" % utc_date

and the result is:

Timezone: America/Chicago
Local time: 2015-06-17 14:58:45.224827-05:00
UTC date: 2015-06-17 19:58:45.224827+00:00

As you can see the offset in local time is "-05:00", nothing wrong with it, but when I create a customized datetime object with the same timezone:

date = datetime(2015, 6, 17, 14, 58, 45, tzinfo=get_localzone())

The result becomes:

Timezone: America/Chicago
Local time: 2015-06-17 14:58:45-05:51

The offset changed from "-05:00" to "-05:51". I even used the same time that the first "datetime.now()" generated, and the timezone did not change, would someone please explain to me why is this happening? Thanks!

YueQi Li
  • 303
  • 4
  • 15

1 Answers1

10

Instead of assigning the tzinfo parameter, use the localize method from pytz.

tz = get_localzone()
date = tz.localize(datetime(2015, 6, 17, 14, 58, 45))

This is discussed prominently in the pytz documentation, starting with the the first "Note" box, and in the very first code sample.

It's also shown in the tzlocal documentation, which is where (I assume) your get_localzone() method is coming from.

FYI, the -05:51 offset comes from the original LMT value of the America/Chicago time zone, which is -05:50:36 and is assumed to have been in use way back in 1883 as shown here. It's rounded to the nearest minute, giving the -05:51 LMT value in Python. You are seeing that offset because the localize method wasn't called, so pytz is just using the first offset known to that time zone's entry.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Thanks for the detailed answer, it solved my problem:) – YueQi Li Jun 17 '15 at 21:23
  • 1
    @YueQiLi: note: you should use `datetime.now(tz)` instead of `tz.localize(datetime.now())`. The latter may fail if the local time is ambiguous (e.g., during a DST transition). If the input time is not now then you could pass `is_dst` parameter to `tz.localize()`, to disambiguate. – jfs Jun 18 '15 at 10:14
  • @J.F.Sebastian Thanks, I just took a look on [the pytz documentation](http://pythonhosted.org/pytz/) and you are right, I will add this to my code. About the other similar question, despite the fact that both of our problems are caused by misusing of datetime constructor, it is still hard for beginners like me to categorize them into the same kind of problem. Keeping mine will be helpful for other people to avoid this kind of rookie mistake:) – YueQi Li Jun 18 '15 at 12:40
  • @YueQiLi: [duplicate questions are not deleted](http://meta.stackexchange.com/questions/5221/how-does-deleting-work-what-can-cause-a-post-to-be-deleted-and-what-does-that). Your post will be preserved as a sign post. The duplicates are about consolidating answers in a single place e.g., it is possible that in the future an analog of `localize()` maybe called automatically in the constructor: it is easier to update info in a single place (it is a common question despite being answered at the top of [the docs](http://pytz.sourceforge.net/)). – jfs Jun 18 '15 at 12:51