Python: 获取“3年前的今天”的日期时间

在 Python 中,如何获得“3年前的今天”的 datetime 对象?

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

101696 次浏览
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)
import datetime
datetime.datetime.now() - datetime.timedelta(days=3*365)

Subtracting 365*3 days is wrong, of course--you're crossing a leap year more than half the time.

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

ED: To get the leap-year issue right,

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
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)

If you need to be exact use the dateutil module to calculate relative dates

from datetime import datetime
from dateutil.relativedelta import relativedelta


three_yrs_ago = datetime.now() - relativedelta(years=3)

Why not simply do a check for leap year before replacing the year. This does not need any extra package or 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)

This works to cater for leap year corner cases and non-leap years too. Because, if day = 29 and month = 2 (Feb), a non-leap year would throw a value error because there is no 29th Feb and the last day of Feb would be 28th, thus doing a -1 on the date works in a try-except block.

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)