Làm thế nào để tính số ngày giữa hai ngày nhất định?


507

Nếu tôi có hai ngày (ví dụ '8/18/2008''9/26/2008'), cách tốt nhất để có được số ngày giữa hai ngày này là gì?

Câu trả lời:


801

Nếu bạn có hai đối tượng ngày, bạn chỉ có thể trừ chúng, tính toán một timedeltađối tượng.

from datetime import date

d0 = date(2008, 8, 18)
d1 = date(2008, 9, 26)
delta = d1 - d0
print(delta.days)

Phần có liên quan của các tài liệu: https://docs.python.org/l Library / datetime.html .

Xem câu trả lời này cho một ví dụ khác.


2
Câu trả lời tuyệt vời ở đây. Vì nhiều người có thể đang sử dụng khung dữ liệu của gấu trúc, nên có thể hữu ích để kiểm tra liên kết về cách chuyển đổi từ np.datetime64sang python datetime stackoverflow.com/questions/52982056/
Lỗi

Điều tốt đẹp là giải pháp này cũng trả về delta chính xác trong những năm nhuận.
Lasma

154

Sử dụng sức mạnh của datetime:

from datetime import datetime
date_format = "%m/%d/%Y"
a = datetime.strptime('8/18/2008', date_format)
b = datetime.strptime('9/26/2008', date_format)
delta = b - a
print delta.days # that's it

4
thực tế, lớp ngày sẽ thích hợp hơn trong trường hợp này hơn datetime.
Jeremy Cantrell

10
@JeremyCantrell Tuy nhiên, thậm chí tám năm sau, datevẫn thiếu tương đương với chính nó strptime().
JAB

Tại sao cần strptimecác formatarg? Nên rõ ràng với ngày arg đầu tiên có định dạng.
Timo

36

Ngày cho đến Giáng sinh:

>>> import datetime
>>> today = datetime.date.today()
>>> someday = datetime.date(2008, 12, 25)
>>> diff = someday - today
>>> diff.days
86

Số học nhiều hơn ở đây .


16

Bạn muốn mô-đun datetime.

>>> from datetime import datetime, timedelta 
>>> datetime(2008,08,18) - datetime(2008,09,26) 
datetime.timedelta(4) 

Một vi dụ khac:

>>> import datetime 
>>> today = datetime.date.today() 
>>> print(today)
2008-09-01 
>>> last_year = datetime.date(2007, 9, 1) 
>>> print(today - last_year)
366 days, 0:00:00 

Như đã chỉ ra ở đây


1
Làm thế nào để tôi có được điều này mà không có phần 0:00:00?
Vicki B

@VickiBdelta = today - last_year print(delta.days)
dbakiu

8
from datetime import datetime
start_date = datetime.strptime('8/18/2008', "%m/%d/%Y")
end_date = datetime.strptime('9/26/2008', "%m/%d/%Y")
print abs((end_date-start_date).days)

2
Điều này không có gì mới so với câu trả lời được đưa ra 4 năm trước đó. -1.
Đánh dấu Amery

+1 cho việc sử dụng abs(), rất hữu ích khi chưa biết ngày so sánh trước và đó là sự khác biệt mà bạn quan tâm. Nếu ngày thứ hai của bạn datetime.strptime(date, date)muộn hơn ngày đầu tiên, kết quả sẽ âm. abs()làm cho tất cả đầu vào tuyệt đối (tức là tích cực).
veuncent


6

không sử dụng Lib chỉ là mã thuần túy:

#Calculate the Days between Two Date

daysOfMonths = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def isLeapYear(year):

    # Pseudo code for this algorithm is found at
    # http://en.wikipedia.org/wiki/Leap_year#Algorithm
    ## if (year is not divisible by 4) then (it is a common Year)
    #else if (year is not divisable by 100) then (ut us a leap year)
    #else if (year is not disible by 400) then (it is a common year)
    #else(it is aleap year)
    return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0

def Count_Days(year1, month1, day1):
    if month1 ==2:
        if isLeapYear(year1):
            if day1 < daysOfMonths[month1-1]+1:
                return year1, month1, day1+1
            else:
                if month1 ==12:
                    return year1+1,1,1
                else:
                    return year1, month1 +1 , 1
        else: 
            if day1 < daysOfMonths[month1-1]:
                return year1, month1, day1+1
            else:
                if month1 ==12:
                    return year1+1,1,1
                else:
                    return year1, month1 +1 , 1
    else:
        if day1 < daysOfMonths[month1-1]:
             return year1, month1, day1+1
        else:
            if month1 ==12:
                return year1+1,1,1
            else:
                    return year1, month1 +1 , 1


def daysBetweenDates(y1, m1, d1, y2, m2, d2,end_day):

    if y1 > y2:
        m1,m2 = m2,m1
        y1,y2 = y2,y1
        d1,d2 = d2,d1
    days=0
    while(not(m1==m2 and y1==y2 and d1==d2)):
        y1,m1,d1 = Count_Days(y1,m1,d1)
        days+=1
    if end_day:
        days+=1
    return days


# Test Case

def test():
    test_cases = [((2012,1,1,2012,2,28,False), 58), 
                  ((2012,1,1,2012,3,1,False), 60),
                  ((2011,6,30,2012,6,30,False), 366),
                  ((2011,1,1,2012,8,8,False), 585 ),
                  ((1994,5,15,2019,8,31,False), 9239),
                  ((1999,3,24,2018,2,4,False), 6892),
                  ((1999,6,24,2018,8,4,False),6981),
                  ((1995,5,24,2018,12,15,False),8606),
                  ((1994,8,24,2019,12,15,True),9245),
                  ((2019,12,15,1994,8,24,True),9245),
                  ((2019,5,15,1994,10,24,True),8970),
                  ((1994,11,24,2019,8,15,True),9031)]

    for (args, answer) in test_cases:
        result = daysBetweenDates(*args)
        if result != answer:
            print "Test with data:", args, "failed"
        else:
            print "Test case passed!"

test()

3

mọi người đã trả lời một cách xuất sắc bằng cách sử dụng ngày, hãy để tôi thử trả lời bằng cách sử dụng gấu trúc

dt = pd.to_datetime('2008/08/18', format='%Y/%m/%d')
dt1 = pd.to_datetime('2008/09/26', format='%Y/%m/%d')

(dt1-dt).days

Điều này sẽ đưa ra câu trả lời. Trong trường hợp một trong những đầu vào là cột dataframe. chỉ cần sử dụng dt.days thay cho ngày

(dt1-dt).dt.days

2

Ngoài ra còn có một datetime.toordinal()phương pháp chưa được đề cập:

import datetime
print(datetime.date(2008,9,26).toordinal() - datetime.date(2008,8,18).toordinal())  # 39

https://docs.python.org/3/lvern/datetime.html#datetime.date.toordinal

date.toordinal ()

Trả lại thứ tự Gregorian proleptic của ngày, trong đó ngày 1 tháng 1 năm 1 có thứ tự 1. Đối với bất kỳ dateđối tượng d , date.fromordinal(d.toordinal()) == d.

Có vẻ rất phù hợp để tính chênh lệch ngày, mặc dù không thể đọc được timedelta.days.


1
Có những trường hợp phương pháp này chiến thắng. Ví dụ: sự khác biệt thực tế giữa 2019-07-09 23:50 và 2019-07-10 00:10 là hai mươi phút. (d1 - d0).daystrả lại 0, d1.toordinal() - d0.toordinal()trả lại 1. Phụ thuộc vào những gì bạn cần trong usecase thực tế của bạn.
peter.slizik

Cách tiếp cận này thực sự có thể so sánh datetime và ngày. Ví dụ: để kiểm tra xem 2020-04-17 == 2020-04017 00:00:00
Harry Duong

2

Để tính ngày và giờ, có một số tùy chọn nhưng tôi sẽ viết theo cách đơn giản:

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

# current time
date_and_time = datetime.datetime.now()
date_only = date.today()
time_only = datetime.datetime.now().time()

# calculate date and time
result = date_and_time - datetime.timedelta(hours=26, minutes=25, seconds=10)

# calculate dates: years (-/+)
result = date_only - dateutil.relativedelta.relativedelta(years=10)

# months
result = date_only - dateutil.relativedelta.relativedelta(months=10)

# days
result = date_only - dateutil.relativedelta.relativedelta(days=10)

# calculate time 
result = date_and_time - datetime.timedelta(hours=26, minutes=25, seconds=10)
result.time()

Hy vọng nó giúp


1

from datetime import date
def d(s):
  [month, day, year] = map(int, s.split('/'))
  return date(year, month, day)
def days(start, end):
  return (d(end) - d(start)).days
print days('8/18/2008', '9/26/2008')

Tất nhiên, điều này giả định rằng bạn đã xác minh rằng ngày của bạn ở định dạng r'\d+/\d+/\d+'.


1
Điều này không có gì mới so với câu trả lời 8 năm trước. -1.
Mark Amery

1
Sự khác biệt chính là hầu hết các câu trả lời khác thậm chí không bận tâm đến việc OP có ngày tháng của mình dưới dạng chuỗi. Và những người đã giải thích cho điều đó phần lớn sử dụng các trình định dạng phức tạp hơn là rất cần thiết. Vì vậy, sự khác biệt chính là map(int, s.split('/')). Không chính xác đột phá, nhưng một lần nữa câu hỏi này là khá cơ bản ngu ngốc. Câu trả lời của tôi chỉ cho thấy một cách khác để da mèo.
Bắn Parthian

Cũng đề cập đến việc xác nhận rằng ngày tháng có định dạng chính xác và đưa ra biểu thức xác thực xấp xỉ đầu tiên. Mà những người khác đã không.
Bắn Parthian

1

Dưới đây là ba cách để giải quyết vấn đề này:

from datetime import datetime

Now = datetime.now()
StartDate = datetime.strptime(str(Now.year) +'-01-01', '%Y-%m-%d')
NumberOfDays = (Now - StartDate)

print(NumberOfDays.days)                     # Starts at 0
print(datetime.now().timetuple().tm_yday)    # Starts at 1
print(Now.strftime('%j'))                    # Starts at 1
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.