How to convert Python datetime dates to decimal/float years
from datetime import datetime as dt
import time
def toYearFraction(date):
def sinceEpoch(date): # returns seconds since epoch
return time.mktime(date.timetuple())
s = sinceEpoch
year = date.year
startOfThisYear = dt(year=year, month=1, day=1)
startOfNextYear = dt(year=year+1, month=1, day=1)
yearElapsed = s(date) - s(startOfThisYear)
yearDuration = s(startOfNextYear) - s(startOfThisYear)
fraction = yearElapsed/yearDuration
return date.year + fraction
Demo:
>>> toYearFraction(dt.today())
2011.47447514
This method is probably accurate to within the second (or the hour if daylight savings or other strange regional things are in effect). It also works correctly during leapyears. If you need drastic resolution (such as due to changes in the Earth's rotation) you are better off querying a net service.
After implementing the accepted solution, I had the revelation that this modern pandas version is identical, and much simpler:
dat['decimal_date']=dat.index.year+ (dat.index.dayofyear -1)/365
Must be used on a date-time index Pandas dataframe. Adding as this solution post comes up in the top of my google search for this issue.
This is a little simpler way than the other solutions:
import datetime
def year_fraction(date):
start = datetime.date(date.year, 1, 1).toordinal()
year_length = datetime.date(date.year+1, 1, 1).toordinal() - start
return date.year + float(date.toordinal() - start) / year_length
>>> print year_fraction(datetime.datetime.today())
2016.32513661
Note that this calculates the fraction based on the start of the day, so December 31 will be 0.997, not 1.0.