อะไรคือความแตกต่างระหว่าง“ datetime.timedelta” และ“ dateutil.relativedelta.relativedelta” เมื่อทำงานกับวันเท่านั้น


90

อะไรคือความแตกต่างระหว่างdatetime.timedelta(จากไลบรารีมาตรฐานของ Python) และdateutil.relativedelta.relativedeltaเมื่อทำงานเฉพาะกับวัน

เท่าที่ฉันเข้าใจtimedeltaรองรับเฉพาะวัน (และสัปดาห์) ในขณะที่relativedeltaเพิ่มการรองรับสำหรับช่วงเวลาที่กำหนดเป็นปีเดือนสัปดาห์หรือวันตลอดจนการกำหนดค่าสัมบูรณ์สำหรับปีเดือนหรือวัน (จำไว้ว่าสำหรับจุดประสงค์ของคำถามนี้ฉันไม่ต้องกังวลเกี่ยวกับชั่วโมงนาทีหรือวินาที)

เมื่อพิจารณาว่าฉันทำงานกับอdatetime.dateอบเจ็กต์เท่านั้นและสนใจเฉพาะช่วงเวลาที่กำหนดโดยจำนวนวันความแตกต่างระหว่างtimedeltaและrelativedeltaคืออะไร? มีความแตกต่างกันหรือไม่?

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
หากคุณสนใจเฉพาะเดลต้าในช่วงวันที่ระหว่างวันที่ให้ใช้ไลบรารีมาตรฐานdateime.timedeltaซึ่งจะบรรลุสิ่งที่คุณต้องการและหลีกเลี่ยงการพึ่งพาdateutilแพ็คเกจภายนอก
Pedro Romano

เป็นสิ่งที่ควรค่าแก่การกล่าวว่านอกเหนือจากการประหยัดการพึ่งพาเพิ่มเติมแล้วการคำนวณเดลต้าในวันระหว่างวันที่นั้นเร็วกว่าหลายเท่าเมื่อใช้ timedelta มากกว่า relativedelta (~ 10 ครั้ง)
Julien B.

คำตอบ:


76

dateutilเป็นแพ็คเกจเสริมสำหรับdatetimeโมดูลมาตรฐาน python อย่างที่คุณพูดมันมีฟังก์ชันพิเศษเช่น Timedeltas ที่แสดงเป็นหน่วยที่มากกว่าหนึ่งวัน

สิ่งนี้มีประโยชน์หากคุณต้องถามคำถามเช่นฉันจะเก็บเงินได้กี่เดือนก่อนวันเกิดของแฟนฉันจะเกิดขึ้นหรือวันศุกร์สุดท้ายของเดือนคืออะไร สิ่งนี้ซ่อนการคำนวณที่ซับซ้อนซึ่งเกิดจากความยาวที่แตกต่างกันของเดือนหรือวันพิเศษในปีอธิกสุรทิน

ในกรณีของคุณคุณสนใจเฉพาะจำนวนวัน ดังนั้นคุณควรใช้timedeltaเพื่อหลีกเลี่ยงการพึ่งพาdateutilแพ็กเกจเพิ่มเติม


32

A relativedeltaมีพารามิเตอร์มากกว่า 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)

ซึ่งคุณสามารถทำสิ่งต่างๆเช่นคำนวณวันศุกร์สุดท้ายของเดือน:

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
นี่เป็นคำตอบที่ยอดเยี่ยมซึ่งให้ข้อมูลเชิงลึกใหม่เกี่ยวกับการใช้ relativedelta สำหรับสิ่งต่างๆเช่น "วันศุกร์สุดท้ายของเดือน" :) ขอบคุณ!
PascalVKooten

11

ความแตกต่างที่สำคัญอย่างหนึ่งที่ไม่ได้เน้นในคำตอบอื่น ๆ คือการปรากฏตัวของคำนามเอกพจน์และพหูพจน์สำหรับความแตกต่างดั้งเดิมในแต่ละครั้ง ในขณะที่timedeltaข้อเสนอเพียงพหูพจน์คำนาม (เช่นhours, days) เพื่อแสดงถึงความแตกต่างเวลาญาติrelativedeltaเสนอคำนามเอกพจน์เช่นกัน (เช่นhour, day) เพื่อแสดงข้อมูลเวลาที่แน่นอน

สิ่งนี้ชัดเจนจากคำจำกัดความของ 2 คลาส:

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)

ตอนนี้รูปเอกพจน์ทำอะไรได้บ้าง? รูปแบบเอกพจน์สร้างเดลต้าซึ่งเมื่อเพิ่มลงในdatetimeอ็อบเจ็กต์ตั้งค่าวันที่ / เวลาดั้งเดิมที่ระบุในdatetimeอ็อบเจ็กต์เป็นที่กล่าวถึงในrelativedelta. นี่คือตัวอย่างเล็ก ๆ :

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

นี้สามารถนำไปสู่การถูกนำมาใช้สำหรับการใช้งานที่น่าสนใจบางอย่างซึ่งจะมีความซับซ้อนในการดำเนินการใช้relativedelta timedeltaสิ่งที่อยู่ในใจอย่างรวดเร็วคือการปัดเศษ

แอปพลิเคชั่นที่น่าสนใจ: การปัดเศษอย่างรวดเร็ว

ตอนนี้ฉันจะแสดงให้คุณเห็นว่าrelativedeltaมีการแสดงออกอย่างไรเมื่อทำการปัดเศษdatetimeวัตถุเป็นนาทีชั่วโมงวัน ฯลฯ ที่ใกล้ที่สุด

ปัดเศษเป็นชั่วโมงที่ใกล้ที่สุด:

สังเกตว่าการปัดเศษโดยใช้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)

มีความซับซ้อนมากขึ้นการปัดเศษแข่งขันอื่น ๆ relativedeltaจะทำได้อย่างง่ายดายโดยใช้ อย่างไรก็ตามโปรดทราบว่าการปัดเศษทั้งหมดที่สามารถทำได้โดยrelativedeltaใช้datetimeฟังก์ชันและtimedeltaวิธีที่ซับซ้อนกว่าเล็กน้อยเท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.