Різниця між двома датами в Python


137

У мене дві різні дати, і я хочу знати різницю в днях між ними. Формат дати - РРРР-ММ-DD.

У мене є функція, яка може ДОДАТИ або ПІДТРИМИТИ дане число на дату:

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

де A - дата і x кількість днів, які я хочу додати. І результат - інша дата.

Мені потрібна функція, де я можу вказати дві дати, і результат буде int з різницею дат у днях.



Зауважте, що ваша функція addonDays вийде з ладу у дні DST.
fishinear

Ти правий. Я вже змінюю функцію. Якщо ви додасте 3600 (одна година), буде працювати.
mauguerra

Відповіді:


272

Використовуйте, -щоб отримати різницю між двома datetimeоб'єктами і взяти daysчлен.

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)

37
Чудова відповідь. Щоб було зрозуміло, результатом (d2 - d1)буде timedeltaоб’єкт.
aganders3

У мене ця консоль на консолі: тип об’єкта 'datetime.datetime' не має атрибута 'strptime'
mauguerra

2
Я отримую TypeError: об'єкт 'int' не викликається, коли я намагаюся робити .days () на об’єкт timedelta, і документація не згадує про нього ( docs.python.org/2/library/datetime.html ).
користувач1761806

4
Чи можете ви також зазначити total_seconds, будь ласка ? Я думаю, що це важливо, адже це те, що я очікував отримати, коли спробував, secondsне читаючи документів.
Мартін Тома

1
@ThejKiran Зробіть d2 і d1 окремо рівно один день і подивіться, чи це те, чого ви очікуєте ;-)
Мартін Тома

27

Ще одне коротке рішення:

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

3
Чи не є ifв diff_datesфункції абсолютно НЕ потрібно? За визначенням абсолютного значення abs(date1-date2)завжди буде дорівнює abs(date2-date1).
Blckknght

Принаймні, з Python3.5, заява про друк має виглядати так: print ('{} днів між {} та {}'. Форматом (результат1, d1, d2))
Ernestas Kardzys

2

Я спробував код, опублікований larsmans вище, але є кілька проблем:

1) Код, як є, призведе до помилки, про яку згадує mauguerra 2) Якщо ви зміните код на наступне:

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

Це перетворить ваші об’єкти дати в рядки, але, дві речі

1) Якщо спроба зробити d2 - d1 не вдасться, оскільки ви не можете використовувати мінусовий оператор на рядках, і 2) Якщо ви читаєте перший рядок вищевказаної відповіді, в якому зазначено, ви хочете використовувати оператор - для двох об'єктів datetime, але, ви просто перетворив їх у рядки

Я знайшов, що вам буквально потрібні лише такі:

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

1
Мій код використовується datetime.strptimeдля перетворення рядків в datetimeоб'єкти. Оскільки в ОП було зазначено, що "Формат дати - РРРР-ММ-DD", я вважав, що дати представляються як рядки. Якщо їх немає, конверсія очевидно не потрібна.
Фред Фоо

0

Спробуйте це:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.