Python: разница между двумя датами в месяцах

Возможный дубликат:
Лучший способ найти месяцы между двумя датами (в питоне)

Я хотел бы знать, как я могу иметь точное количество месяцев для этой разницы:

date1 = datetime.strptime(str('2011-08-15 12:00:00'), '%Y-%m-%d %H:%M:%S')
date2 = datetime.strptime(str('2012-02-15'), '%Y-%m-%d')

Результаты date2-date1 в

datetime.timedelta(183, 43200)

Я хотел бы знать точное количество месяцев, в этом случае должно возвращаться 5, а не 6 (из-за часа)

4 ответа

Решение

С помощью calendar Модуль, чтобы узнать, сколько дней у каждого месяца, вы можете просто посчитать месяцы.

from calendar import monthrange
from datetime import datetime, timedelta

def monthdelta(d1, d2):
    delta = 0
    while True:
        mdays = monthrange(d1.year, d1.month)[1]
        d1 += timedelta(days=mdays)
        if d1 <= d2:
            delta += 1
        else:
            break
    return delta

Вы можете использовать http://labix.org/python-dateutil.

In [4]: from datetime import datetime

In [5]: date1 = datetime.strptime(str('2011-08-15 12:00:00'), '%Y-%m-%d %H:%M:%S')

In [6]: date2 = datetime.strptime(str('2012-02-15'), '%Y-%m-%d')

In [7]: from dateutil import relativedelta

In [8]: r = relativedelta.relativedelta(date1, date2)

In [9]: r
Out[9]: relativedelta(months=-5, days=-30, hours=-12)

Только вы знаете требования, которым вы должны соответствовать, но тот факт, что между этими двумя датами есть 183 дня и 43200 SI секунд, подчеркивает присущую субъективность в определении того, сколько месяцев "действительно".

Месяц 30 дней, или (365 / 12) дней, или ((365 * 4 + 1) / 48) дней, или...?

День всегда 86400 секунд, или вы считаете исторические високосные секунды, или вы прогнозируете високосные секунды для будущих дат?

Эти решения влияют на ответ, который алгоритм, который вы, по-видимому, желаете, даст вам для определенных входных дат, которые близки к этим границам.

На мой взгляд, более интуитивно понятно считать месяцы атомными единицами времени для этой цели и использовать эту формулу: (date2.year - date1.year) * 12 + (date2.month - date1.month)

Преимущество такого способа состоит в том, что имеется мало зависимостей от модулей и нет циклических циклов - месяцы можно найти прямым вычислением.

import datetime as dt

def months_between(date1,date2):
    if date1>date2:
        date1,date2=date2,date1
    m1=date1.year*12+date1.month
    m2=date2.year*12+date2.month
    months=m2-m1
    if date1.day>date2.day:
        months-=1
    elif date1.day==date2.day:
        seconds1=date1.hour*3600+date1.minute+date1.second
        seconds2=date2.hour*3600+date2.minute+date2.second
        if seconds1>seconds2:
            months-=1
    return months

date1 = dt.datetime.strptime('2011-08-15 12:00:00', '%Y-%m-%d %H:%M:%S')
date2 = dt.datetime.strptime('2012-02-15', '%Y-%m-%d')
print(months_between(date1,date2))
# 5

date1 = dt.datetime.strptime('2011-08-15 12:00:00', '%Y-%m-%d %H:%M:%S')
date2 = dt.datetime.strptime('2012-02-15 11:59:00', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 5

date2 = dt.datetime.strptime('2012-02-15 12:00:00', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 6

date2 = dt.datetime.strptime('2012-02-15 12:00:01', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 6
Другие вопросы по тегам