Каков стандартный способ добавить N секунд для datetime.time в Python? - PullRequest
304 голосов
/ 19 сентября 2008

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

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

Относящиеся

Ответы [ 8 ]

432 голосов
/ 19 сентября 2008

Вы можете использовать полные 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
45 голосов
/ 19 сентября 2008

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

19 голосов
/ 19 сентября 2008

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

>>> b = a + datetime.timedelta(seconds=3000)
>>> b
datetime.datetime(1, 1, 1, 12, 24, 59)
11 голосов
/ 19 сентября 2008

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

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

6 голосов
/ 27 июля 2011

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

5 голосов
/ 18 января 2018

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

2 голосов
/ 09 октября 2017

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

sometime = arrow.now()
abitlater = sometime.shift(seconds=3)
1 голос
/ 19 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...