Is there a more efficient way of doing this below? I want to have the difference in years between two dates as a single scalar. Any suggestions are welcome.
I think what you're looking for is:
difference_in_years = difference.dt.days / 365.25
Before install library :
choco upgrade Python -y
python pip install python-dateutil
In One line in Python in Cmder (windows) :
python -c "import datetime; from dateutil.relativedelta import relativedelta; myBirthday = datetime.datetime(2019,2,6,11,0,0,0); now = datetime.datetime.utcnow(); diff = relativedelta(now, myBirthday); print ("'My'+'" "'+'year'+'" "'+':'+'" "'+'%d''" "''and''" "''%d''" "''microseconds'" % (diff.years, diff.microseconds))"
In Batch escape percent with %% :
python -c "import datetime; from dateutil.relativedelta import relativedelta; myBirthday = datetime.datetime(2019,2,6,11,0,0,0); now = datetime.datetime.utcnow(); diff = relativedelta(now, myBirthday); print ("'My'+'" "'+'year'+'" "'+':'+'" "'+'%%d''" "''and''" "''%%d''" "''microseconds'" %% (diff.years, diff.microseconds))"
More robust function - calculates difference in years (age) and days:
def get_diff_in_years_and_days(from_date, to_date):
try:
from_in_this_year = date(to_date.year, from_date.month, from_date.day)
except:
from_in_this_year = date(to_date.year, from_date.month, from_date.day-1) # today is feb in leap year
if from_in_this_year <= to_date:
years = to_date.year - from_date.year
days = (to_date - from_in_this_year).days
else:
years = to_date.year - from_date.year - 1
try:
from_in_prev_year = date(to_date.year-1, from_date.month, from_date.day)
except:
from_in_prev_year = date(to_date.year-1, from_date.month, from_date.day-1) # today is feb in leap year
days = (to_date - from_in_prev_year).days
assert days>=0 and days<=365, days
assert years>=0, years
return years, days
some unit-tests:
self.assertEqual((0, 0), get_diff_in_years_and_days(date(2018,1, 1), date(2018,1, 1)))
self.assertEqual((1, 0), get_diff_in_years_and_days(date(2017,1, 1), date(2018,1, 1)))
self.assertEqual((1, 1), get_diff_in_years_and_days(date(2017,1, 1), date(2018,1, 2)))
self.assertEqual((2, 0), get_diff_in_years_and_days(date(2016,2,29), date(2018,2,28)))
self.assertEqual((2, 1), get_diff_in_years_and_days(date(2014,2,28), date(2016,2,29)))
self.assertEqual((1,364), get_diff_in_years_and_days(date(2014,2,28), date(2016, 2,27)))
self.assertEqual((3,30) , get_diff_in_years_and_days(date(2015,10,1), date(2018,10,31)))
self.assertEqual((10,30), get_diff_in_years_and_days(date(2010,10,1), date(2020,10,31)))
self.assertEqual((3,31) , get_diff_in_years_and_days(date(2015,10,1), date(2018,11, 1)))
self.assertEqual((2,364), get_diff_in_years_and_days(date(2015,10,1), date(2018, 9,30)))
Here's what I came up with, without using an external dependency:
def year_diff(d1, d2):
"""Returns the number of years between the dates as a positive integer."""
later = max(d1, d2)
earlier = min(d1, d2)
result = later.year - earlier.year
if later.month < earlier.month or (later.month == earlier.month and later.day < earlier.day):
result -= 1
return result
If you want precise results, I recommend using the dateutil library.
from dateutil.relativedelta import relativedelta
difference_in_years = relativedelta(end_date, start_date).years
This is for complete years (e.g. a person's age). If you want fractional years, then add months, days, hours, ... up to the desired precision.
Just do this:
from dateutil.relativedelta import relativedelta
myBirthday = datetime.datetime(1983,5,20,0,0,0,0)
now = datetime.datetime.now()
difference = relativedelta(now, myBirthday)
print("My years: "+str(difference.years))