Bagaimana cara menghitung jumlah hari antara dua tanggal yang diberikan?


507

Jika saya memiliki dua tanggal (mis. '8/18/2008'Dan '9/26/2008'), apa cara terbaik untuk mendapatkan jumlah hari antara dua tanggal ini?

Jawaban:


801

Jika Anda memiliki dua objek tanggal, Anda bisa menguranginya, yang menghitung timedeltaobjek.

from datetime import date

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

Bagian yang relevan dari dokumen ini: https://docs.python.org/library/datetime.html .

Lihat jawaban ini untuk contoh lain.


2
Jawaban yang bagus di sini. Karena banyak orang mungkin menggunakan bingkai data panda, pemikiran mungkin berguna untuk memeriksa tautan tentang cara mengkonversi dari np.datetime64ke python datetime stackoverflow.com/questions/52982056/…
Pramit

Yang menyenangkan adalah bahwa solusi ini juga mengembalikan delta yang benar untuk tahun kabisat.
Lasma

154

Menggunakan kekuatan 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
sebenarnya, kelas tanggal akan lebih tepat dalam hal ini daripada datetime.
Jeremy Cantrell

11
@ JeremyCantrell Namun, bahkan delapan tahun kemudian, datemasih kurang setara dengan strptime().
JAB

Mengapa perlu strptimeyang formatarg? Harus jelas dengan tanggal arg pertama yang memiliki format.
Timo

36

Hari sampai Natal:

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

Lebih banyak aritmatika di sini .


16

Anda ingin modul datetime.

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

Contoh lain:

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

Seperti yang ditunjukkan di sini


1
Bagaimana saya mendapatkan ini tanpa bagian 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
Ini menambahkan tidak ada yang baru dibandingkan dengan jawaban yang diberikan 4 tahun sebelumnya. -1.
Mark Amery

+1 untuk penggunaan abs(), yang berguna ketika tanggal yang dibandingkan tidak diketahui sebelumnya dan itu adalah perbedaan yang Anda minati. Jika kencan kedua Anda datetime.strptime(date, date)lebih lambat dari tanggal pertama, hasilnya akan negatif. abs()membuat semua input mutlak (mis. positif).
Berlaku


6

tanpa menggunakan Lib hanya kode murni:

#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

semua orang telah menjawab dengan sangat baik menggunakan tanggal, izinkan saya mencoba untuk menjawabnya menggunakan panda

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

Ini akan memberikan jawabannya. Dalam hal salah satu input adalah kolom dataframe. cukup gunakan dt.days sebagai ganti hari

(dt1-dt).dt.days

2

Ada juga datetime.toordinal()metode yang belum disebutkan:

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

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

date.toordinal ()

Kembalikan ordinal Gregorian proleptic dari tanggal, di mana tanggal 1 Januari tahun 1 memiliki 1. ordinal Untuk setiap dateobjek d , date.fromordinal(d.toordinal()) == d.

Tampaknya cocok untuk menghitung perbedaan hari, meskipun tidak dapat dibaca timedelta.days.


1
Ada beberapa kasus di mana pendekatan ini menang. Misalnya, perbedaan aktual antara 2019-07-09 23:50 dan 2019-07-10 00:10 adalah dua puluh menit. (d1 - d0).dayskembali 0, d1.toordinal() - d0.toordinal()kembali 1. Bergantung pada apa yang Anda butuhkan di usecase Anda yang sebenarnya.
peter.slizik

pendekatan ini sebenarnya dapat membandingkan waktu dan tanggal. Misalnya untuk memeriksa apakah 2020-04-17 == 2020-04017 00:00:00
Harry Duong

2

Untuk menghitung tanggal dan waktu, ada beberapa opsi tetapi saya akan menulis dengan cara sederhana:

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

Semoga ini bisa membantu


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

Ini mengasumsikan, tentu saja, bahwa Anda telah memverifikasi bahwa tanggal Anda dalam format r'\d+/\d+/\d+'.


1
Ini menambahkan tidak ada yang baru dibandingkan dengan jawaban yang diberikan 8 tahun sebelumnya. -1.
Mark Amery

1
Perbedaan utama adalah sebagian besar jawaban lain bahkan tidak repot-repot memperhitungkan fakta bahwa OP memiliki tanggal sebagai string. Dan mereka yang bertanggung jawab untuk itu sebagian besar menggunakan formatters yang lebih rumit daripada yang diperlukan. Jadi, perbedaan utamanya adalah map(int, s.split('/')). Tidak persis terobosan, tapi sekali lagi pertanyaan ini adalah dasar yang sangat bodoh. Jawaban saya hanya menunjukkan cara lain untuk menguliti kucing.
Parthian Shot

Disebutkan juga memvalidasi bahwa tanggal berada dalam format yang benar, dan memberikan regex validasi aproksimasi pertama. Yang lain tidak.
Parthian Shot

1

Berikut adalah tiga cara untuk mengatasi masalah ini:

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.