Як перетворити секунди на години, хвилини та секунди?


470

У мене є функція, яка повертає інформацію за секунди, але мені потрібно зберігати цю інформацію в годинах: хвилинах: секундах.

Чи є простий спосіб перетворити секунди в цей формат на Python?


20
Зворотність цієї проблеми можна знайти в розділі Як перетворити часовий рядок H: MM: SS в секунди на Python?
обіймає

Відповіді:


762

Ви можете використовувати datetime.timedeltaфункцію:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'

8
Це найкращий спосіб, IMHO, оскільки ви можете потім використовувати арифметику на timedelta та будь-які об'єкти дати.
Меттью Шинкель

12
Це працює протягом декількох днів: 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

614

Використовуючи 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)
bufh

18
І ви можете продовжити його дні: d, h = divmod(h, 24).
Марк Рансом

14
@MarkRansom: а потім до місяців m, d = divmod(m, 31). Ооо, ні, ви не можете. Гірше, що ваш код буде неправильним, якщо в гру потраплять високосні секунди. Довга коротка історія: використовуйте timedeltaі не возиться з календарем, він вас вкусить.

4
@Tibo має timedeltaсправу з високосними секундами? Підозрюю, що ні. Існує безліч застосувань, де цієї простої математики більш ніж достатньо.
Марк Викуп

1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))результат "-1 день, 22:00:00", тому ... idk, якщо він працює з високосними секундами, але він не працює з від'ємними числами.
cprn

69

Я важко назвати цей простий спосіб (принаймні, не можу згадати синтаксис), але можна використовувати time.strearch , який дає більше контролю над форматуванням:

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'.
Riaz Rizvi

40

Використання 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))). Перевірте цю відповідь для отримання додаткової інформації.
Берріель

21

Це мій швидкий трюк:

from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'

Для отримання додаткової інформації відвідайте: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan


Ви не знаєте, як довго я шукав саме цю відповідь. Дуже дякую. Я б хотів, щоб я міг дати вам більше +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компонент якого дорівнює нулю.


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

@RiazRizvi дає послідовну довжину рядка протягом мікросекунд для 666.0та 666.1значень.
anatoly techtonik

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

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, ви отримаєте години


-3

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

PS Мій код непрофесійний


2
ей, питання задайте формат у годинах: хв: сек, а не простий поділ ..
StupidWolf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.