पायथन में एन सेकंड को डेटाइमटाइम में जोड़ने का मानक तरीका क्या है?


369

datetime.timeपायथन में एक मूल्य को देखते हुए , क्या एक पूर्णांक संख्या को सेकंड के लिए पूर्णांक संख्या में जोड़ने का एक मानक तरीका है, इसलिए कि 11:34:59+ 3 = 11:35:02, उदाहरण के लिए?

ये स्पष्ट विचार काम नहीं करते हैं:

>>> datetime.time(11, 34, 59) + 3
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'int'
>>> datetime.time(11, 34, 59) + datetime.timedelta(0, 3)
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.timedelta'
>>> datetime.time(11, 34, 59) + datetime.time(0, 0, 3)
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.time'

अंत में मैंने इस तरह के कार्य लिखे हैं:

def add_secs_to_time(timeval, secs_to_add):
    secs = timeval.hour * 3600 + timeval.minute * 60 + timeval.second
    secs += secs_to_add
    return datetime.time(secs // 3600, (secs % 3600) // 60, secs % 60)

मैं यह सोचने में मदद नहीं कर सकता कि मुझे यह करने का एक आसान तरीका याद आ रहा है।

सम्बंधित


संबंधित अजगर मुद्दा: '+' और के लिए datetime.time समर्थन '-'
JFS

जवाबों:


499

आप पूर्ण datetimeचर का उपयोग कर सकते हैं timedelta, और एक डमी तिथि प्रदान करके फिर timeसमय मान प्राप्त करने के लिए उपयोग कर सकते हैं।

उदाहरण के लिए:

import datetime
a = datetime.datetime(100,1,1,11,34,59)
b = a + datetime.timedelta(0,3) # days, seconds, then other fields.
print(a.time())
print(b.time())

दो मूल्यों में परिणाम, तीन सेकंड के अलावा:

11:34:59
11:35:02

आप अधिक पठनीय का विकल्प भी चुन सकते हैं

b = a + datetime.timedelta(seconds=3)

अगर तुम इतने झुके हो।


यदि आप एक समारोह के बाद ऐसा कर रहे हैं, तो आप addSecsनीचे प्रयोग करके देख सकते हैं:

import datetime

def addSecs(tm, secs):
    fulldate = datetime.datetime(100, 1, 1, tm.hour, tm.minute, tm.second)
    fulldate = fulldate + datetime.timedelta(seconds=secs)
    return fulldate.time()

a = datetime.datetime.now().time()
b = addSecs(a, 300)
print(a)
print(b)

यह आउटपुट:

 09:11:55.775695
 09:16:55

6
OverflowErrors से बचने के लिए, मैं एक अलग डमी तिथि का उपयोग करने की सलाह दूंगा, उदाहरण के लिए कुछ साल बाद: डेटाइम (101,1,1,11,34,59)। यदि आप ऊपर की तारीख से एक बड़े टाइमडेलटा को घटाने की कोशिश करते हैं, तो आपको एक "ओवरफ्लोरर: डेट ऑफ रेंज ऑफ आउट" त्रुटि मिलेगी क्योंकि एक
डेटाइम

2
@ पेहेलिक्स, किया, भले ही थोड़ा देर से, बिल्कुल चुस्त प्रतिक्रिया समय नहीं :-) जब से मुझे अपने कोड में एक और बग ठीक करना था, मैंने सोचा कि मैं उसी समय आपके सुझाव को शामिल करूंगा।
पैक्सिडाब्लो

53

जैसा कि यहां अन्य लोगों ने बताया है, आप पूरी तरह से संपूर्ण डेटाइम वस्तुओं का उपयोग कर सकते हैं:

from datetime import datetime, date, time, timedelta
sometime = time(8,00) # 8am
later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time()

हालाँकि, मुझे लगता है कि यह समझाने योग्य है कि पूर्ण डेटाटाइम ऑब्जेक्ट की आवश्यकता क्यों है। विचार करें कि क्या होगा अगर मैंने 2 घंटे 11 बजे जोड़ा। सही व्यवहार क्या है? एक अपवाद, क्योंकि आपके पास 11:59 बजे से बड़ा समय नहीं हो सकता है? क्या इसे वापस लपेटना चाहिए?

अलग-अलग प्रोग्रामर अलग-अलग चीजों की उम्मीद करेंगे, इसलिए उन्होंने जो भी परिणाम निकाला वह बहुत सारे लोगों को आश्चर्यचकित करेगा। इससे भी बदतर, प्रोग्रामर कोड लिखेंगे जो ठीक काम करते हैं जब उन्होंने इसे शुरू में परीक्षण किया था, और फिर कुछ अप्रत्याशित करके बाद में इसे तोड़ दिया। यह बहुत बुरा है, यही कारण है कि आपको समय-समय पर ऑब्जेक्ट्स जोड़ने की अनुमति नहीं है।


22

एक छोटी सी बात, सेकंड के लिए डिफ़ॉल्ट मान को ओवरराइड करने के लिए स्पष्टता जोड़ सकती है

>>> b = a + datetime.timedelta(seconds=3000)
>>> b
datetime.datetime(1, 1, 1, 12, 24, 59)

4
मैं यह पसंद है। निर्दिष्ट तर्क के साथ अच्छा और स्पष्ट।
विगॉन

12

पूरे डेटासेट का उपयोग करने के सुझाव के लिए @Pax Diablo, @bvmou और @Arachnid का धन्यवाद। अगर मुझे बाहरी स्रोत से डेटाइम.टाइम ऑब्जेक्ट्स को स्वीकार करना है, तो यह एक वैकल्पिक add_secs_to_time()कार्य लगता है :

def add_secs_to_time(timeval, secs_to_add):
    dummy_date = datetime.date(1, 1, 1)
    full_datetime = datetime.datetime.combine(dummy_date, timeval)
    added_datetime = full_datetime + datetime.timedelta(seconds=secs_to_add)
    return added_datetime.time()

इस क्रिया कोड को इस वन-लाइनर में संपीड़ित किया जा सकता है:

(datetime.datetime.combine(datetime.date(1, 1, 1), timeval) + datetime.timedelta(seconds=secs_to_add)).time()

लेकिन मुझे लगता है कि मैं कोड स्पष्टता के लिए एक समारोह में वैसे भी लपेटना चाहता हूँ।


धन्यवाद - महान विचार
अनुपम

9

यदि यह आपकी परियोजना में एक और फ़ाइल / निर्भरता जोड़ने के लायक है, तो मैंने सिर्फ एक छोटा सा वर्ग लिखा है जो datetime.timeअंकगणित करने की क्षमता के साथ विस्तारित होता है। जब आप आधी रात को जाते हैं, तो यह लगभग शून्य पर लपेटता है। अब, "क्या समय होगा, अब से 24 घंटे" में बहुत सारे कोने के मामले हैं, जिनमें डेलाइट सेविंग टाइम, लीप सेकंड, ऐतिहासिक टाइमज़ोन परिवर्तन, और इसी तरह शामिल हैं। लेकिन कभी-कभी आपको वास्तव में सरल मामले की आवश्यकता होती है, और यही वह करेगा।

आपका उदाहरण लिखा जाएगा:

>>> import datetime
>>> import nptime
>>> nptime.nptime(11, 34, 59) + datetime.timedelta(0, 3)
nptime(11, 35, 2)

nptimeइनहेरिट करता है datetime.time, इसलिए उन तरीकों में से कोई भी प्रयोग करने योग्य होना चाहिए।

यह PyPi से nptime("गैर-पांडित्य समय"), या GitHub पर उपलब्ध है: https://github.com/tgs/nptime


6

आप बस संख्या को जोड़ नहीं सकते datetime क्योंकि यह अस्पष्ट है कि किस इकाई का उपयोग किया जाता है: सेकंड, घंटे, सप्ताह ...

नहीं है timedeltaदिनांक और समय के साथ जोड़तोड़ के लिए वर्ग। datetimeमाइनस datetimeदेता है timedelta, datetimeप्लस timedeltaदेता है datetime, दो datetimeवस्तुओं को जोड़ा नहीं जा सकता है, हालांकि दोtimedelta कर सकते हैं।

बनाएं timedeltaकितने सेकंड आप जोड़ सकते हैं और में जोड़ने के लिए चाहते हैं के साथ वस्तु datetimeवस्तु:

>>> from datetime import datetime, timedelta
>>> t = datetime.now() + timedelta(seconds=3000)
>>> print(t)
datetime.datetime(2018, 1, 17, 21, 47, 13, 90244)

C ++ में एक ही अवधारणा है std::chrono::duration:।


4
कृपया हमेशा स्पष्टीकरण जोड़ें, नवागंतुकों के पास एक सुराग नहीं हो सकता है कि आप यहां क्या कर रहे हैं।
गेरहार्ड बार्नार्ड

3

पूर्णता की खातिर, यहाँ इसे arrow(पायथन के लिए बेहतर तारीख और समय) के साथ करने का तरीका है :

sometime = arrow.now()
abitlater = sometime.shift(seconds=3)

1

datetime.datetimeको जोड़ने का प्रयास करें datetime.timedelta। यदि आप केवल समय भाग चाहते हैं, तो आप इसे प्राप्त करने के लिए time()परिणामी datetime.datetimeवस्तु पर विधि कह सकते हैं ।


0

पुराना सवाल है, लेकिन मुझे लगा कि मैं टाइमज़ोन को संभालने वाले फ़ंक्शन में फेंक दूंगा। मुख्य भाग datetime.timeवस्तु की tzinfoविशेषता को संयोजित कर रहे हैं, और फिर परिणामी डमीटाइम के timetz()बजाय इसका उपयोग कर रहे हैं time()। यह उत्तर आंशिक रूप से अन्य उत्तरों से प्रेरित है।

def add_timedelta_to_time(t, td):
    """Add a timedelta object to a time object using a dummy datetime.

    :param t: datetime.time object.
    :param td: datetime.timedelta object.

    :returns: datetime.time object, representing the result of t + td.

    NOTE: Using a gigantic td may result in an overflow. You've been
    warned.
    """
    # Create a dummy date object.
    dummy_date = date(year=100, month=1, day=1)

    # Combine the dummy date with the given time.
    dummy_datetime = datetime.combine(date=dummy_date, time=t, tzinfo=t.tzinfo)

    # Add the timedelta to the dummy datetime.
    new_datetime = dummy_datetime + td

    # Return the resulting time, including timezone information.
    return new_datetime.timetz()

और यहाँ एक बहुत ही सरल परीक्षण केस क्लास है (बिल्ट-इन का उपयोग करके unittest):

import unittest
from datetime import datetime, timezone, timedelta, time

class AddTimedeltaToTimeTestCase(unittest.TestCase):
    """Test add_timedelta_to_time."""

    def test_wraps(self):
        t = time(hour=23, minute=59)
        td = timedelta(minutes=2)
        t_expected = time(hour=0, minute=1)
        t_actual = add_timedelta_to_time(t=t, td=td)
        self.assertEqual(t_expected, t_actual)

    def test_tz(self):
        t = time(hour=4, minute=16, tzinfo=timezone.utc)
        td = timedelta(hours=10, minutes=4)
        t_expected = time(hour=14, minute=20, tzinfo=timezone.utc)
        t_actual = add_timedelta_to_time(t=t, td=td)
        self.assertEqual(t_expected, t_actual)


if __name__ == '__main__':
    unittest.main()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.