Каков стандартный способ добавить N секунд к datetime.time в Python?
Вопрос
Учитывая 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
возражать, чтобы получить это.