79

在 Python 中,如何获取“3 年前的今天”的日期时间对象?

更新:FWIW,我不太关心准确性......即今天是 2 月 29 日,我不在乎我的回答是 2 月 28 日还是 3 月 1 日。在这种情况下,简洁比可配置性更重要。

4

7 回答 7

170

如果您需要准确使用dateutil模块来计算相对日期

from datetime import datetime
from dateutil.relativedelta import relativedelta

three_yrs_ago = datetime.now() - relativedelta(years=3)
于 2011-03-01T19:05:23.183 回答
114
import datetime
datetime.datetime.now() - datetime.timedelta(days=3*365)
于 2011-03-01T17:45:30.070 回答
30

当然,减去 365*3 天是错误的——你有一半以上的时间是跨过闰年的。

dt = datetime.now()
dt = dt.replace(year=dt.year-3)
# datetime.datetime(2008, 3, 1, 13, 2, 36, 274276)

ED:为了解决闰年问题,

def subtract_years(dt, years):
    try:
        dt = dt.replace(year=dt.year-years)
    except ValueError:
        dt = dt.replace(year=dt.year-years, day=dt.day-1)
    return dt
于 2011-03-01T18:00:46.717 回答
4
def add_years(dt, years):
    try:
        result = datetime.datetime(dt.year + years, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo)
    except ValueError:
        result = datetime.datetime(dt.year + years, dt.month, dt.day - 1, dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo)
    return result

>>> add_years(datetime.datetime.now(), -3)
datetime.datetime(2008, 3, 1, 12, 2, 35, 22000)
>>> add_years(datetime.datetime(2008, 2, 29), -3)
datetime.datetime(2005, 2, 28, 0, 0)
于 2011-03-01T18:04:10.930 回答
0

这也适用于闰年极端情况和非闰年。因为,如果天 = 29 和月份 = 2(2 月),非闰年会抛出一个值错误,因为没有 2 月 29 日,而 2 月的最后一天是 28 日,因此在该日期执行 -1一个 try-except 块。

from datetime import datetime

last_year = datetime.today().year - 1
month = datetime.today().month
day = datetime.today().day

try:
    # try returning same date last year
    last_year_date = datetime.strptime(f"{last_year}-{month}-{day}",'%Y-%m-%d').date()
except ValueError: 
    # incase of error due to leap year, return date - 1 in last year
    last_year_date = datetime.strptime(f"{last_year}-{month}-{day-1}",'%Y-%m-%d').date()

print(last_year_date)
于 2022-01-20T02:22:36.517 回答
-1
In [3]: import datetime as dt

In [4]: today=dt.date.today()

In [5]: three_years_ago=today-dt.timedelta(days=3*365)

In [6]: three_years_ago
Out[6]: datetime.date(2008, 3, 1)
于 2011-03-01T17:44:38.073 回答
-2

为什么不在更换年份之前简单地检查一下闰年。这不需要任何额外的包或try:Except。

def years_ago(dt, years):
    if dt.month == 2 and dt.day == 29:
        dt = dt.replace(day=28)

    return dt.replace(year=dt.year - years)
于 2016-05-31T13:54:32.153 回答