Вопрос:

Каков стандартный способ добавить N секунд для datetime.time в Python?

python datetime time math

287615 просмотра

9 ответа

50881 Репутация автора

Учитывая datetime.timeзначение в Python, есть ли стандартный способ добавить к нему целое число секунд, так что , например , 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)

Я не могу не думать, что мне не хватает более простого способа сделать это, хотя.

Связанный

Автор: Paul Stephenson Источник Размещён: 19.09.2008 07:19

Ответы (9)


1 плюс

95795 Репутация автора

Попробуйте добавить datetime.datetimeк datetime.timedelta. Если вам нужна только часть времени, вы можете вызвать time()метод для результирующего datetime.datetimeобъекта, чтобы получить его.

Автор: Nick Johnson Размещён: 19.09.2008 07:29

461 плюса

675743 Репутация автора

Решение

Вы можете использовать полные 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
Автор: paxdiablo Размещён: 19.09.2008 07:54

19 плюса

24853 Репутация автора

Одна маленькая вещь, может добавить ясности, чтобы переопределить значение по умолчанию на секунды

>>> b = a + datetime.timedelta(seconds=3000)
>>> b
datetime.datetime(1, 1, 1, 12, 24, 59)
Автор: unmounted Размещён: 19.09.2008 08:08

11 плюса

50881 Репутация автора

Спасибо @Pax Diablo, @bvmou и @Arachnid за предложение использовать полные даты и времени. Если мне нужно принять объекты datetime.time из внешнего источника, то это, кажется, альтернативная 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()

но я думаю, я бы хотел обернуть это в функцию для ясности кода в любом случае.

Автор: Paul Stephenson Размещён: 19.09.2008 09:40

47 плюса

132319 Репутация автора

Как уже говорили другие, вы можете просто использовать полные объекты datetime:

sometime = get_some_time() # the time to which you want to add 3 seconds
later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time()

Тем не менее, я думаю, что стоит объяснить, почему требуются полные объекты даты и времени. Посмотрим, что произойдет, если я добавлю 2 часа до 11 вечера. Какое правильное поведение? Исключение, потому что вы не можете иметь время больше 23:59? Должен ли он обернуться?

Разные программисты будут ожидать разных вещей, поэтому любой результат, который они выберут, удивит многих. Хуже всего то, что программисты писали код, который отлично работал, когда они сначала тестировали его, а затем ломали его позже, делая что-то неожиданное. Это очень плохо, поэтому вы не можете добавлять объекты timedelta к объектам времени.

Автор: Eli Courtwright Размещён: 19.09.2008 01:47

8 плюса

7506 Репутация автора

Если стоит добавить еще один файл / зависимость в ваш проект, я только что написал крошечный маленький класс, который расширяет 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

Автор: rescdsk Размещён: 27.07.2011 03:49

3 плюса

900 Репутация автора

Для полноты, вот способ сделать это arrow(лучше даты и время для Python):

sometime = arrow.now()
abitlater = sometime.shift(seconds=3)
Автор: Bart Van Loon Размещён: 09.10.2017 07:41

5 плюса

105 Репутация автора

Вы не можете просто добавить число, 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.

Автор: user2387567 Размещён: 18.01.2018 07:30

0 плюса

320 Репутация автора

Старый вопрос, но я решил добавить функцию, которая обрабатывает часовые пояса. Ключевые части передают атрибут 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()
Автор: blthayer Размещён: 14.08.2019 03:58
Вопросы из категории :
32x32