在 DST 安全的 Python 中获取昨天的日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15344710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get yesterday's date in Python, DST-safe
提问by Ike Walker
I have a python script that uses this call to get yesterday's date in YYYY-MM-DD format:
我有一个 python 脚本,它使用这个调用以 YYYY-MM-DD 格式获取昨天的日期:
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 CDTit returned "2013-03-09"instead of "2013-03-10".
它大部分时间都可以工作,但是当脚本今天早上运行时,2013-03-11 0:35 CDT它返回"2013-03-09"而不是"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 CDTwas 2013-03-09 23:35 CST, which led to the result of "2013-03-09".
据推测,夏令时(昨天开始)是罪魁祸首。我猜timedelta(days=1)实现的方式是它减去 24 小时,而 24 小时之前2013-03-11 0:35 CDT是2013-03-09 23:35 CST,这导致了"2013-03-09".
So what's a good DST-safe way to get yesterday's date in python?
那么在 python 中获取昨天日期的一个好的 DST 安全方法是什么?
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.
更新:在 bukzor 指出我的代码应该可以正常工作后,我回到脚本并确定它没有被使用。它设置了默认值,但包装器 shell 脚本正在显式设置日期。所以错误在shell脚本中,而不是python脚本中。
回答by Rob?
datetime.date.fromordinal(datetime.date.today().toordinal()-1)
回答by bukzor
I'm not able to reproduce your issue in python2.7 or python3.2:
我无法在 python2.7 或 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.
在我看来,这已经是“夏令时安全”yesterday()功能的最简单实现了。
回答by jfs
You'll get 2013-03-10if you use naive datetimeobject that knows nothing about timezones (and DST in particular):
2013-03-10如果您使用datetime对时区(尤其是夏令时)一无所知的幼稚对象,您会得到:
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-09is correct if you are interested what date it was 24 hours ago.
2013-03-09如果您对 24 小时前的日期感兴趣,那是正确的。
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-10again:
注意:.date()剥离时区信息,以便您2013-03-10再次获得:
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).
如果时区在那个时间附近缺少天数,则通过剥离时区信息获取昨天可能会失败。然后此方法将在给定的时区中生成不存在的日期(tz.localize()引发错误)。

