Làm cách nào để tính ngày sáu tháng kể từ ngày hiện tại bằng mô-đun Python thời gian?


391

Tôi đang sử dụng mô-đun Python datetime. Tôi đang tìm cách tính ngày 6 tháng kể từ ngày hiện tại. Ai đó có thể giúp tôi một chút giúp làm điều này?

Lý do tôi muốn tạo một ngày 6 tháng kể từ ngày hiện tại là để tạo ra một ngày xem xét . Nếu người dùng nhập dữ liệu vào hệ thống, nó sẽ có ngày xem xét là 6 tháng kể từ ngày họ nhập dữ liệu.


2
Bạn sẽ phải cụ thể hơn: khi nào là sáu tháng kể từ ngày 31 tháng 3? Và từ tháng 30?
kmkaplan

3
Có, chỉnh sửa giúp: điều đó có nghĩa là bạn có thể bỏ qua 6 tháng đến 183 ngày mà không có hiệu ứng xấu. Vì vậy, thêm 183 ngày cho đến hôm nay sẽ thực hiện các mẹo.
kmkaplan

15
Các ý kiến ​​trên đánh tôi là ngớ ngẩn. Khái niệm "thêm sáu tháng" khá rõ ràng - lấy thành phần tháng và thêm 6vào đó, với sự hỗ trợ để lăn qua năm (và đạp xe trong tháng trở lại 1) nếu chúng ta đi qua tháng 12. Điều này xảy ra chính xác là những gì relativedeltavà thực tế là những gì mọi ngôn ngữ lập trình hỗ trợ cho loại khái niệm này làm.
Kirk Woll

5
@KirkWoll: Tôi chắc chắn nó khá rõ ràng. Nhưng vẫn khác nhau cho bất cứ ai nói. Python: date(2015, 3, 31) + relativedelta(months = 6)cho datetime.date(2015, 9, 30). Perl: DateTime->new(year=>2000, month=>3, day=>31)->add(months=>6)cho 2000-10-01T00:00:00. Php: date_create('2000-03-31', new DateTimeZone('UTC'))->add(new DateInterval('P6M'))cho 2000-10-01. Chọn thuốc độc của bạn.
kmkaplan 10/2/2015

2
... Thêm 182 có vẻ thực dụng hơn để tạo ngày đánh giá : nó giữ nguyên ngày trong tuần.
Sói

Câu trả lời:


1047

Tôi thấy giải pháp này là tốt. (Điều này sử dụng phần mở rộng python-dateutil )

from datetime import date
from dateutil.relativedelta import relativedelta

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

Ưu điểm của phương pháp này là nó xử lý các vấn đề với 28, 30, 31 ngày, v.v ... Điều này trở nên rất hữu ích trong việc xử lý các quy tắc và kịch bản kinh doanh (giả sử tạo hóa đơn, v.v.)

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

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

2
các 6 là một chỉ báo rằng nó có thể là -6, điều tương tự áp dụng cho ngày và năm cũng :)
securecurve

5
@sliders_alpha Bạn cần phải cài đặt gói python-dateutil (pip cài đặt python-dateutil)
poiuytrez

18
Đây là giải pháp chính xác. Nếu OP đã yêu cầu 6 năm thay vì 6 tháng, thì câu trả lời được phê duyệt sẽ thất bại thảm hại. Vì vậy, người ta nên nhớ rằng các câu trả lời càng có giá trị thì càng khái quát.
Daniel F

3
Vui lòng lưu ý rằng relativedeltahàm cũng lấy monthlàm đối số, về cơ bản thay thế / bộ / sửa lỗi tháng trong ngày đã qua, rất khác so với việc thêm nhiều tháng. Chỉ là một lời cảnh báo cho mọi người tự hỏi nếu chức năng bị hỏng vì họ quên mất thêm s trong tháng .
shad0w_wa1k3r

1
Tôi tò mò: có ai biết tại sao điều này không được bao gồm theo mặc định không? Timedelta dường như được đóng gói datetimetheo mặc định. Tôi thực sự cho rằng tôi có thể vượt qua "tháng" vào timedelta.
dTanMan

51

Chà, điều đó phụ thuộc vào ý nghĩa của bạn trong 6 tháng kể từ ngày hiện tại.

  1. Sử dụng tháng tự nhiên:

    (day, month, year) = (day, (month + 5) % 12 + 1, year + (month + 5)/12)
  2. Sử dụng định nghĩa của ngân hàng, 6 * 30:

    date += datetime.timedelta(6 * 30)

3
Bạn có thể đưa ra định nghĩa nửa năm (183 ngày) cộng với định nghĩa 26 tuần không? Nó giúp có tất cả chúng ở một nơi.
S.Lott

11
chỉ là một nhận xét nhanh: Tôi nghĩ, trong tháng, công thức sẽ thay thế (tháng + 5)% 12 + 1 b / c cho tháng sáu, công thức của bạn cho 0 trong khi kết quả dự kiến ​​là 12 ... mặc dù có lỗi nhỏ này, tâm trí của tôi, câu trả lời của bạn là câu trả lời tốt nhất cho câu hỏi
PierrOz

3
và tương tự cho năm: phải là năm + (tháng + 5) / 12
PierrOz

7
Điều gì xảy ra nếu ngày là 31 và tháng sáu tháng sau không thể có 31 ngày (đó là trường hợp của hầu hết các tháng có 31 ngày)?
akv

4
Downvote vì giải pháp đầu tiên (day, month, year) = (day, (month+6)%12, year+(month+6)/12)có thể có lỗi, vì nó tạo ra các ngày không hợp lệ, chẳng hạn như (31, 8, 2015)->(31, 2, 2016)
ohw

37

Với Python 3.x bạn có thể làm như thế này:

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

nhưng bạn sẽ cần cài đặt mô-đun python-dateutil :

pip install python-dateutil

Được ủng hộpip install ...
Nathan

Tôi muốn giới thiệu from dateutil.relativedelta import relativedelta. Sử dụng import *không rõ ràng.
Sam Morgan

19

Để tính đầu tháng đến tháng:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

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

18
Đây không phải là giải pháp tương đối được đề cập ở trên trong các ý kiến. Tiếp tục cuộn tìm giải pháp với hơn 600 lượt upvote.
Nỗi nhớ.io

15

"6 tháng" nghĩa là gì?

Là 2009/02/13 + 6 tháng == 2009-08-13? Hay là 2009/02/13 + 6 * 30 ngày?

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'

Thông tin thêm về mx.DateTime


14

Vì vậy, đây là một ví dụ về dateutil.relativedeltađiều mà tôi thấy hữu ích cho việc lặp lại trong năm qua, bỏ qua một tháng mỗi lần cho đến ngày hiện tại:

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

Cũng như các câu trả lời khác, bạn phải tìm ra ý nghĩa thực sự của bạn trong "6 tháng kể từ bây giờ". Nếu bạn có nghĩa là "ngày hôm nay của tháng trong tháng sáu năm trong tương lai" thì điều này sẽ làm:

datetime.datetime.now() + relativedelta(months=6)

14

Giải pháp này hoạt động chính xác cho tháng 12, mà hầu hết các câu trả lời trên trang này không có. Trước tiên, bạn cần chuyển các tháng từ cơ sở 1 (tức là tháng 1 = 1) sang cơ sở 0 (tức là tháng 1 = 0) trước khi sử dụng mô đun (%) hoặc phân chia số nguyên (//), nếu không thì tháng 11 (11) cộng với 1 tháng mang lại cho bạn 12 , khi tìm phần còn lại (12% 12) cho 0.

(Và không đề xuất "(tháng% 12) + 1" hoặc tháng 10 + 1 = tháng 12!)

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

Tuy nhiên ... Điều này không giải thích cho vấn đề như ngày 31 tháng 1 + một tháng. Vì vậy, chúng tôi quay trở lại OP - bạn có ý nghĩa gì khi thêm một tháng? Một giải pháp là quay lại cho đến khi bạn đến một ngày hợp lệ, với điều kiện là hầu hết mọi người sẽ đoán ngày cuối cùng của tháng một, cộng với một tháng, bằng với ngày cuối cùng của tháng Hai. Điều này cũng sẽ hoạt động với số tháng âm. Bằng chứng:

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

3
Khắc phục sự cố "ngày 31 tháng 1 + một tháng": days_in_month = calendar.monthrange (newyear, newmonth) [1]; ngày mới = phút (d.day, days_in_month); (giảm số ngày xuống nếu quá lớn, ví dụ: ngày 31 tháng 2 đến ngày 28 tháng 2)
Curtis Yallop

Điều này chỉ hiệu quả với tôi bằng cách chuyển đổi newyear thành kiểu dữ liệu số nguyên def AddMonths (d, x): newmonth = (((d.month - 1) + x)% 12) + 1 newyear = d.year + int ( (d.month - 1) + x) / 12) return datetime.date (newyear, newmonth, d.day)
Manmeet Singh

12

Tôi biết điều này đã được 6 tháng, tuy nhiên câu trả lời hiển thị trên google về "thêm tháng trong python" nếu bạn thêm một tháng:

import calendar

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

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

điều này sẽ tính các ngày trong tháng hiện tại và thêm chúng vào ngày hiện tại, sử dụng 365/12 sẽ quảng cáo 1/12 của một năm có thể gây ra sự cố cho các tháng ngắn / dài nếu lặp đi lặp lại theo ngày.


11

Không có cách nào trực tiếp để làm điều đó với datetime của Python.

Kiểm tra loại relativingelta tại python-dateutil . Nó cho phép bạn chỉ định một đồng bằng thời gian trong tháng.


10

Chỉ cần sử dụng timetuple phương pháp để trích xuất các tháng, thêm tháng của bạn và xây dựng một dateobject mới. Nếu có một phương thức đã có sẵn cho điều này thì tôi không biết.

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 hơi vụng về, nhưng hoạt động như một ví dụ. Rõ ràng cũng sẽ không hoạt động trên các trường hợp góc như 2008-01-31 + 1 tháng. :)


3
Lỗi trong mã của bạn: new_month % 12nên được (new_month % 12) or 12. Nếu không, nếu bạn thử điều này vào tháng 11, bạn sẽ gặp lỗi. :)
Jordan Reiter

Điều này thực sự sạch hơn nhiều so với giải pháp được chấp nhận. Điều này không yêu cầu bất kỳ nhập mới, chỉ là toán cơ bản
Simon PA

trả lại datetime.date (năm + (new_month / / 12), (new_month% 12) hoặc 12, ngày)
paytam

9

Gói Dateutil đã thực hiện các chức năng như vậy. Nhưng hãy lưu ý rằng điều này sẽ là ngây thơ , như những người khác đã chỉ ra.


dateutil là tuyệt vời. Nó cũng có thể được cài đặt với easy_install.
Soviut

Thông minh. Cảm ơn đã gợi ý rằng. Đó dường như là một vị thần được gửi đến.
ayaz

9

Sử dụng các thư viện chuẩn của Python, tức là không có dateutilhoặc các thư viện khác và giải quyết vấn đề 'ngày 31 tháng 2':

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

Kiểm tra:

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

Điều này có một lỗi: Nếu tháng mục tiêu là tháng 12, nó sẽ trả lại một ngày muộn hơn một năm so với cần thiết. Ví dụ: add_months(datetime.date(2018, 11, 30), 1)lợi nhuận datetime.date(2019, 12, 30)(năm nên là 2018, không phải 2019). Vì vậy, tốt hơn nên sử dụng một thư viện chuyên dụng, được thử nghiệm tốt cho việc này! Nếu bạn thực sự chỉ cần sử dụng các mô-đun thư viện tiêu chuẩn, hãy xem câu trả lời của tôi cho một câu hỏi tương tự .
taleinat

5

Tôi có một cách tốt hơn để giải quyết vấn đề 'ngày 31 tháng 2':

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)

Tôi nghĩ rằng nó cũng hoạt động với các số âm (để trừ tháng), nhưng tôi đã không kiểm tra điều này rất nhiều.


1
Câu trả lời này có giá trị giải quyết chính xác vấn đề chỉ sử dụng các thư viện Python tích hợp. Kiểm tra stackoverflow.com/a/4131114/302264 để biết câu trả lời tương đương nhưng ngắn gọn hơn một chút.
Eduardo Dobay

3

Lớp QĐate của PyQt4 có chức năng 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)

3

Còn cái này thì sao? Không sử dụng thư viện khác ( dateutil) hoặc timedelta? dựa trên câu trả lời của vartec tôi đã làm điều này và tôi tin rằng nó hoạt động:

import datetime

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

Tôi đã thử sử dụng timedelta, nhưng vì nó đang đếm ngày, 365/2hoặc 6*356/12không phải lúc nào cũng dịch thành 6 tháng, mà là 182 ngày. ví dụ

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

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

Tôi tin rằng chúng ta thường cho rằng 6 tháng kể từ một ngày nhất định sẽ hạ cánh vào cùng một ngày trong tháng nhưng 6 tháng sau (tức là 2015-03-10-> 2015-09-10, Không phải 2015-09-08)

Tôi hy vọng bạn tìm thấy điều này hữu ích.


1
day + datetime.timedelta(6*365/12)sẽ không hoạt động luôn, vì một số năm có 365 ngày và những năm khác có 365 ngày.
3kstc

3

Điều này không trả lời câu hỏi cụ thể ( datetimechỉ sử dụng ) nhưng, do người khác đề xuất sử dụng các mô-đun khác nhau, ở đây có một giải pháp sử dụng pandas.

import datetime as dt
import pandas as pd

date = dt.date.today() - \
       pd.offsets.DateOffset(months=6)

print(date)

2019-05-04 00:00:00

Mà hoạt động như mong đợi trong năm nhuận

date = dt.datetime(2019,8,29) - \
       pd.offsets.DateOffset(months=6)
print(date)

2019-02-28 00:00:00

2

Đã sửa đổi AddMonths () để sử dụng trong Zope và xử lý số ngày không hợp lệ:

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)

Điều này dường như không xem xét năm nhuận (29 ngày trong feb).
xử lý

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

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

1

Sửa đổi câu trả lời của Julian Wei trong trường hợp 1new_month = 121. Điều này hoạt động hoàn hảo với tôi. Các tháng có thể là tích cực hoặc tiêu cực.

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)

2
Nó KHÔNG "hoạt động hoàn hảo" khi ngày trong ngày bắt đầu lớn hơn số ngày trong tháng mục tiêu. Ví dụ: 2001-01-31 cộng với một tháng cố gắng tạo ngày 2001 / 02-31.
John Machin

1

Một giải pháp khác - hy vọng ai đó sẽ thích nó:

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

Giải pháp này không hoạt động trong các ngày 29,30,31 cho tất cả các trường hợp, vì vậy cần có giải pháp mạnh mẽ hơn (không còn tốt nữa :)):

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

1

Từ câu trả lời này , xem Parsedatetime . Mã ví dụ sau. Thêm chi tiết: kiểm tra đơn vị với nhiều ngôn ngữ tự nhiên -> ví dụ chuyển đổi YYYY-MM-DD và các thách thức / lỗi chuyển đổi phân tích thời gian rõ ràng .

#!/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's 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')

Đoạn mã trên tạo ra các thông tin sau từ máy MacOSX:

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

1

Đây là một ví dụ cho phép người dùng quyết định cách trả về một ngày trong đó ngày lớn hơn số ngày trong tháng.

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)

1

cho rằng biến datetime của bạn được gọi là ngày:

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)

1

Chức năng chung để có được ngày tiếp theo sau / trước x tháng.

từ ngày nhập dữ liệu

def after_month (give_date, tháng):
    yyyy = int (((give_date.year * 12 + give_date.month) + tháng) / 12)
    mm = int (((give_date.year * 12 + give_date.month) + tháng)% 12)

    nếu mm == 0:
        yyyy - = 1
        mm = 12
    return give_date.replace (năm = yyyy, tháng = mm)


if __name__ == "__main__":
    hôm nay = date.today ()
    in (hôm nay)

    cho mm trong [-12, -1, 0, 1, 2, 12, 20]:
        next_date = after_month (hôm nay, mm)
        in (next_date)

Đây rõ ràng là câu trả lời tốt nhất. Đơn giản và hiệu quả, không có vấn đề làm tròn.
jprobichaud

1

Một gợi ý nhanh là Mũi tên

mũi tên cài đặt pip

>>> import arrow

>>> arrow.now().date()
datetime.date(2019, 6, 28)
>>> arrow.now().shift(months=6).date()
datetime.date(2019, 12, 28)

0

Sử dụng mô-đun datetime python để thêm thời gian sáu tháng vào datetime.today ().

http://docs.python.org/l Library / datetime.html

Bạn sẽ đương nhiên phải giải quyết vấn đề nêu ra bởi Johannes Weiß-- gì làm bạn có nghĩa là 6 tháng?


1
timedelta không hỗ trợ tháng và vì vậy bỏ qua các câu trả lời có thể cho câu hỏi "6 tháng có bao nhiêu ngày?" Mã của Eef sẽ đặt ngày đánh giá, vì vậy tôi sẽ đề nghị một người có thể xem xét việc đặt thời gian bằng cách sử dụng ngày (6 * 30). Nếu khoảng thời gian thể hiện quyền truy cập của khách hàng vào sản phẩm / dịch vụ thì định nghĩa kinh doanh có thể được yêu cầu / ưu tiên.
Carl

0

Đây là những gì tôi đã đưa ra. Nó di chuyển đúng số tháng và năm nhưng bỏ qua ngày (đó là những gì tôi cần trong tình huống của mình).

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)

0

Tôi sử dụng chức năng này để thay đổi năm và tháng nhưng giữ ngày:

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

Bạn nên viết:

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)

0

Tôi nghĩ sẽ an toàn hơn nếu làm điều gì đó như thế này thay vì thêm ngày thủ công:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.