Sự khác biệt giữa “datetime.timedelta” và “dateutil.relativedelta.relativedelta” là gì khi chỉ làm việc với ngày?


90

Sự khác biệt giữa datetime.timedelta(từ thư viện tiêu chuẩn của Python) và dateutil.relativedelta.relativedeltakhi chỉ làm việc với ngày là gì?

Theo như tôi hiểu, timedeltachỉ hỗ trợ ngày (và tuần), trong khi relativedeltathêm hỗ trợ cho các khoảng thời gian được xác định theo năm, tháng, tuần hoặc ngày, cũng như xác định giá trị tuyệt đối cho năm, tháng hoặc ngày. (hãy nhớ, với mục đích của câu hỏi này, tôi không phải lo lắng về giờ, phút hoặc giây)

Xem xét rằng tôi chỉ làm việc với datetime.datecác đối tượng và chỉ quan tâm đến các khoảng thời gian được xác định bởi số ngày, sự khác biệt giữa timedeltavà là relativedeltagì? Có sự khác biệt nào không?

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)

3
Nếu bạn chỉ quan tâm đến delta trong các ngày giữa các ngày, chỉ cần sử dụng thư viện tiêu chuẩn dateime.timedeltasẽ đạt được những gì bạn muốn và tránh phụ thuộc vào dateutilgói bên ngoài .
Pedro Romano

Điều đáng nói là ngoài việc tiết kiệm thêm một sự phụ thuộc, việc tính toán delta trong các ngày giữa các ngày sẽ nhanh hơn nhiều lần với thời gian theo thời gian so với tương đối. (~ 10 lần)
Julien B.

Câu trả lời:


76

dateutillà một gói mở rộng cho datetimemô-đun tiêu chuẩn python . Như bạn nói, nó cung cấp chức năng bổ sung, chẳng hạn như thời gian được biểu thị bằng đơn vị lớn hơn một ngày.

Điều này rất hữu ích nếu bạn phải hỏi những câu hỏi như tôi có thể tiết kiệm được bao nhiêu tháng trước khi sinh nhật bạn gái tôi, hoặc thứ sáu cuối cùng trong tháng là gì? Điều này che giấu các phép tính phức tạp gây ra bởi độ dài khác nhau của các tháng hoặc số ngày thừa trong năm nhuận.

Trong trường hợp của bạn, bạn chỉ quan tâm đến số ngày. Vì vậy, tốt nhất bạn nên sử dụng timedeltavì điều này tránh phụ thuộc thêm vào dateutilgói.


32

A relativedeltacó nhiều tham số hơn a 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)

mà bạn có thể làm những việc như tính toán thứ Sáu cuối cùng trong tháng:

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)

1
Đây là một câu trả lời tuyệt vời đã cung cấp cái nhìn sâu sắc mới về việc sử dụng đồng hành tương đối cho những thứ như "ngày thứ sáu cuối cùng của tháng" :) Cảm ơn!
PascalVKooten

10

Một điểm khác biệt chính không được làm nổi bật trong các câu trả lời khác là sự hiện diện của danh từ số ít và số nhiều cho mỗi sự khác biệt thời gian nguyên thủy. Trong khi timedeltachỉ cung cấp danh từ số nhiều (ví dụ hours, days) để biểu thị sự khác biệt về thời gian tương đối, relativedeltacung cấp danh từ số ít (ví dụ hour, day) để biểu thị thông tin thời gian tuyệt đối.

Điều này rõ ràng từ định nghĩa của 2 lớp:

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)

Bây giờ, chính xác thì dạng số ít làm gì? Dạng số ít tạo ra một delta khi được thêm vào một datetimeđối tượng, đặt ngày / giờ cụ thể đó trong datetimeđối tượng thành được đề cập trong relativedelta. Đây là một ví dụ nhỏ:

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

Điều này có thể dẫn đến relativedeltaviệc được sử dụng cho một số ứng dụng thú vị, có thể phức tạp để triển khai sử dụng timedelta. Một điều mà bạn nhanh chóng nghĩ đến là làm tròn số.

Một ứng dụng thú vị: Nhanh chóng làm tròn

Bây giờ tôi sẽ chỉ cho bạn cách relativedeltabiểu cảm hơn khi làm tròn một datetimeđối tượng đến phút, giờ, ngày, v.v.

Làm tròn đến giờ gần nhất:

Lưu ý rằng nó đơn giản như thế nào khi sử dụng 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)

Các quy tắc làm tròn phức tạp khác có thể dễ dàng đạt được bằng cách sử dụng relativedelta. Tuy nhiên, lưu ý rằng tất cả các vòng lặp có thể được thực hiện bởi relativedeltacũng có thể được thực hiện bằng cách sử dụng các datetimehàm và timedeltachỉ theo một cách phức tạp hơn một chút.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.