Apa perbedaan antara "datetime.timedelta" dan "dateutil.relativedelta.relativedelta" saat bekerja hanya dengan hari?

90

Apa perbedaan antara datetime.timedelta(dari pustaka standar Python) dan dateutil.relativedelta.relativedeltasaat bekerja hanya dengan hari?

Sejauh yang saya mengerti, timedeltahanya mendukung hari (dan minggu), sambil relativedeltamenambahkan dukungan untuk periode yang ditentukan dalam hal tahun, bulan, minggu atau hari, serta menentukan nilai absolut untuk tahun, bulan atau hari. (ingat, untuk keperluan pertanyaan ini, saya tidak perlu khawatir tentang jam, menit, atau detik)

Mengingat saya hanya bekerja dengan datetime.dateobjek, dan hanya tertarik pada periode yang ditentukan oleh jumlah hari, apa perbedaan antara timedeltadan relativedelta? Apakah ada bedanya?

from datetime import date, timedelta
from dateutil.relativedelta import relativedelta

i = -1  # This could have been any integer, positive or negative
someday = date.today()
# Is there any difference between these two lines?
otherday = someday + timedelta(days=i)
otherday = someday + relativedelta(days=i)
Denilson Sá Maia
sumber
3
Jika Anda hanya tertarik pada delta di hari-hari antara tanggal, cukup gunakan pustaka standar dateime.timedeltayang akan mencapai apa yang Anda inginkan dan hindari ketergantungan pada dateutilpaket eksternal .
Pedro Romano
Perlu dikatakan bahwa selain menghemat satu ketergantungan ekstra, menghitung delta dalam hari-hari di antara tanggal-tanggal itu beberapa kali lebih cepat dengan timedelta daripada relativedelta. (~ 10 kali)
Julien B.

Jawaban:

76

dateutiladalah paket ekstensi untuk datetimemodul standar python . Seperti yang Anda katakan, ini menyediakan fungsionalitas ekstra, seperti lelt waktu yang diekspresikan dalam satuan yang lebih besar dari satu hari.

Ini berguna jika Anda harus mengajukan pertanyaan seperti berapa bulan saya dapat menabung sebelum pacar saya berulang tahun, atau berapa bulan Jumat terakhir? Ini menyembunyikan kalkulasi kompleks yang disebabkan oleh panjang bulan yang berbeda, atau hari ekstra dalam tahun kabisat.

Dalam kasus Anda, Anda hanya tertarik pada jumlah hari. Jadi sebaiknya gunakan timedeltakarena ini menghindari ketergantungan ekstra pada dateutilpaket.

Hans Kemudian
sumber
32

A relativedeltamemiliki lebih banyak parameter daripada timedelta:

Definition:   relativedelta.relativedelta(self, dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0,
seconds=0, microseconds=0, year=None, month=None, day=None,
weekday=None, yearday=None, nlyearday=None, hour=None, minute=None,
second=None, microsecond=None)

yang dengannya Anda dapat melakukan hal-hal seperti menghitung hari Jumat terakhir dalam sebulan:

In [14]: import datetime as dt

In [15]: import dateutil.relativedelta as relativedelta

In [16]: today = dt.date.today()

In [17]: rd = relativedelta.relativedelta(day = 31, weekday = relativedelta.FR(-1))

In [18]: today+rd
Out[18]: datetime.date(2012, 9, 28)
unutbu
sumber
1
Ini adalah jawaban luar biasa yang memberikan wawasan baru tentang penggunaan relativedelta untuk hal-hal seperti "jumat terakhir bulan ini" :) Terima kasih!
PascalVKooten
10

Satu perbedaan utama yang tidak disorot dalam jawaban lain adalah adanya kata benda tunggal dan jamak untuk setiap perbedaan waktu primitif. Sementara timedeltahanya menawarkan kata benda jamak (misalnya hours, days) untuk menunjukkan perbedaan waktu relatif, relativedeltamenawarkan kata benda tunggal juga (misalnya hour, day) untuk menunjukkan informasi waktu absolut.

Ini jelas dari definisi 2 kelas:

Definition:   datetime.timedelta([days[, seconds[, microseconds[, 
milliseconds[, minutes[, hours[, weeks]]]]]]])

Definition:   relativedelta.relativedelta(self, dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0,
seconds=0, microseconds=0, year=None, month=None, day=None,
weekday=None, yearday=None, nlyearday=None, hour=None, minute=None,
second=None, microsecond=None)

Sekarang, sebenarnya apa yang dilakukan bentuk tunggalnya? Bentuk tunggal membuat delta yang ketika ditambahkan ke datetimeobjek, menyetel tanggal / waktu tertentu primitif dalam datetimeobjek ke yang disebutkan di relativedelta. Berikut ini contoh kecilnya:

>>> import datetime as dt; from dateutil.relativedelta import *
>>> NOW = dt.datetime(2018, 11, 17, 9, 6, 31)
>>> NOW
datetime.datetime(2018, 11, 17, 9, 6, 31)
>>> NOW + relativedelta(hours=1) #Simply add one hour
datetime.datetime(2018, 11, 17, 10, 6, 31)
>>> NOW + relativedelta(hour=1) #Set the hour to 01:00 am
datetime.datetime(2018, 11, 17, 1, 6, 31)

Ini bisa menyebabkan relativedelta digunakannya beberapa aplikasi menarik, yang dapat menjadi rumit untuk diterapkan menggunakan timedelta. Salah satu yang cepat terlintas dalam pikiran adalah pembulatan.

Aplikasi yang Menarik: Pembulatan Cepat

Sekarang saya akan menunjukkan cara relativedeltayang lebih ekspresif saat melakukan pembulatan adatetime objek ke menit, jam, hari terdekat, dll.

Pembulatan ke jam terdekat:

Perhatikan betapa mudahnya membulatkan menggunakan relativedelta:

#Using `relativedelta`
NOW + relativedelta(hours=1, minute=0, second=0, microsecond=0)

#Using `timedelta`
dt.combine(NOW.date(),dt.time(NOW.hour,0,0)) + dt.timedelta(0,60*60,0)

Pembulatan lain yang lebih rumit mudah dicapai dengan menggunakan relativedelta. Namun, perhatikan bahwa semua pembulatan yang dapat dilakukan relativedeltajuga dapat dilakukan dengan menggunakan datetimefungsi dan timedelta, hanya dengan cara yang sedikit lebih berbelit-belit.

shivam
sumber