Как я могу преобразовать секунды в часы, минуты и секунды?

472

У меня есть функция, которая возвращает информацию в секундах, но мне нужно хранить эту информацию в часах: минутах: секундах.

Есть ли простой способ конвертировать секунды в этот формат в Python?

Specto
источник
20
Обратную сторону
Хьюз

Ответы:

764

Вы можете использовать datetime.timedeltaфункцию:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'
SilentGhost
источник
9
ИМХО, это лучший способ, поскольку вы можете использовать арифметику для timedelta и любых объектов datetime.
Мэтью Шинкель
13
Это работает в течение нескольких дней: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
Hyprnick
3
str(datetime.timedelta(seconds=round(666666.55)))правильно отображает дни; подавляет десятичные секунды.
CPBL
1
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 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+
Брэндон Роудс
источник
2
Если вы предпочитаете операторы над функциями, используйте модуль; например (только минуты / секунды):'%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()требуется.

Примечание: усечения после 23:59:59

анатолий техтоник
источник
Ну, ответ на самом деле здесь - stackoverflow.com/questions/1384406/…
Анатолий techtonik
13
К сожалению, этот метод начинает измерять дни с 1, поэтому он не предназначен для представления разницы во времени, и поэтому это случайность, которая должна произойти. Например, с time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 день, 0:00:01'.
Риаз Ризви
41

С помощью datetime:

С ':0>8'форматом:

from datetime import timedelta

"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Без ':0>8'формата:

"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Использование time:

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
Марцелл
источник
1
он потерпит неудачу, если дельта меньше секунды:"{: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'

Для получения дополнительной информации посетите: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan

doories
источник
Вы не представляете, как долго я искал этот самый ответ. Огромное спасибо. Я хотел бы дать вам больше, чем +1.
Пеппа
9

Если вам нужно получить datetime.timeзначение, вы можете использовать этот трюк:

my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()

Вы не можете добавить timedeltaк time, но можете добавить его datetime.

UPD : еще один вариант той же техники:

my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()

Вместо этого 1вы можете использовать любое число больше 0. Здесь мы используем тот факт, что datetime.fromordinalвсегда будет возвращать datetimeобъект с timeкомпонентом, равным нулю.

MarSoft
источник
6

Вот так я и получил.

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)

Некоторые примеры:

$ sec2time(10, 3)
Out: '00:00:10.000'

$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'

$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'

$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']
подветренный
источник
1
В чем преимущество этого ответа над ответом выше? str(datetime.timedelta(seconds=666))
Риаз Ризви
@RiazRizvi дает согласованную длину строки для микросекунд 666.0и 666.1значений.
анатолий техтоник
6

Следующий набор работал для меня.

def sec_to_hours(seconds):
    a=str(seconds//3600)
    b=str((seconds%3600)//60)
    c=str((seconds%3600)%60)
    d=["{} hours {} mins {} seconds".format(a, b, c)]
    return d


print(sec_to_hours(10000))
# ['2 hours 46 mins 40 seconds']

print(sec_to_hours(60*60*24+105))
# ['24 hours 1 mins 45 seconds']
наивный декодер
источник
3

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)))

Печать

40.0
01:30:40
teekarna
источник
1
Я получаю разные результаты от вашего, что заставляет меня думать, что у вас есть опечатка. Вы, вероятно, хотели использовать seconds=5440вместо seconds=5540. Мне нравится ваш ответ, хотя!
JL
2

часы (ч), рассчитанные делением на пол (на //) секунд на 3600 (60 мин / ч * 60 с / мин)

минуты (м), рассчитанные делением на пол оставшихся секунд (остаток от часового расчета,%) на 60 (60 сек / мин)

аналогично, секунд (ы) по оставшимся часам и минутам.

Отдых это просто форматирование строки!

def hms(seconds):
    h = seconds // 3600
    m = seconds % 3600 // 60
    s = seconds % 3600 % 60
    return '{: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 / 60
print(minutes)

Когда вы разделите его снова на 60, вы получите часы

alosha002
источник
-3

division = 3623 // 3600 #to hours
division2 = 600 // 60 #to minutes
print (division) #write hours
print (division2) #write minutes

PS мой код непрофессиональный

Денис Керстенс Денисик35
источник
2
Привет, вопрос задать формат в часах: мин: сек, а не простое деление ..
StupidWolf