python как преобразовать даты datetime в десятичные годы
Я ищу способ преобразования объектов datetime в десятичный год. Ниже приведен пример
>>> obj = SomeObjet()
>>> obj.DATE_OBS
datetime.datetime(2007, 4, 14, 11, 42, 50)
Как преобразовать datetime.датавремя(2007, 4, 14, 11, 42, 50) десятичная лет? От этого формата dd/mm / yyyy до такого формата yyyy.yyyy
6 ответов
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
демо:
>>> toYearFraction(dt.today())
2011.47447514
этот метод, вероятно, точен в течение секунды (или часа, если действует летнее время или другие странные региональные вещи). Он также работает правильно во время leapyears. Если вам нужно резкое разрешение (например, из-за изменений во вращении Земли), вам лучше запросить сетевую службу.
Я предполагаю, что вы используете это для сравнения значений datetime. Для этого, пожалуйста, используйте timedelta объекты вместо reiniventing колесо.
пример:
>>> from datetime import timedelta
>>> from datetime import datetime as dt
>>> d = dt.now()
>>> year = timedelta(days=365)
>>> tomorrow = d + timedelta(days=1)
>>> tomorrow + year > d + year
True
если по какой-то причине вы действительно нужно десятичное лет, datetime
метод объекты strftime()
может дать вам целое представление день на %j
- если это то, что вы ищете, ниже простой пример (только на 1 день разрешение):
>>> from datetime import datetime
>>> d = datetime(2007, 4, 14, 11, 42, 50)
>>> (float(d.strftime("%j"))-1) / 366 + float(d.strftime("%Y"))
2007.2814207650274
после реализации принятого решения у меня было откровение, что эта современная версия панды идентична и намного проще:
dat['decimal_date']=dat.index.year+ (dat.index.dayofyear -1)/365
должен использоваться в фрейме данных индекса даты и времени Pandas. Добавление как это решение сообщение появляется в верхней части моего поиска google для этой проблемы.
Это немного проще, чем другие решения:
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
обратите внимание, что это вычисляет дробь на основе начала дня, поэтому 31 декабря будет 0.997, а не 1.0.
удивлен, никто не упомянул об этом... но ... --1--> объекты, которые являются результатом вычитания datetime.datetime
объекты имеют метод разделения. Таким образом, вы можете использовать простую функцию
from datetime import datetime
def datetime2year(dt):
year_part = dt - datetime(year=dt.year, month=1, day=1)
year_length = datetime(year=dt.year+1, month=1, day=1) - datetime(year=dt.year, month=1, day=1)
return dt.year + year_part/year_length
где деление между datetime.timedelta
объекты.
можно вычислить десятичную дату, используя юлианскую дату Панды и следующие формулы.
в случае, когда ваш фрейм данных pandas имеет индекс, который является датой-временем:
JD=dat.index.to_julian_date() #create julian date
L= JD+68569
N= 4*L/146097
L= L-(146097*N+3)/4
I= 4000*(L+1)/1461001
L= L-1461*I/4+31
J= 80*L/2447
K= L-2447*J/80
L= J/11
J= J+2-12*L
decimal_date= 100*(N-49)+I+L
decimal_date-это серия вашей даты (в том же TZ, что и индекс фрейма данных) в виде чего-то вроде 2007.123452.