Get yesterday's date in Python, DST-safe

匿名 (未验证) 提交于 2019-12-03 01:52:01

问题:

I have a python script that uses this call to get yesterday's date in YYYY-MM-DD format:

str(date.today() - timedelta(days=1)))

It works most of the time, but when the script ran this morning at 2013-03-11 0:35 CDT it returned "2013-03-09" instead of "2013-03-10".

Presumably daylight saving time (which started yesterday) is to blame. I guess the way timedelta(days=1) is implemented it subtracted 24 hours, and 24 hours before 2013-03-11 0:35 CDT was 2013-03-09 23:35 CST, which led to the result of "2013-03-09".

So what's a good DST-safe way to get yesterday's date in python?

UPDATE: After bukzor pointed out that my code should have worked properly, I went back to the script and determined it wasn't being used. It sets the default value, but a wrapper shell script was setting the date explicitly. So the bug is in the shell script, not the python script.

回答1:

datetime.date.fromordinal(datetime.date.today().toordinal()-1)


回答2:

I'm not able to reproduce your issue in python2.7 or python3.2:

>>> import datetime >>> today = datetime.date(2013, 3, 11) >>> print today 2013-03-11 >>> day = datetime.timedelta(days=1) >>> print today - day 2013-03-10

It seems to me that this is already the simplest implementation of a "daylight-savings safe" yesterday() function.



回答3:

You'll get 2013-03-10 if you use naive datetime object that knows nothing about timezones (and DST in particular):

from datetime import datetime, timedelta  dt_naive = datetime(2013, 3, 11, 0, 35) print((dt_naive - timedelta(days=1)).date()) # ignores DST # -> 2013-03-10

2013-03-09 is correct if you are interested what date it was 24 hours ago.

import pytz # $ pip install pytz  local_tz = pytz.timezone("America/Chicago") # specify your local timezone dt = local_tz.localize(dt_naive, is_dst=None) # raise if dt_naive is ambiguous yesterday = local_tz.normalize(dt - timedelta(days=1)).date() print(yesterday) # -> 2013-03-09

Note: .date() strips timezone info so you'll get 2013-03-10 again:

print(dt.date() - timedelta(days=1)) # -> 2013-03-10

To get yesterday in particular timezone:

from datetime import datetime, time, timedelta import pytz # $ pip install pytz  tz = pytz.timezone("America/Chicago") yesterday = datetime.now(tz).date() - timedelta(days=1)  # to add timezone info back (to get yesterday's midnight) midnight = tz.localize(datetime.combine(yesterday, time(0, 0)), is_dst=None)

Getting yesterday by stripping timezone info might fail if the timezone has missing days around that time. Then this method would produce non-existing date in the given timezone (tz.localize() raises an error).



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!