7

How do I convert fractional years to a real date by using Python? E. g. I have an array

[2012.343, 2012.444, 2012.509] 

containing fractional years and I would like to get "yyyy-mm-dd hh:mm".

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
paulchen
  • 1,009
  • 1
  • 10
  • 17
  • Parse out what you need and create a date using those values – Justin Jasmann Oct 10 '13 at 20:55
  • 1
    That seems like a really poor format, as years can vary in length (due to leap years and leap seconds). I'm not sure if floating point accuracy is an issue for precision at the minute level. – chepner Oct 10 '13 at 21:06
  • @chepner, floating point (double) accuracy is more than sufficient for most date calculations. As for dealing with years that aren't the same size, I once proposed an interesting solution: http://stackoverflow.com/a/4455700/5987 – Mark Ransom Oct 10 '13 at 21:55

3 Answers3

9

Here it`s a better solution, that give you the answer in datetime format.

from datetime import timedelta, datetime

def convert_partial_year(number):

    year = int(number)
    d = timedelta(days=(number - year)*365)
    day_one = datetime(year,1,1)
    date = d + day_one
    return date

This solution doesnt count the extra day in leap years. If you need to do so, make a function is_leap(year) that returns a bool, and change my code to this:

from datetime import timedelta, datetime

def convert_partial_year(number):

    year = int(number)
    d = timedelta(days=(number - year)*(365 + is_leap(year)))
    day_one = datetime(year,1,1)
    date = d + day_one
    return date

Check out datetime module. You can find a even better solution for your problem there.

Lucas Ribeiro
  • 6,132
  • 2
  • 25
  • 28
3
import datetime as DT
def t2dt(atime):
    """
    Convert atime (a float) to DT.datetime
    This is the inverse of dt2t.
    assert dt2t(t2dt(atime)) == atime
    """
    year = int(atime)
    remainder = atime - year
    boy = DT.datetime(year, 1, 1)
    eoy = DT.datetime(year + 1, 1, 1)
    seconds = remainder * (eoy - boy).total_seconds()
    return boy + DT.timedelta(seconds=seconds)

def dt2t(adatetime):
    """
    Convert adatetime into a float. The integer part of the float should
    represent the year.
    Order should be preserved. If adate<bdate, then d2t(adate)<d2t(bdate)
    time distances should be preserved: If bdate-adate=ddate-cdate then
    dt2t(bdate)-dt2t(adate) = dt2t(ddate)-dt2t(cdate)
    """
    year = adatetime.year
    boy = DT.datetime(year, 1, 1)
    eoy = DT.datetime(year + 1, 1, 1)
    return year + ((adatetime - boy).total_seconds() / ((eoy - boy).total_seconds()))
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
0

You can determine the epoch time of Jan 1 of the year part. Add that to the fractional part times 365 * 24 * 60 * 60. Then convert your epoch time to a date time.

see Python: Converting Epoch time into the datetime

Community
  • 1
  • 1
Fred Mitchell
  • 2,145
  • 2
  • 21
  • 29