在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:52:16  来源:igfitidea点击:

Get yesterday's date in Python, DST-safe

python

提问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 CDT2013-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()引发错误)。