Как рассчитать дату за шесть месяцев с текущей даты с помощью модуля Python datetime?

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

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

Ответ 1

import datetime
print (datetime.date.today() + datetime.timedelta(6*365/12)).isoformat()

Ответ 2

Я нашел это решение хорошим. (Для этого используется расширение 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)

Ответ 3

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

  • Использование естественных месяцев:

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

    date += datetime.timedelta(6*30)
    

Ответ 4

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

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)

Ответ 5

Что вы подразумеваете под "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

Ответ 6

С 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

Ответ 7

Итак, вот пример 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)

Ответ 8

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

(И не предлагайте "(месяц% 12) + 1" или Oct + 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 января + один месяц. Итак, мы возвращаемся к OP - что вы подразумеваете, добавив месяц? Один soln должен отступить, пока вы не доберетесь до действительного дня, учитывая, что большинство людей предпочтут последний день jan, плюс один месяц, равный последнему дню февраля. Это будет работать и с отрицательным числом месяцев. Доказательство:

>>> 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)>>> 

Ответ 9

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

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

Ответ 10

Я знаю, что это было в течение 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 года может вызвать проблемы в течение коротких/длинных месяцев, если вы повторяете дату.

Ответ 11

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

import datetime

def in_the_future(months=1):
    year, month, day = datetime.date.today().timetuple()[:3]
    new_month = month + months
    return datetime.date(year + (new_month / 12), (new_month % 12) or 12, day)

API немного неуклюж, но работает как пример. Также явно не будет работать на угловых делах, таких как 2008-01-31 + 1 месяц. :)

Ответ 12

В пакете Dateutil реализована такая функциональность. Но имейте в виду, что это будет наивно, как уже указывали другие.

Ответ 13

Использование стандартных библиотек Python, т.е. без dateutil или других, и решение проблемы "31 февраля":

import datetime
import calendar

def add_months(date, months):
    months_count = date.month + months

    # Calculate the year
    year = date.year + int(months_count / 12)

    # Calculate the month
    month = (months_count % 12)
    if month == 0:
        month = 12

    # Calculate the day
    day = date.day
    last_day_of_month = calendar.monthrange(year, month)[1]
    if day > last_day_of_month:
        day = last_day_of_month

    new_date = datetime.date(year, month, day)
    return new_date

Тестирование:

>>>date = datetime.date(2018, 11, 30)

>>>print(date, add_months(date, 3))
(datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))

>>>print(date, add_months(date, 14))
(datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))

Ответ 14

У меня есть лучший способ решить проблему "31-го сентября":

def add_months(start_date, months):
    import calendar

    year = start_date.year + (months / 12)
    month = start_date.month + (months % 12)
    day = start_date.day

    if month > 12:
        month = month % 12
        year = year + 1

    days_next = calendar.monthrange(year, month)[1]
    if day > days_next:
        day = days_next

    return start_date.replace(year, month, day)

Я думаю, что он также работает с отрицательными числами (чтобы вычесть месяцы), но я не очень это испытал.

Ответ 15

Класс QDate PyQt4 имеет функцию addmonths.

>>>from PyQt4.QtCore import QDate  
>>>dt = QDate(2009,12,31)  
>>>required = dt.addMonths(6) 

>>>required
PyQt4.QtCore.QDate(2010, 6, 30)

>>>required.toPyDate()
datetime.date(2010, 6, 30)

Ответ 16

Изменен AddMonths() для использования в Zope и обработки недопустимых чисел дня:

def AddMonths(d,x):
    days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    newmonth = ((( d.month() - 1) + x ) % 12 ) + 1
    newyear  = d.year() + ((( d.month() - 1) + x ) // 12 ) 
    if d.day() > days_of_month[newmonth-1]:
      newday = days_of_month[newmonth-1]
    else:
      newday = d.day() 
    return DateTime( newyear, newmonth, newday)

Ответ 17

import time

def add_month(start_time, months):  

        ret = time.strptime(start_time, '%Y-%m-%d')
        t = list(ret)

        t[1] += months

        if t[1] > 12:
            t[0] += 1 + int(months / 12)

            t[1] %= 12

        return int(time.mktime(tuple(t)))

Ответ 18

Как насчет этого? Не использовать другую библиотеку (dateutil) или timedelta? на vartec Ответ Я сделал это, и я считаю, что он работает:

import datetime

today = datetime.date.today()
six_months_from_today = datetime.date(today.year + (today.month + 6)/12, (today.month + 6) % 12, today.day)

Я попытался использовать timedelta, но поскольку он подсчитывает дни, 365/2 или 6*356/12 не всегда переводится на 6 месяцев, а на 182 дня. например.

day = datetime.date(2015, 3, 10)
print day
>>> 2015-03-10

print (day + datetime.timedelta(6*365/12))
>>> 2015-09-08

Я считаю, что мы обычно предполагаем, что 6 месяцев с определенного дня приземлится в тот же день месяца, но через 6 месяцев (т.е. 2015-03-102015-09-10, Not 2015-09-08)

Надеюсь, вы сочтете это полезным.

Ответ 19

Модифицированный ответ Йоханнеса Вэй в случае 1new_month = 121. Это отлично работает для меня. Месяцы могут быть положительными или отрицательными.

def addMonth(d,months=1):
    year, month, day = d.timetuple()[:3]
    new_month = month + months
    return datetime.date(year + ((new_month-1) / 12), (new_month-1) % 12 +1, day)

Ответ 20

Я решил эту проблему следующим образом:

import calendar
from datetime import datetime
moths2add = 6
now = datetime.now()
current_year = now.year
current_month = now.month
#count days in months you want to add using calendar module
days = sum(
  [calendar.monthrange(current_year, elem)[1] for elem in range(current_month, current_month + moths)]
    )
print now + days

Ответ 21

import datetime


'''
Created on 2011-03-09

@author: tonydiep
'''

def add_business_months(start_date, months_to_add):
    """
    Add months in the way business people think of months. 
    Jan 31, 2011 + 1 month = Feb 28, 2011 to business people
    Method: Add the number of months, roll back the date until it becomes a valid date
    """
    # determine year
    years_change = months_to_add / 12

    # determine if there is carryover from adding months
    if (start_date.month + (months_to_add % 12) > 12 ):
        years_change = years_change + 1

    new_year = start_date.year + years_change

    # determine month
    work = months_to_add % 12
    if 0 == work:
        new_month = start_date.month
    else:
        new_month = (start_date.month + (work % 12)) % 12

    if 0 == new_month:
        new_month = 12 

    # determine day of the month
    new_day = start_date.day
    if(new_day in [31, 30, 29, 28]):
        #user means end of the month
        new_day = 31


    new_date = None
    while (None == new_date and 27 < new_day):
        try:
            new_date = start_date.replace(year=new_year, month=new_month, day=new_day)
        except:
            new_day = new_day - 1   #wind down until we get to a valid date

    return new_date


if __name__ == '__main__':
    #tests
    dates = [datetime.date(2011, 1, 31),
             datetime.date(2011, 2, 28),
             datetime.date(2011, 3, 28),
             datetime.date(2011, 4, 28),
             datetime.date(2011, 5, 28),
             datetime.date(2011, 6, 28),
             datetime.date(2011, 7, 28),
             datetime.date(2011, 8, 28),
             datetime.date(2011, 9, 28),
             datetime.date(2011, 10, 28),
             datetime.date(2011, 11, 28),
             datetime.date(2011, 12, 28),
             ]
    months = range(1, 24)
    for start_date in dates:
        for m in months:
            end_date = add_business_months(start_date, m)
            print("%s\t%s\t%s" %(start_date, end_date, m))

Ответ 22

Еще одно решение - надеюсь, кому-то это понравится:

def add_months(d, months):
    return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12)

Это решение не работает в течение дней 29,30,31 для всех случаев, поэтому требуется более надежное решение (что уже не так приятно:)):

def add_months(d, months):
    for i in range(4):
        day = d.day - i
        try:
            return d.replace(day=day).replace(year=d.year+int(months)//12).replace(month=(d.month+int(months))%12)
        except:
            pass
    raise Exception("should not happen")

Ответ 23

От этот ответ, см. parsedatetime. Пример кода. Подробнее: unit test со многими примерами преобразования на естественном языке → YYYY-MM-DD и очевидным проблемы преобразования/ошибки преобразования > .

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, calendar
from datetime import date

# from https://github.com/bear/parsedatetime
import parsedatetime as pdt

def print_todays_date():
    todays_day_of_week = calendar.day_name[date.today().weekday()]
    print "today date = " + todays_day_of_week + ', ' + \
                              time.strftime('%Y-%m-%d')

def convert_date(natural_language_date):
    cal = pdt.Calendar()
    (struct_time_date, success) = cal.parse(natural_language_date)
    if success:
        formal_date = time.strftime('%Y-%m-%d', struct_time_date)
    else:
        formal_date = '(conversion failed)'
    print '{0:12s} -> {1:10s}'.format(natural_language_date, formal_date)

print_todays_date()
convert_date('6 months')

Приведенный выше код генерирует следующее из машины MacOSX:

$ ./parsedatetime_simple.py 
today date = Wednesday, 2015-05-13
6 months     -> 2015-11-13
$ 

Ответ 24

Вот пример, который позволяет пользователю решить, как вернуть дату, когда день больше, чем количество дней в месяце.

def add_months(date, months, endOfMonthBehaviour='RoundUp'):
    assert endOfMonthBehaviour in ['RoundDown', 'RoundIn', 'RoundOut', 'RoundUp'], \
        'Unknown end of month behaviour'
    year = date.year + (date.month + months - 1) / 12
    month = (date.month + months - 1) % 12 + 1
    day = date.day
    last = monthrange(year, month)[1]
    if day > last:
        if endOfMonthBehaviour == 'RoundDown' or \
            endOfMonthBehaviour == 'RoundOut' and months < 0 or \
            endOfMonthBehaviour == 'RoundIn' and months > 0:
            day = last
        elif endOfMonthBehaviour == 'RoundUp' or \
            endOfMonthBehaviour == 'RoundOut' and months > 0 or \
            endOfMonthBehaviour == 'RoundIn' and months < 0:
            # we don't need to worry about incrementing the year
            # because there will never be a day in December > 31
            month += 1
            day = 1
    return datetime.date(year, month, day)


>>> from calendar import monthrange
>>> import datetime
>>> add_months(datetime.datetime(2016, 1, 31), 1)
datetime.date(2016, 3, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2)
datetime.date(2015, 12, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2, 'RoundDown')
datetime.date(2015, 11, 30)

Ответ 25

учитывая, что ваша переменная datetime называется date:

date=datetime.datetime(year=date.year+int((date.month+6)/12),
                       month=(date.month+6)%13 + (1 if (date.month + 
                       months>12) else 0), day=date.day)

Ответ 26

Общая функция для получения следующей даты после/до х месяцев.

from datetime import date

def after_month(given_date, month):
    yyyy = int(((given_date.year * 12 + given_date.month) + month)/12)
    mm = int(((given_date.year * 12 + given_date.month) + month)%12)

    if mm == 0:
        yyyy -= 1
        mm = 12
    return given_date.replace(year=yyyy, month=mm)


if __name__ == "__main__":
    today = date.today()
    print(today)

    for mm in [-12, -1, 0, 1, 2, 12, 20 ]:
        next_date = after_month(today, mm)
        print(next_date)

Ответ 27

Используйте модуль datetime для python, чтобы добавить timedelta из шести месяцев в datetime.today().

http://docs.python.org/library/datetime.html

Вам, конечно, придется решить вопрос, поднятый Йоханнесом Вейсом - что вы подразумеваете под 6 месяцев?

Ответ 28

Вот что я придумал. Он перемещает правильное количество месяцев и лет, но игнорирует дни (это было то, что мне нужно в моей ситуации).

import datetime

month_dt = 4
today = datetime.date.today()
y,m = today.year, today.month
m += month_dt-1
year_dt = m//12
new_month = m%12
new_date = datetime.date(y+year_dt, new_month+1, 1)

Ответ 29

Я использую эту функцию для изменения года и месяца, но сохраняю день:

def replace_month_year(date1, year2, month2):
    try:
        date2 = date1.replace(month = month2, year = year2)
    except:
        date2 = datetime.date(year2, month2 + 1, 1) - datetime.timedelta(days=1)
    return date2

Вы должны написать:

new_year = my_date.year + (my_date.month + 6) / 12
new_month = (my_date.month + 6) % 12
new_date = replace_month_year(my_date, new_year, new_month)

Ответ 30

Я думаю, было бы безопаснее делать что-то вроде этого вместо того, чтобы вручную добавлять дни:

import datetime
today = datetime.date.today()

def addMonths(dt, months = 0):
    new_month = months + dt.month
    year_inc = 0
    if new_month>12:
        year_inc +=1
        new_month -=12
    return dt.replace(month = new_month, year = dt.year+year_inc)

newdate = addMonths(today, 6)