Python: get datetime for '3 years ago today'
83,124
Solution 1
import datetime
datetime.datetime.now() - datetime.timedelta(days=3*365)
Solution 2
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)
Solution 3
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
Solution 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)
Related videos on Youtube
Author by
AP257
Updated on January 20, 2022Comments
-
AP257 over 2 years
In Python, how do I get a datetime object for '3 years ago today'?
UPDATE: FWIW, I don't care hugely about accuracy... i.e. it's Feb 29th today, I don't care whether I'm given Feb 28th or March 1st in my answer. Concision is more important than configurability, in this case.
-
Mark Ransom about 13 yearsPresumably if it's March 1 today, you want to get March 1 no matter if a leap year occurs in between or not? I think all the existing answers fail in that regard.
-
Glenn Maynard about 13 yearsThis site really needs a way for the community to override when people accept a clearly incorrect answer. 3*365 days is not 3 years, and there's a correct answer right there.
-
-
Jochen Ritzel about 13 yearsWell, now you have that other issue:
datetime.datetime(2008,2,29).replace(year=2005) -> ValueError
. It is still more accurate to catch that error and just subtract one extra day I guess. -
Mark Ransom about 13 yearsI keep forgetting about
replace
. It makes for a simpler solution than mine. -
Glenn Maynard about 13 years@Mark: I did at first, too; I initially did what you did. The site seems to have misplaced that version in the edit history, though.
-
PartialOrder over 10 yearsWhat happens after 2100?