0

我试图在另一个日期前 7 天获得一个日期时间。

所以我在控制台中做:

import datetime
from dateutil.relativedelta import relativedelta

dt = datetime.date(2014, 10, 18)
dt_minus_one_week = datetime.date(2014, 10, 18) - relativedelta(days=7)

结果正如预期的那样datetime.date(2014, 10, 11)。但是,我正在运行一个 web 服务(使用 eve,但我认为这并不重要)应用程序很长时间,然后当我调用该方法来获取一周前的日期时,我得到datetime.date(2014, 10, 10). 代码与上面完全相同。

如果我重新启动应用程序,日期就是我所期望的。为什么会这样?relativedelta 是不确定的吗?有什么方法可以“重置”它,以便我可以再次获得正确的值?

4

3 回答 3

4

从评论中对你的函数的描述来看,你踩到了一个常见的python“地雷”。

def get_d_minus_one_pacific_local_date():
    return datetime.datetime.now(
            pytz.timezone('US/Pacific')).date() - relativedelta(days=1)

def get_relative_date(init=get_d_minus_one_pacific_local_date(), *args, **kwargs):
    return init + datetime.timedelta(*args, **kwargs)

# ...
get_relative_date(days=-7)

init当你在定义中设置默认值时get_relative_date,它不会被重新计算。所以当第二天到来时,它会使用函数定义时得到的值。

请参阅:https ://stackoverflow.com/a/530768/632706

于 2014-10-19T19:03:12.940 回答
1

如果您只处理几天,我会使用该datetime模块。

import datetime

old_date = datetime.date(2014, 10, 18)

new_date = old_date - datetime.timedelta(days=7)

输出将是datetime.date(2014, 10, 11). 我已经使用timedelta了一点,并且没有遇到日期不准确的问题。

于 2014-10-19T16:23:55.863 回答
1

假设 Web 服务器设置在美国/夏威夷时区,当前本地时间是 2014 年 10 月 17 日晚上 11 点。然后

In [57]: datetime.datetime(2014, 10, 17, 23, 0, 0, tzinfo=pytz.timezone('US/Pacific')).date()
Out[57]: datetime.date(2014, 10, 17)

但是,美国/太平洋的当前时间是

In [44]: now = datetime.datetime(2014, 10, 17, 23, 0, 0)

In [45]: hawaii = pytz.timezone('US/Hawaii')

In [46]: pacific = pytz.timezone('US/Pacific')

In [47]: pacific.normalize(hawaii.localize(now).astimezone(pacific)).date()
Out[47]: datetime.date(2014, 10, 18)

这会导致您看到的症状。

简而言之,你几乎不想通过直接将它提供给 tzinfo 来构建一个时区感知的日期时间:

datetime.datetime.now(pytz.timezone('US/Pacific')).date()

如果您使用的是 pytz,请使用 pytz 时区的 localize 方法:

tzone.localize(naive_date)

顺便一提,

datetime.datetime.now(pytz.timezone('US/Pacific')).date()

总是等价于

datetime.datetime.now().date()

或者

datetime.date.today()

datetime.datetime.now(pytz.timezone('US/Pacific'))datetime.datetime.now()与将 tzinfo 设置为相同 pytz.timezone('US/Pacific'),但如果您随后调用该date方法,则 tzinfo 无关紧要,因为您返回的只是年、月和日期。

于 2014-10-19T17:39:28.163 回答