timedeltaне является безопасным при переполнении и не может правильно выполнять математические операции, например, str(timedelta(hours=8) - timedelta(hours=10))результат '-1 day, 22:00:00'и целочисленное решение как раз для тех ситуаций, где вам нужно'-02:00:00' .
cprn
1
+1. Этот ответ может быть изменен очень легко. Например, если вы хотите пропустить поле при печати, используйте это: stackoverflow.com/questions/7999935/…
eric_kernfeld
616
Используя divmod()функцию, которая выполняет только одно деление для получения как частного, так и остатка, вы можете очень быстро получить результат, выполнив всего две математические операции:
m, s = divmod(seconds,60)
h, m = divmod(m,60)
А затем используйте форматирование строки, чтобы преобразовать результат в желаемый результат:
print('{:d}:{:02d}:{:02d}'.format(h, m, s))# Python 3print(f'{h:d}:{m:02d}:{s:02d}')# Python 3.6+
Если вы предпочитаете операторы над функциями, используйте модуль; например (только минуты / секунды):'%d:%02dmn' % (seconds / 60, seconds % 60)
буф
18
И вы можете продлить его до дней d, h = divmod(h, 24).
Марк Рэнсом
14
@MarkRansom: а затем месяцы m, d = divmod(m, 31). Ой, нет, ты не можешь. Хуже того, ваш код будет неправильным, если в игру вступят дополнительные секунды. Короче говоря: используйте timedeltaи не связывайтесь с календарем, он вас укусит.
4
@ Тибо timedeltaсправляется с високосными секундами? Я подозреваю, что нет. Существует множество приложений, в которых эта простая математика более чем достаточна.
Марк Рэнсом
1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))результат '-1 день, 22:00:00', так что ... idk, если он работает с високосными секундами, но не работает с отрицательными числами.
CpRn
70
Я не могу назвать это простым способом (по крайней мере, я не могу вспомнить синтаксис), но возможно использовать time.strftime , который дает больше контроля над форматированием:
from time import strftime
from time import gmtime
strftime("%H:%M:%S", gmtime(666))'00:11:06'
strftime("%H:%M:%S", gmtime(60*60*24))'00:00:00'
gmtime используется для преобразования секунд в специальный формат кортежа, который strftime()требуется.
К сожалению, этот метод начинает измерять дни с 1, поэтому он не предназначен для представления разницы во времени, и поэтому это случайность, которая должна произойти. Например, с time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 день, 0:00:01'.
from time import gmtime
from time import strftime
# NOTE: The following resets if it goes over 23:59:59!
strftime("%H:%M:%S", gmtime(125))# Result: '00:02:05'
strftime("%H:%M:%S", gmtime(60*60*24-1))# Result: '23:59:59'
strftime("%H:%M:%S", gmtime(60*60*24))# Result: '00:00:00'
strftime("%H:%M:%S", gmtime(666777))# Result: '17:12:57'# Wrong
он потерпит неудачу, если дельта меньше секунды:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
JFS
1
Для всех остальных: в without ':0>8':примере отсутствуют ведущие 0. {:0>8}нулевые площадки слева от 8 нулей.
TankorSmash
2
В python 3.5.2 я получаю ошибку TypeError. Я форматирую time.time()-startпеременную. Любое понимание? TypeError: non-empty format string passed to object.__format__
medley56
Я попытался использовать datetime.now()вместо того, time.time()чтобы сгенерировать объект timedelta, и я получил ту же ошибку.
medley56
@ medley56 При использовании Python3, вам нужно использовать , str()если вы собираетесь использовать формат , такие как 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Проверьте этот ответ для получения дополнительной информации.
Берриэль
22
Это мой быстрый трюк:
from humanfriendly import format_timespan
secondsPassed =1302
format_timespan(secondsPassed)# '21 minutes and 42 seconds'
Вместо этого 1вы можете использовать любое число больше 0. Здесь мы используем тот факт, что datetime.fromordinalвсегда будет возвращать datetimeобъект с timeкомпонентом, равным нулю.
def sec2time(sec, n_msec=3):''' Convert seconds to 'D days, HH:MM:SS.FFF' '''if hasattr(sec,'__len__'):return[sec2time(s)for s in sec]
m, s = divmod(sec,60)
h, m = divmod(m,60)
d, h = divmod(h,24)if n_msec >0:
pattern ='%%02d:%%02d:%%0%d.%df'%(n_msec+3, n_msec)else:
pattern = r'%02d:%02d:%02d'if d ==0:return pattern %(h, m, s)return('%d days, '+ pattern)%(d, h, m, s)
dateutil.relativedeltaЭто удобно, если вам нужно получить доступ к часам, минутам и секундам, а также поплавкам. datetime.timedeltaне предоставляет аналогичный интерфейс.
from dateutil.relativedelta import relativedelta
rt = relativedelta(seconds=5440)print(rt.seconds)print('{:02d}:{:02d}:{:02d}'.format(
int(rt.hours), int(rt.minutes), int(rt.seconds)))
Я получаю разные результаты от вашего, что заставляет меня думать, что у вас есть опечатка. Вы, вероятно, хотели использовать seconds=5440вместо seconds=5540. Мне нравится ваш ответ, хотя!
JL
2
часы (ч), рассчитанные делением на пол (на //) секунд на 3600 (60 мин / ч * 60 с / мин)
минуты (м), рассчитанные делением на пол оставшихся секунд (остаток от часового расчета,%) на 60 (60 сек / мин)
аналогично, секунд (ы) по оставшимся часам и минутам.
Отдых это просто форматирование строки!
def hms(seconds):
h = seconds //3600
m = seconds %3600//60
s = seconds %3600%60return'{:02d}:{:02d}:{:02d}'.format(h, m, s)print(hms(7500))# Should print 02h05m00s
Хотя этот код может обеспечить решение вопроса ОП, лучше добавить контекст относительно того, почему / как он работает. Это может помочь будущим пользователям учиться и применять эти знания в своем собственном коде. Вы также, вероятно, получите положительные отзывы от пользователей в виде откликов, когда код объясняется.
borchvm
2
Только что, спасибо @borchvm за указание!
Сэм
-2
Вы можете разделить секунды на 60, чтобы получить минуты
import time
seconds = time.time()
minutes = seconds /60print(minutes)
Когда вы разделите его снова на 60, вы получите часы
Ответы:
Вы можете использовать
datetime.timedelta
функцию:источник
str(datetime.timedelta(seconds=60*60*24+1))
='1 day, 0:00:01'
str(datetime.timedelta(seconds=round(666666.55)))
правильно отображает дни; подавляет десятичные секунды.timedelta
не является безопасным при переполнении и не может правильно выполнять математические операции, например,str(timedelta(hours=8) - timedelta(hours=10))
результат'-1 day, 22:00:00'
и целочисленное решение как раз для тех ситуаций, где вам нужно'-02:00:00'
.Используя
divmod()
функцию, которая выполняет только одно деление для получения как частного, так и остатка, вы можете очень быстро получить результат, выполнив всего две математические операции:А затем используйте форматирование строки, чтобы преобразовать результат в желаемый результат:
источник
'%d:%02dmn' % (seconds / 60, seconds % 60)
d, h = divmod(h, 24)
.m, d = divmod(m, 31)
. Ой, нет, ты не можешь. Хуже того, ваш код будет неправильным, если в игру вступят дополнительные секунды. Короче говоря: используйтеtimedelta
и не связывайтесь с календарем, он вас укусит.timedelta
справляется с високосными секундами? Я подозреваю, что нет. Существует множество приложений, в которых эта простая математика более чем достаточна.str(timedelta(hours=8) - timedelta(hours=10))
результат '-1 день, 22:00:00', так что ... idk, если он работает с високосными секундами, но не работает с отрицательными числами.Я не могу назвать это простым способом (по крайней мере, я не могу вспомнить синтаксис), но возможно использовать time.strftime , который дает больше контроля над форматированием:
gmtime используется для преобразования секунд в специальный формат кортежа, который
strftime()
требуется.источник
time.strftime('%d %H:%M:%S', time.gmtime(1))
=> '1 день, 0:00:01'.С помощью
datetime
:С
':0>8'
форматом:Без
':0>8'
формата:Использование
time
:источник
"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
without ':0>8':
примере отсутствуют ведущие 0.{:0>8}
нулевые площадки слева от 8 нулей.time.time()-start
переменную. Любое понимание?TypeError: non-empty format string passed to object.__format__
datetime.now()
вместо того,time.time()
чтобы сгенерировать объект timedelta, и я получил ту же ошибку.str()
если вы собираетесь использовать формат , такие как0>8
:"{:0>8}".format(str(datetime.timedelta(seconds=666777)))
. Проверьте этот ответ для получения дополнительной информации.Это мой быстрый трюк:
Для получения дополнительной информации посетите: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan
источник
Если вам нужно получить
datetime.time
значение, вы можете использовать этот трюк:Вы не можете добавить
timedelta
кtime
, но можете добавить егоdatetime
.UPD : еще один вариант той же техники:
Вместо этого
1
вы можете использовать любое число больше 0. Здесь мы используем тот факт, чтоdatetime.fromordinal
всегда будет возвращатьdatetime
объект сtime
компонентом, равным нулю.источник
Вот так я и получил.
Некоторые примеры:
источник
str(datetime.timedelta(seconds=666))
666.0
и666.1
значений.Следующий набор работал для меня.
источник
dateutil.relativedelta
Это удобно, если вам нужно получить доступ к часам, минутам и секундам, а также поплавкам.datetime.timedelta
не предоставляет аналогичный интерфейс.Печать
источник
seconds=5440
вместоseconds=5540
. Мне нравится ваш ответ, хотя!часы (ч), рассчитанные делением на пол (на //) секунд на 3600 (60 мин / ч * 60 с / мин)
минуты (м), рассчитанные делением на пол оставшихся секунд (остаток от часового расчета,%) на 60 (60 сек / мин)
аналогично, секунд (ы) по оставшимся часам и минутам.
Отдых это просто форматирование строки!
источник
Вы можете разделить секунды на 60, чтобы получить минуты
Когда вы разделите его снова на 60, вы получите часы
источник
PS мой код непрофессиональный
источник