Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 769
jmetz Avatar asked Aug 30 '12 18:08

jmetz


People also ask

How does Python handle Daylight Savings Time?

You can use time. localtime and look at the tm_isdst flag in the return value. Using time. localtime() , you can ask the same question for any arbitrary time to see whether DST would be (or was) in effect for your current time zone.

How do you check is daylight saving is on in Python?

daylight() Function. Time. daylight() function which returns a non zero integer value when Daylight Saving Time (DST) is defined, else it returns 0.

What is the function to offset the date for daylight saving in time series?

IsDaylightSavingTime(DateTimeOffset) Indicates whether a specified date and time falls in the range of daylight saving time for the time zone of the current TimeZoneInfo object.

Does pytz account for daylight savings?

Timedelta and DSTpytz will help you to tell if an date is under DST influence by checking dst() method.


2 Answers

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.

like image 71
Mark Ransom Avatar answered Sep 18 '22 13:09

Mark Ransom


The first solution is correct with regards to DST, and the second solution is bad.

I'll give an example. Here in Europe, when running this code:

from datetime import datetime
import pytz # $ pip install pytz

la = pytz.timezone("America/Los_Angeles")
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
now = datetime.now(la)
now2 = la.localize(datetime.now())
now3 = datetime.now()
print(now.strftime(fmt))
print(now2.strftime(fmt))
print(now3.strftime(fmt))

I get the following:

2012-08-30 12:34:06 PDT-0700
2012-08-30 21:34:06 PDT-0700
2012-08-30 21:34:06 

datetime.now(la) creates a datetime with the current time in LA, plus the timezone information for LA.

la.localize(datetime.now()) adds timezone information to the naive datetime, but does no timezone conversion; it just assumes the time was already in this timezone.

datetime.now() creates a naive datetime (without timezone information) with the local time.

As long as you are in LA, you will not see the difference, but if your code ever runs somewhere else, it will probably not do what you wanted.

Apart from that, if you ever need to deal seriously with timezones, it is better to have all your times in UTC, saving yourself a lot of trouble with DST.

like image 45
user711413 Avatar answered Sep 18 '22 13:09

user711413