2011-08-10 35 views
28

thể trùng lặp:
Best way to find the months between two dates (in python)Python: Sự khác biệt của 2 datetimes trong tháng

Tôi muốn biết làm thế nào tôi có thể có con số chính xác của tháng đối với sự khác biệt này:

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

ngày2-ngày1 kết quả trong

datetime.timedelta(183, 43200) 

Tôi muốn biết chính xác số lượng tháng, trong trường hợp này nó sẽ trả về và không 6 (vì giờ)

+0

Câu hỏi này đã được trả lời ở đây: http://stackoverflow.com/questions/4039879/best-way-to-find-the-months-giữa-hai-ngày-trong-python – Dan

+0

không cho datetime với giờ –

+1

Điều này sẽ dễ dàng hơn để trả lời khi bạn quyết định chính xác "số tháng chính xác" nghĩa là gì. Một tháng không phải là thời lượng cố định; nó có thể thay đổi từ 28 đến 31 ngày. Ngày 1 tháng 1 và ngày 1 tháng 2 cách xa nhau hơn ngày 1 tháng 2 và ngày 1 tháng 3; bạn có gọi cả hai khoảng "chính xác 1 tháng" không? –

Trả lời

22

Sử dụng mô-đun calendar để tìm hiểu số ngày mỗi tháng có, bạn chỉ cần đếm số tháng.

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 
5

Ưu điểm của làm nó theo cách này là có rất ít phụ thuộc mô-đun và không có vòng lặp - các tháng có thể được tìm thấy bằng cách tính toán thẳng.

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 
52

Bạn có thể sử dụng 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) 
+5

mặc dù: 'relativedelta.relativedelta (ngày (2015, 9, 30), ngày (2015, 10, 1)). Tháng sản lượng 0 là đúng nhưng có thể không phản ánh kết quả mong đợi nếu bạn muốn biết rằng các tháng là khác nhau – ezdazuzena

13

Chỉ có bạn mới biết các yêu cầu bạn phải đáp ứng, nhưng thực tế là có 183 ngày và 43200 SI giây giữa hai ngày này nêu bật một tính chủ quan cố hữu trong việc xác định có bao nhiêu tháng mà "thực sự" là.

Là tháng 30 ngày hoặc (365/12) ngày hoặc ((365 * 4 + 1)/48) ngày hoặc ...?

Có phải một ngày luôn luôn là 86400 giây hoặc bạn tính số giây nhảy vọt trong lịch sử hoặc bạn dự đoán giây nhảy vọt cho các ngày trong tương lai?

Những quyết định này ảnh hưởng đến câu trả lời thuật toán bạn mong muốn sẽ cung cấp cho bạn một số ngày đầu vào gần với các ranh giới này.

Theo tôi, đó là trực quan hơn để xem xét tháng như đơn vị nguyên tử của thời gian cho mục đích này và sử dụng công thức này: (date2.year - date1.year) * 12 + (date2.month - date1.month)

+0

Điều này là hiệu quả và cũng giải thích, làm việc cho vấn đề của tôi. –

Các vấn đề liên quan