Różnica między dwiema datami w Pythonie

150

Mam dwie różne daty i chcę poznać różnicę w dniach między nimi. Format daty to RRRR-MM-DD.

Mam funkcję, która może DODAĆ lub ODEJMOWAĆ podaną liczbę do daty:

def addonDays(a, x):
   ret = time.strftime("%Y-%m-%d",time.localtime(time.mktime(time.strptime(a,"%Y-%m-%d"))+x*3600*24+3600))      
   return ret

gdzie A jest datą, a x liczbą dni, które chcę dodać. Rezultatem jest kolejna randka.

Potrzebuję funkcji, w której mogę podać dwie daty, a wynikiem będzie int z różnicą dat w dniach.

mauguerra
źródło
Pamiętaj, że funkcja addonDays nie powiedzie się w dni czasu letniego.
fishinear
Masz rację. Ja już modyfikuję funkcję. Jeśli dodasz 3600 (jedna godzina), zadziała.
mauguerra

Odpowiedzi:

299

Użyj, -aby uzyskać różnicę między dwoma datetimeobiektami i wziąć daysczłonka.

from datetime import datetime

def days_between(d1, d2):
    d1 = datetime.strptime(d1, "%Y-%m-%d")
    d2 = datetime.strptime(d2, "%Y-%m-%d")
    return abs((d2 - d1).days)
Fred Foo
źródło
45
Świetna odpowiedź. Żeby było jasne, wynikiem (d2 - d1)będzie timedeltaobiekt.
aganders3
1
Mam ten błąd na konsoli: obiekt typu „datetime.datetime” nie ma atrybutu „strptime”
mauguerra
2
Otrzymuję TypeError: obiekt 'int' nie jest wywoływalny, kiedy próbuję wykonać .days () na obiekcie timedelta, a dokumentacja również o tym nie wspomina ( docs.python.org/2/library/datetime.html ).
user1761806
4
Czy mógłbyś też wspomnieć total_seconds? Myślę, że to jest ważne, ponieważ to jest to, czego się spodziewałem, kiedy próbowałem secondsbez czytania dokumentów.
Martin Thoma,
1
@ThejKiran Rozmieść d2 i d1 dokładnie jeden dzień i zobacz, czy tego właśnie oczekujesz ;-)
Martin Thoma
30

Kolejne krótkie rozwiązanie:

from datetime import date

def diff_dates(date1, date2):
    return abs(date2-date1).days

def main():
    d1 = date(2013,1,1)
    d2 = date(2013,9,13)
    result1 = diff_dates(d2, d1)
    print '{} days between {} and {}'.format(result1, d1, d2)
    print ("Happy programmer's day!")

main()
0x8BADF00D
źródło
3
Czy funkcja ifw diff_datesfunkcji nie jest całkowicie niepotrzebna? Z definicji wartość bezwzględna abs(date1-date2)zawsze będzie równa abs(date2-date1).
Blckknght
Przynajmniej w Pythonie 3.5 instrukcja print powinna wyglądać następująco: print ('{} dni między {} a {}'. Format (wynik1, d1, d2))
Ernestas Kardzys
2

Wypróbowałem kod wysłany przez larsmana powyżej, ale jest kilka problemów:

1) Kod taki, jaki jest, zgłosi błąd, o którym wspomina mauguerra 2) Jeśli zmienisz kod na następujący:

...
    d1 = d1.strftime("%Y-%m-%d")
    d2 = d2.strftime("%Y-%m-%d")
    return abs((d2 - d1).days)

Spowoduje to przekonwertowanie obiektów datetime na ciągi, ale dwie rzeczy

1) Próba wykonania d2 - d1 zakończy się niepowodzeniem, ponieważ nie możesz użyć operatora minus na łańcuchach i 2) Jeśli przeczytałeś pierwszy wiersz powyższej odpowiedzi, to właśnie podano, chcesz użyć operatora - na dwóch obiektach daty i godziny, ale po prostu przekształcił je w łańcuchy

Odkryłem, że dosłownie potrzebujesz tylko:

import datetime

end_date = datetime.datetime.utcnow()
start_date = end_date - datetime.timedelta(days=8)
difference_in_days = abs((end_date - start_date).days)

print difference_in_days
schalkneethling
źródło
1
Mój kod używa datetime.strptimedo konwersji ciągów znaków na datetimeobiekty. Ponieważ w OP stwierdzono, że „Format daty to RRRR-MM-DD”, założyłem, że daty są przedstawiane jako ciągi. Jeśli tak nie jest, oczywiście nie ma potrzeby konwersji.
Fred Foo
0

Spróbuj tego:

data=pd.read_csv('C:\Users\Desktop\Data Exploration.csv')
data.head(5)
first=data['1st Gift']
last=data['Last Gift']
maxi=data['Largest Gift']
l_1=np.mean(first)-3*np.std(first)
u_1=np.mean(first)+3*np.std(first)


m=np.abs(data['1st Gift']-np.mean(data['1st Gift']))>3*np.std(data['1st Gift'])
pd.value_counts(m)
l=first[m]
data.loc[:,'1st Gift'][m==True]=np.mean(data['1st Gift'])+3*np.std(data['1st Gift'])
data['1st Gift'].head()




m=np.abs(data['Last Gift']-np.mean(data['Last Gift']))>3*np.std(data['Last Gift'])
pd.value_counts(m)
l=last[m]
data.loc[:,'Last Gift'][m==True]=np.mean(data['Last Gift'])+3*np.std(data['Last Gift'])
data['Last Gift'].head()
user8359392
źródło
-1

Wypróbowałem kilka kodów, ale w końcu używam czegoś tak prostego jak (w Pythonie 3):

from datetime import datetime
df['difference_in_datetime'] = abs(df['end_datetime'] - df['start_datetime'])

Jeśli twoje start_datetime i end_datetime kolumny są w datetime64[ns]formacie datetime rozumie go i zwróci różnicę w dni + znacznik czasu, który jest w timedelta64[ns]formacie.

Jeśli chcesz zobaczyć tylko różnicę w dniach , możesz oddzielić tylko część daty początkowej i końcowej godziny, używając (działa również dla części czasu ):

df['start_date'] = df['start_datetime'].dt.date
df['end_date'] = df['end_datetime'].dt.date

A potem biegnij:

df['difference_in_days'] = abs(df['end_date'] - df['start_date'])
Marcus Trugilho
źródło
-5

pd.date_range ('2019-01-01', '2019-02-01'). shape [0]

ar91
źródło