2013-06-07 12 views
7

क्या relativedelta और timedelta के बीच कनवर्ट करना एक सुरुचिपूर्ण था?पाइथन datetime.timedelta को dateutil.relativedelta को बदलने के लिए सुरुचिपूर्ण तरीका

उपयोग केस उपयोगकर्ता इनपुट आईएसओ तिथि प्राप्त कर रहा है। पायथन का isodate या तो isodate.duration.Duration या datetime.timedelta वापस आ जाएगा।

हमें relativedelta (प्रति What is the difference between "datetime.timedelta" and "dateutil.relativedelta.relativedelta" when working only with days?) की विशेषताओं की आवश्यकता है - यह और अधिक है) इसलिए इन दोनों प्रकारों को relativedata में परिवर्तित करने की आवश्यकता है।

उत्तर

6

बस, seconds और microseconds की कुल संख्या ले कि सभी एक timedelta वस्तु भंडार है:

def to_relativedelta(tdelta): 
    return relativedelta(seconds=int(tdelta.total_seconds()), 
         microseconds=tdelta.microseconds) 

>>> to_relativedelta(timedelta(seconds=0.3)) 
relativedelta(microseconds=+300000) 
>>> to_relativedelta(timedelta(seconds=3)) 
relativedelta(seconds=+3) 
>>> to_relativedelta(timedelta(seconds=300)) 
relativedelta(minutes=+5) 
>>> to_relativedelta(timedelta(seconds=3000000)) 
relativedelta(days=+34, hours=+17, minutes=+20) 
+0

माइक्रोसॉंड कुल_सेकंड में शामिल हैं। –

+0

@LennartRegebro: हाँ, लेकिन relativedelta fractional सेकंड स्वीकार नहीं करता है ('relativedelta (सेकंड = 0.3)' 'relativedelta देता है (सेकंड = + 0)')। साथ ही, जैसा कि प्रलेखन कहता है, माइक्रोसॉन्ड बहुत बड़े अंतराल के लिए सटीक नहीं हो सकता है। –

+0

relativedelta (सेकंड = 0.3) मुझे relativedelta (सेकंड = 0.3) देता है। मैं पाइथन-डेटुटिल 1.5 – falsetru

0
d = datetime.timedelta(...) 
dateutil.relativedelta.relativedelta(seconds=d.total_seconds()) 
+0

http://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds – falsetru

0

सेकंड relativedelta के साथ सीधे का उपयोग करना महीनों और वर्षों खानों को भरने नहीं करता है और वहाँ का एक कारण यह है बेशक हम नहीं जानते कि यह 31 दिनों के साथ एक लीप वर्ष या एक महीने है।

तो कुछ इस तरह:

[In]: tdelta = datetime.now() - datetime(1971, 1, 1) 
[In]: relativedelta(seconds=tdelta.total_seconds()) 
[Out]: relativedelta(days=+16958, hours=+13, minutes=+19, seconds=+49) 

और दिन के बहुत सारे नहीं महीनों के साथ रिश्तेदार डेल्टा देता है। हालांकि कुछ मामलों में यह ठीक हो सकता है, कुछ में हमें वर्षों और महीनों की आवश्यकता हो सकती है। इसलिए:

def timedelta_to_relativedelta(tdelta): 
    assert isinstance(tdelta, timedelta) 

    seconds_in = { 
     'year' : 365 * 24 * 60 * 60, 
     'month' : 30 * 24 * 60 * 60, 
     'day' : 24 * 60 * 60, 
     'hour' : 60 * 60, 
     'minute': 60 
    } 

    years, rem = divmod(tdelta.total_seconds(), seconds_in['year']) 
    months, rem = divmod(rem, seconds_in['month']) 
    days, rem = divmod(rem, seconds_in['day']) 
    hours, rem = divmod(rem, seconds_in['hour']) 
    minutes, rem = divmod(rem, seconds_in['minute']) 
    seconds = rem 

    return relativedelta(years=years, months=months, days=days, hours=hours, minutes=minutes, seconds=seconds) 

यह एक बहुत ही पाइथोनिक समाधान नहीं हो सकता है लेकिन यह काम करता है।

नोट: यह मानता है कि एक वर्ष में 365 दिन (गैर लीप वर्ष छलांग लगते हैं) और महीनों में 30 दिन हैं।

संबंधित मुद्दे