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

StackOverflow https://stackoverflow.com/questions/100210

  •  01-07-2019
  •  | 
  •  

Вопрос

Учитывая 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)

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

Связанный

Это было полезно?

Решение

Вы можете использовать полную 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

Другие советы

Как уже говорили другие, вы можете просто использовать полные объекты 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()

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

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

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

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

Спасибо @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()

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top