Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

datetime - Daylight savings time in Python

I am writing a program which deals a lot with timezones and crossing them. The two things I deal with most are creating a datetime object from "now" and then localizing a naive datetime object.

To create a datetime object from now in the pacific timezone, I am currently doing this (python 2.7.2+)

from datetime import datetime
import pytz
la = pytz.timezone("America/Los_Angeles")
now = datetime.now(la)

Is this correct with regards to DST? If not, I suppose I should be doing:

now2 = la.localize(datetime.now())

My question is why? Can anyone show me a case where the first is wrong and the seconds is right?

As for my seconds question, suppose I had a naive date and time from some user input for 9/1/2012 at 8:00am in Los Angeles, CA. Is the right way to make the datetime like this:

la.localize(datetime(2012, 9, 1, 8, 0))

If not, how should I be building these datetimes?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From the pytz documentation:

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.

So ideally you should be using utcnow instead of now.

Assuming for some reason that your hands are tied and you need to work with local times, you can still run into a problem with trying to localize the current time if you're doing it during the daylight saving transition window. The same datetime might occur twice, once during daylight time and again during standard time, and the localize method doesn't know how to settle the conflict unless you tell it explicitly with the is_dst parameter.

So to get the current UTC time:

utc = pytz.timezone('UTC')
now = utc.localize(datetime.datetime.utcnow())

And to convert it to your local time (but only when you must):

la = pytz.timezone('America/Los_Angeles')
local_time = now.astimezone(la)

Edit: as pointed out in the comments by @J.F. Sebastian, your first example using datetime.now(tz) will work in all cases. Your second example fails during the fall transition as I outlined above. I still advocate using UTC instead of local time for everything except display.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...