Improving support for timezones in Python (was: UTC timezone causing brain explosions)
Ben Finney ben+pyt...@benfinney.id.au writes: Time zones are a hairy beast to manage, made all the more difficult because national politicians continually fiddle with them which means they can't just be a built-in part of the Python standard library. PyCon 2013 had a good talk on calendaring and timezone issues URL:http://www.pyvideo.org/video/1765/blame-it-on-caesar-what-you-need-to-know-about-d (video at URL:https://www.youtube.com/watch?v=GBKqRhn0ekM). The speaker, Lennart Regebro, maintains a library for getting the local timezone URL:https://pypi.python.org/pypi/tzlocal, and is currently working on a PEP to improve timezone support directly in the standard library URL:http://www.python.org/dev/peps/pep-0431/. He also reinforces the message that UTC is the canonical timezone for storing and manipulating timestamp values, and we should be converting to/from those canonical values as early/late as possible in our programs. -- \ “Reality must take precedence over public relations, for nature | `\cannot be fooled.” —Richard P. Feynman | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: Improving support for timezones in Python (was: UTC timezone causing brain explosions)
On Fri, Jan 31, 2014 at 1:26 PM, Ben Finney ben+pyt...@benfinney.id.au wrote: He also reinforces the message that UTC is the canonical timezone for storing and manipulating timestamp values, and we should be converting to/from those canonical values as early/late as possible in our programs. Call it a UTC Sandwich, like Ned Batchelder's Unicode Sandwich. It's a good idea for the same reason. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
UTC timezone causing brain explosions
Following up on my earlier note about UTC v. GMT, I am having some trouble grokking attempts to convert a datetime into UTC. Consider these three values: import pytz UTC = pytz.timezone(UTC) UTC UTC LOCAL_TZ = pytz.timezone(America/Chicago) LOCAL_TZ DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD now = datetime.datetime.now() now datetime.datetime(2014, 1, 29, 15, 39, 35, 263666) All well and good, right? The variable now is a naive datetime object. I happen to be sitting in a chair in the city of Chicago, so let's call it what it is, a datetime in the America/Chicago timezone: s = LOCAL_TZ.localize(now) s datetime.datetime(2014, 1, 29, 15, 39, 35, 263666, tzinfo=DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD) That looks good to me. Now, let's normalize it to UTC: t = UTC.normalize(s) t datetime.datetime(2014, 1, 29, 15, 39, 35, 263666, tzinfo=UTC) t.hour 15 WTF? Why isn't the t.hour == 21? Okay, let's see what GMT does for us: GMT = pytz.timezone(GMT) u = GMT.normalize(s) u datetime.datetime(2014, 1, 29, 21, 39, 35, 263666, tzinfo=StaticTzInfo 'GMT') u.hour 21 That looks correct, but I don't understand why I don't get hour==21 out of the UTC.normalize call. It's like it's a no-op. Skip -- https://mail.python.org/mailman/listinfo/python-list
Re: UTC timezone causing brain explosions
On 01/29/2014 01:52 PM, Skip Montanaro wrote: Following up on my earlier note about UTC v. GMT, I am having some trouble grokking attempts to convert a datetime into UTC. Okay, let's see what GMT does for us: GMT = pytz.timezone(GMT) u = GMT.normalize(s) u datetime.datetime(2014, 1, 29, 21, 39, 35, 263666, tzinfo=StaticTzInfo 'GMT') u.hour 21 That looks correct, but I don't understand why I don't get hour==21 out of the UTC.normalize call. It's like it's a no-op. Having not examined the code, I can't tell you why UTC is different. I can say that .astimezone seems to work in all cases: -- GMT StaticTzInfo 'GMT' -- UTC UTC -- LOCAL_TZ = pytz.timezone(America/Los_Angeles) -- now = datetime.datetime.now() -- s = LOCAL_TZ.localize(now) -- s datetime.datetime(2014, 1, 29, 14, 9, 56, 494967, tzinfo=DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD) -- s.astimezone(UTC) datetime.datetime(2014, 1, 29, 22, 9, 56, 494967, tzinfo=UTC) -- s.astimezone(GMT) datetime.datetime(2014, 1, 29, 22, 9, 56, 494967, tzinfo=StaticTzInfo 'GMT') -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: UTC timezone causing brain explosions
Skip Montanaro s...@pobox.com writes: Following up on my earlier note about UTC v. GMT, I am having some trouble grokking attempts to convert a datetime into UTC. For what it's worth, you're not alone. Time zones are a hairy beast to manage, made all the more difficult because national politicians continually fiddle with them which means they can't just be a built-in part of the Python standard library. Consider these three values: import pytz UTC = pytz.timezone(UTC) UTC UTC LOCAL_TZ = pytz.timezone(America/Chicago) LOCAL_TZ DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD now = datetime.datetime.now() now datetime.datetime(2014, 1, 29, 15, 39, 35, 263666) All well and good, right? Not really :-) You avoid the pain if you never create naive datetime values in the first place. Instead, specify the timezone for the value you're creating:: now = datetime.datetime.now(tz=LOCAL_TZ) now datetime.datetime(2014, 1, 29, 16, 35, 7, 900526, tzinfo=DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD) That way the value will respond correctly to requests to convert it to whatever timezone you specify:: MELBOURNE = pytz.timezone(Australia/Melbourne) now.astimezone(MELBOURNE) datetime.datetime(2014, 1, 30, 9, 35, 7, 900526, tzinfo=DstTzInfo 'Australia/Melbourne' EST+11:00:00 DST) now.astimezone(UTC) datetime.datetime(2014, 1, 29, 22, 35, 7, 900526, tzinfo=UTC) now.astimezone(LOCAL_TZ) datetime.datetime(2014, 1, 29, 16, 35, 7, 900526, tzinfo=DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD) -- \ “We tend to scoff at the beliefs of the ancients. But we can't | `\scoff at them personally, to their faces, and this is what | _o__) annoys me.” —Jack Handey | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: UTC timezone causing brain explosions
On Wed, Jan 29, 2014 at 1:52 PM, Skip Montanaro s...@pobox.com wrote: Following up on my earlier note about UTC v. GMT, I am having some trouble grokking attempts to convert a datetime into UTC. Consider these three values: import pytz UTC = pytz.timezone(UTC) LOCAL_TZ = pytz.timezone(America/Chicago) LOCAL_TZ DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD now = datetime.datetime.now() now datetime.datetime(2014, 1, 29, 15, 39, 35, 263666) All well and good, right? The variable now is a naive datetime object. I happen to be sitting in a chair in the city of Chicago, so let's call it what it is, a datetime in the America/Chicago timezone: s = LOCAL_TZ.localize(now) s datetime.datetime(2014, 1, 29, 15, 39, 35, 263666, tzinfo=DstTzInfo 'America/Chicago' CST-1 day, 18:00:00 STD) That looks good to me. Now, let's normalize it to UTC: I don't think .normalize() doesn't do what you think it does; it's related to timezones with DST. I believe you want datetime.astimezone() instead. t = UTC.normalize(s) t datetime.datetime(2014, 1, 29, 15, 39, 35, 263666, tzinfo=UTC) t.hour 15 WTF? Why isn't the t.hour == 21? Because you didn't actually perform a proper timezone conversion: t = s.astimezone(UTC) t datetime.datetime(2014, 1, 29, 21, 39, 35, 263666, tzinfo=UTC) t.hour == 21 True snip That looks correct, but I don't understand why I don't get hour==21 out of the UTC.normalize call. It's like it's a no-op. It is indeed a no-op: You can take shortcuts when dealing with the UTC side of timezone conversions. normalize() and localize() are not really necessary when there are no daylight savings time transitions to deal with. -- http://pytz.sourceforge.net Cheers, Chris -- https://mail.python.org/mailman/listinfo/python-list