পাইথনে ডেটটাইম.টাইমে এন সেকেন্ড যুক্ত করার মানক উপায় কী?


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)

যদিও আমি এটি করতে একটি সহজ উপায় অনুপস্থিত তা ভেবে সাহায্য করতে পারি না।

সম্পর্কিত


সম্পর্কিত পাইথন ইস্যু: '+' এবং '-' এর জন্য
ডেটটাইম.টাইম

উত্তর:


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
ওভারফ্লো এরিফারগুলি এড়াতে, আমি আলাদা ডামি তারিখ ব্যবহার করার পরামর্শ দেব, উদাহরণস্বরূপ কয়েক বছর পরে: ডেটটাইম (101,1,1,11,34,59)। যদি আপনি উপরের তারিখ থেকে বৃহত টাইমডেল্টা বিয়োগ করার চেষ্টা করেন, আপনি একটি "ওভারফ্লো এরিয়ার: তারিখের মূল্য ছাড়িয়ে যায়" তারিখের সময় অবজেক্টের জন্য বছরের হিসাবে ত্রুটিটি 1
ফেইলিক্স

2
@ ফিলিকস, কিছুটা দেরীতে হলেও ঠিক চটজলদি প্রতিক্রিয়া সময় নয় :-) যেহেতু আমার কোডটিতে আমাকে অন্য একটি বাগ ফিক্স করতে হয়েছিল, তাই আমি ভেবেছিলাম যে আমি আপনার পরামর্শটি একই সাথে অন্তর্ভুক্ত করব।
প্যাক্সডিয়াবল্লো

53

এখানে অন্যরা যেমন বলেছে, আপনি কেবল পুরো ডেটটাইম অবজেক্টগুলি জুড়ে ব্যবহার করতে পারেন:

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

যাইহোক, আমি মনে করি কেন পুরো ডেটটাইম অবজেক্টগুলি প্রয়োজন তা ব্যাখ্যা করা উপযুক্ত। আমি 11 ঘন্টা বেলা 2 ঘন্টা যোগ করা হলে কি হবে তা বিবেচনা করুন। সঠিক আচরণ কি? একটি ব্যতিক্রম, কারণ আপনার কাছে রাত 11:59 এর চেয়ে বেশি সময় থাকতে পারে না? এটি প্রায় ফিরে মোড়ানো উচিত?

বিভিন্ন প্রোগ্রামাররা বিভিন্ন জিনিস প্রত্যাশা করবে, সুতরাং যে কোনও ফলাফল তারা বেছে নিলে অনেক লোক অবাক হয়ে যায়। সবচেয়ে খারাপ বিষয়, প্রোগ্রামাররা কোডটি লিখতেন যা প্রাথমিকভাবে এটি পরীক্ষা করার সময় ঠিকঠাক কাজ করেছিল এবং তারপরে অপ্রত্যাশিত কিছু করে এটি পরে ভেঙে ফেলবে। এটি খুব খারাপ, এজন্য আপনাকে সময়সীমার সাথে টাইমডেল্টা অবজেক্ট যুক্ত করার অনুমতি দেওয়া হচ্ছে না।


22

একটি সামান্য জিনিস, সেকেন্ডের জন্য ডিফল্ট মানটিকে ওভাররাইড করতে স্বচ্ছতা যুক্ত করতে পারে

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

4
আমার এটা ভাল লেগেছে. নির্দিষ্ট আর্গুমেন্টের সাথে দুর্দান্ত এবং পরিষ্কার।
ভিজরন্ড

12

পুরো ডেটটাইম জুড়ে ব্যবহারের পরামর্শের জন্য @ প্যাক্স ডায়াবলো, @ বিভিএমউ এবং @ আরাকনিডকে ধন্যবাদ জানাই। যদি আমাকে কোনও বহিরাগত উত্স থেকে ডেটটাইম.টাইম অবজেক্ট গ্রহণ করতে হয়, তবে এটি একটি বিকল্প 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পাটিগণিত করার ক্ষমতা নিয়ে প্রসারিত । আপনি যখন মধ্যরাত পেরিয়ে যান, তখন এটি শূন্যের কাছাকাছি যায় wra এখন, "এখন কী সময় হবে, এখন থেকে ২৪ ঘন্টা" এর মধ্যে দিবালোকের সঞ্চয় সময়, লিপ সেকেন্ড, historicalতিহাসিক টাইমজোন পরিবর্তন ইত্যাদিসহ অনেকগুলি কর্নার কেস রয়েছে। তবে কখনও কখনও আপনার সত্যিকারের সরল কেসের প্রয়োজন হয় এবং এটিই এটি করবে।

আপনার উদাহরণ লেখা হবে:

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

nptimeউত্তরাধিকার সূত্রে প্রাপ্ত datetime.time, সুতরাং এই পদ্ধতিগুলির যে কোনওটি ব্যবহারযোগ্যও হবে।

এটি পিপিআই থেকে nptime("নন- পেডেন্টিক সময়") হিসাবে পাওয়া যায় , বা গিটহাব: 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)

সি ++: তে একই ধারণা রয়েছে 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()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.