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?

Strahl
quelle

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.

Dana
quelle
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
Dguaraglia
quelle
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 .

Harley Holcombe
quelle
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

kolrie
quelle
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)
Prasanna Ranganathan
quelle
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
7

Es kann auch leicht gemacht werden mit arrow:

import arrow

a = arrow.get('2017-05-09')
b = arrow.get('2017-05-11')

delta = (b-a)
print delta.days

Als Referenz: http://arrow.readthedocs.io/en/latest/

Cimarie
quelle
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()
Muhammad Elsayeh
quelle
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
Amit Gupta
quelle
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.

Dmitriy Arbeit
quelle
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

Gavriel Cohen
quelle
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+'.

Parthian Shot
quelle
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
Antoine Thiry
quelle