Как вычислить дату через шесть месяцев от текущей даты, используя модуль Python datetime? - PullRequest
299 голосов
/ 13 февраля 2009

Я использую модуль даты и времени Python. Я рассчитываю рассчитать дату 6 месяцев с текущей даты. Может ли кто-нибудь помочь мне с этим?

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

Ответы [ 41 ]

861 голосов
/ 10 декабря 2010

Я нашел это решение хорошим. (Используется расширение python-dateutil )

from datetime import date
from dateutil.relativedelta import relativedelta

six_months = date.today() + relativedelta(months=+6)

Преимущество этого подхода заключается в том, что он решает проблемы с 28, 30, 31 днем ​​и т. Д. Это становится очень полезным при обработке бизнес-правил и сценариев (например, генерация счетов и т. Д.)

$ date(2010,12,31)+relativedelta(months=+1)
  datetime.date(2011, 1, 31)

$ date(2010,12,31)+relativedelta(months=+2)
  datetime.date(2011, 2, 28)
46 голосов
/ 13 февраля 2009

Ну, это зависит от того, что вы подразумеваете под 6 месяцами от текущей даты.

  1. В натуральных месяцах:

    (day, month, year) = (day, (month+6)%12, year+(month+6)/12)
    
  2. Используя определение банкира, 6 * 30:

    date += datetime.timedelta(6*30)
    
19 голосов
/ 13 февраля 2009
import datetime
print (datetime.date.today() + datetime.timedelta(6*365/12)).isoformat()
17 голосов
/ 02 февраля 2017

Для начала расчета месяца к месяцу:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)
13 голосов
/ 13 февраля 2009

Что вы подразумеваете под «6 месяцев». 2009-02-13 + 6 месяцев == 2009-08-13 или 2009-02-13 + 6 * 30 дней?

import mx.DateTime as dt

#6 Months
dt.now()+dt.RelativeDateTime(months=6)
#result is '2009-08-13 16:28:00.84'

#6*30 days
dt.now()+dt.RelativeDateTime(days=30*6)
#result is '2009-08-12 16:30:03.35'

Подробнее о mx.DateTime

12 голосов
/ 24 сентября 2018

С Python 3.x вы можете сделать это так:

from datetime import datetime, timedelta
from dateutil.relativedelta import *

date = datetime.now()
print(date)
# 2018-09-24 13:24:04.007620

date = date + relativedelta(months=+6)
print(date)
# 2019-03-24 13:24:04.007620

но вам нужно будет установить python-dateutil модуль:

pip install python-dateutil
12 голосов
/ 12 августа 2010

Это решение работает правильно для декабря, что большинство ответов на этой странице нет. Прежде чем использовать модуль (%) или целочисленное деление (//), необходимо сначала сдвинуть месяцы с основания 1 (т.е. января = 1) на основание 0 (т.е. января = 0), в противном случае ноябрь (11) плюс 1 месяц дает вам 12 , который при нахождении остатка (12% 12) дает 0.

(И не предлагайте "(месяц% 12) + 1" или октябрь + 1 = декабрь!)

def AddMonths(d,x):
    newmonth = ((( d.month - 1) + x ) % 12 ) + 1
    newyear  = d.year + ((( d.month - 1) + x ) / 12 ) 
    return datetime.date( newyear, newmonth, d.day)

Однако ... Это не объясняет проблему, такую ​​как 31 января + один месяц. Итак, мы возвращаемся к ОП - что вы имеете в виду, добавляя месяц? Единственное, что нужно сделать, это вернуться назад, пока вы не доберетесь до действительного дня, учитывая, что большинство людей предполагает, что последний день января плюс один месяц равен последнему дню февраля. Это будет работать и на отрицательных числах месяцев. Доказательство:

>>> import datetime
>>> AddMonths(datetime.datetime(2010,8,25),1)
datetime.date(2010, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),4)
datetime.date(2010, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),5)
datetime.date(2011, 1, 25)
>>> AddMonths(datetime.datetime(2010,8,25),13)
datetime.date(2011, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),24)
datetime.date(2012, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-1)
datetime.date(2010, 7, 25)
>>> AddMonths(datetime.datetime(2010,8,25),0)
datetime.date(2010, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-12)
datetime.date(2009, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-8)
datetime.date(2009, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-7)
datetime.date(2010, 1, 25)>>> 
12 голосов
/ 07 июля 2010

Итак, вот пример dateutil.relativedelta, который я нашел полезным для итерации в течение прошлого года, пропуская месяц каждый раз до текущей даты:

>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.datetime.today()
>>> month_count = 0
>>> while month_count < 12:
...  day = today - relativedelta(months=month_count)
...  print day
...  month_count += 1
... 
2010-07-07 10:51:45.187968
2010-06-07 10:51:45.187968
2010-05-07 10:51:45.187968
2010-04-07 10:51:45.187968
2010-03-07 10:51:45.187968
2010-02-07 10:51:45.187968
2010-01-07 10:51:45.187968
2009-12-07 10:51:45.187968
2009-11-07 10:51:45.187968
2009-10-07 10:51:45.187968
2009-09-07 10:51:45.187968
2009-08-07 10:51:45.187968

Как и в случае с другими ответами, вы должны выяснить, что вы на самом деле подразумеваете под "через 6 месяцев". Если вы имеете в виду «сегодняшний день месяца в месяце шесть лет в будущем», то это будет делать:

datetime.datetime.now() + relativedelta(months=6)
11 голосов
/ 13 февраля 2009

Нет прямого способа сделать это с датой и временем Python.

Проверьте тип относительной дельты в python-dateutil . Позволяет указать дельту времени в месяцах.

11 голосов
/ 13 апреля 2011

Я знаю, что это было в течение 6 месяцев, однако ответ показывает в Google "добавление месяцев в python", если вы добавляете один месяц:

import calendar

date = datetime.date.today()    //Or your date

datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])

это будет считать дни в текущем месяце и добавлять их к текущей дате, использование 365/12 будет означать, что 1/12 года может вызвать проблемы для коротких / длинных месяцев, если вы перебираете дату.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...