Wie berechnet man die Anzahl der Tage zwischen zwei angegebenen Daten?


506

Wenn ich zwei Daten habe (z. B. '8/18/2008'und '9/26/2008'), wie kann ich die Anzahl der Tage zwischen diesen beiden Daten am besten ermitteln?

Antworten:


800

Wenn Sie zwei Datumsobjekte haben, können Sie diese einfach subtrahieren, wodurch ein timedeltaObjekt berechnet wird.

from datetime import date

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

Der relevante Abschnitt der Dokumente: https://docs.python.org/library/datetime.html .

In dieser Antwort finden Sie ein weiteres Beispiel.


2
Tolle Antworten hier. Da viele Leute möglicherweise Pandas Datenrahmen verwenden , könnte es nützlich sein, den Link zu überprüfen, wie von np.datetime64zu python datetime stackoverflow.com/questions/52982056/…
Pramit

Das Schöne ist, dass diese Lösung auch für Schaltjahre das richtige Delta zurückgibt.
Lasma

154

Mit der Kraft von 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
Tatsächlich wäre die Datumsklasse in diesem Fall geeigneter als datetime.
Jeremy Cantrell

10
@JeremyCantrell Und doch datefehlt auch acht Jahre später noch ein eigenes Äquivalent zu strptime().
JAB

Warum braucht strptimedas formatArgument? Sollte mit dem ersten Arg-Datum klar sein, das ein Format hat.
Timo

36

Tage bis Weihnachten:

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

Mehr Arithmetik hier .


16

Sie möchten das Datum / Uhrzeit-Modul.

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

Ein anderes Beispiel:

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

Wie hier ausgeführt


1
Wie bekomme ich das ohne den 0:00:00 Teil?
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
Dies fügt nichts Neues hinzu im Vergleich zu den Antworten, die 4 Jahre zuvor gegeben wurden. -1.
Mark Amery

+1 für die Verwendung von abs(), was nützlich ist, wenn die verglichenen Daten vorher unbekannt sind und es sich um den Unterschied handelt, an dem Sie interessiert sind. Wenn Ihr zweites Datum datetime.strptime(date, date)später als das erste Datum ist, ist das Ergebnis negativ. abs()macht alle Eingaben absolut (dh positiv).
veuncent


6

ohne Lib nur reinen Code:

#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

Jeder hat hervorragend mit dem Datum geantwortet. Lassen Sie mich versuchen, es mit Pandas zu beantworten

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

Dies wird die Antwort geben. Falls eine der Eingaben eine Datenrahmenspalte ist. Verwenden Sie einfach dt.days anstelle von Tagen

(dt1-dt).dt.days

2

Es gibt auch eine datetime.toordinal()Methode, die noch nicht erwähnt wurde:

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

Geben Sie die proleptische Gregorianische Ordnungszahl des Datums zurück, an dem der 1. Januar des Jahres 1 die Ordnungszahl 1 hat. Für jedes dateObjekt d , date.fromordinal(d.toordinal()) == d.

Scheint gut geeignet für die Berechnung der Tagesdifferenz, wenn auch nicht so lesbar wie timedelta.days.


1
Es gibt Fälle, in denen dieser Ansatz gewinnt. Beispielsweise beträgt der tatsächliche Unterschied zwischen 2019-07-09 23:50 und 2019-07-10 00:10 20 Minuten. (d1 - d0).dayskehrt zurück 0, d1.toordinal() - d0.toordinal()kehrt zurück 1. Hängt davon ab, was Sie in Ihrem tatsächlichen Anwendungsfall benötigen.
Peter.slizik

Dieser Ansatz kann tatsächlich Datum und Uhrzeit vergleichen. Zum Beispiel, um zu überprüfen, ob 2020-04-17 == 2020-04017 00:00:00
Harry Duong

2

Für die Berechnung von Datum und Uhrzeit gibt es mehrere Möglichkeiten, aber ich werde auf einfache Weise schreiben:

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

Ich hoffe es hilft


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

Dies setzt natürlich voraus, dass Sie bereits überprüft haben, ob Ihre Daten im Format vorliegen r'\d+/\d+/\d+'.


1
Dies fügt nichts Neues hinzu im Vergleich zu den Antworten, die 8 Jahre zuvor gegeben wurden. -1.
Mark Amery

1
Der Hauptunterschied besteht darin, dass die meisten anderen Antworten nicht einmal die Tatsache berücksichtigt haben, dass das OP seine Daten als Zeichenfolgen hatte. Und diejenigen, die dafür verantwortlich waren, verwendeten größtenteils kompliziertere Formatierer als unbedingt notwendig. Der Hauptunterschied ist also map(int, s.split('/')). Nicht gerade bahnbrechend, aber andererseits ist diese Frage ziemlich dumm grundlegend. Meine Antwort zeigt nur einen anderen Weg, um die Katze zu häuten.
Parthian Shot

Erwähnt wurde auch die Validierung, dass die Daten im richtigen Format vorliegen, und es wurde ein Regex für die Validierung in erster Näherung angegeben. Welche anderen nicht.
Parthian Shot

1

Hier sind drei Möglichkeiten, um dieses Problem zu lösen:

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.