Làm cách nào để chuyển đổi giây thành giờ, phút và giây?


Câu trả lời:


764

Bạn có thể sử dụng datetime.timedeltachức năng:

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

9
Đây là cách tốt nhất, IMHO, khi đó bạn có thể sử dụng số học trên timedelta và bất kỳ đối tượng datetime nào.
Matthew Schinckel

13
Điều này hoạt động trong nhiều ngày: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
hyprnick

3
str(datetime.timedelta(seconds=round(666666.55)))kết xuất chính xác ngày; thay thế số thập phân giây.
CPBL

1
timedeltakhông tràn an toàn và không thể thực hiện chính xác các phép toán, ví dụ str(timedelta(hours=8) - timedelta(hours=10))kết quả là '-1 day, 22:00:00'và giải pháp dựa trên số nguyên chính xác cho những tình huống mà bạn cần '-02:00:00'.
cprn

1
+1. Câu trả lời này có thể được sửa đổi rất dễ dàng. Ví dụ: nếu bạn muốn bỏ qua một trường khi in, hãy sử dụng: stackoverflow.com/questions/7999935/
dọa

616

Bằng cách sử dụng divmod()hàm, chỉ thực hiện một phép chia duy nhất để tạo ra cả thương số và phần còn lại, bạn có thể có kết quả rất nhanh chỉ với hai phép toán:

m, s = divmod(seconds, 60)
h, m = divmod(m, 60)

Và sau đó sử dụng định dạng chuỗi để chuyển đổi kết quả thành đầu ra mong muốn của bạn:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+

2
Nếu bạn thích toán tử hơn các hàm, hãy sử dụng modulo; ví dụ (chỉ vài phút / giây):'%d:%02dmn' % (seconds / 60, seconds % 60)
bufh

18
Và bạn có thể kéo dài nó đến ngày : d, h = divmod(h, 24).
Đánh dấu tiền chuộc

14
@MarkRansom: và sau đó đến tháng m, d = divmod(m, 31). Rất tiếc, không, bạn không thể. Tệ hơn, mã của bạn sẽ sai nếu bước nhảy vọt vào trò chơi. Câu chuyện dài ngắn: sử dụng timedeltavà đừng lộn xộn với lịch, nó sẽ cắn bạn.

4
@Tibo có timedeltađối phó với giây nhuận? Tôi nghi ngờ là không. Có rất nhiều ứng dụng mà toán học đơn giản này là quá đủ.
Đánh dấu tiền chuộc

1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))kết quả là '-1 ngày, 22:00:00' vì vậy ... idk nếu nó hoạt động với giây nhuận nhưng nó không hoạt động với các số âm.
cprn

70

Tôi khó có thể đặt tên theo cách dễ dàng (ít nhất là tôi không thể nhớ cú pháp), nhưng có thể sử dụng time.strftime , giúp kiểm soát định dạng nhiều hơn:

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 được sử dụng để chuyển đổi giây sang định dạng tuple đặc biệt strftime()yêu cầu.

Lưu ý: Cắt ngắn sau 23:59:59


Chà, câu trả lời thực sự được cung cấp ở đây - stackoverflow.com/questions/1384406/
trộm

13
Thật không may, phương pháp này bắt đầu đo ngày từ 1 vì vậy nó không được thiết kế để thể hiện đồng bằng thời gian và do đó, đây là một tai nạn đang chờ xảy ra. Ví dụ với time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 ngày, 0:00:01'.
Riaz Rizvi

41

Sử dụng datetime:

Với ':0>8'định dạng:

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'

Không có ':0>8'định dạng:

"{}".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'

Sử dụng 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
nó không thành công nếu đồng bằng nhỏ hơn một giây:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs

1
Đối với mọi người khác: without ':0>8':Ví dụ thiếu một số 0 hàng đầu {:0>8}ở bên trái 8 số không.
TankorSmash

2
Trong python 3.5.2, tôi nhận được TypeError. Tôi đang định dạng một time.time()-startbiến. Bất kỳ cái nhìn sâu sắc? TypeError: non-empty format string passed to object.__format__
medley56

Tôi đã thử sử dụng datetime.now()thay vì time.time()tạo đối tượng timedelta của mình và tôi cũng gặp lỗi tương tự.
medley56

@ medley56 Khi sử dụng Python3, bạn cần sử dụng str()nếu bạn định sử dụng một định dạng như 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Kiểm tra câu trả lời này để biết thêm.
Berriel


9

Nếu bạn cần nhận được datetime.timegiá trị, bạn có thể sử dụng thủ thuật này:

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

Bạn không thể thêm timedeltavào time, nhưng có thể thêm nó vào datetime.

CẬP NHẬT : Một biến thể khác của cùng một kỹ thuật:

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

Thay vì 1bạn có thể sử dụng bất kỳ số nào lớn hơn 0. Ở đây chúng tôi sử dụng thực tế là datetime.fromordinalsẽ luôn trả về datetimeđối tượng có timethành phần bằng không.


6

Đây là cách tôi có nó.

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)

Vài ví dụ:

$ 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
Lợi thế của điều này so với câu trả lời ở trên là gì? str(datetime.timedelta(seconds=666))
Riaz Rizvi

@RiazRizvi cung cấp độ dài chuỗi nhất quán cho micro giây 666.0666.1giá trị.
anatoly techtonik

6

Các bộ sau đây làm việc cho tôi.

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.relativedeltathuận tiện nếu bạn cần truy cập hàng giờ, phút và giây như phao. datetime.timedeltakhông cung cấp một giao diện tương tự.

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

Bản in

40.0
01:30:40

1
Tôi đang nhận được đầu ra khác với bạn, điều này khiến tôi nghĩ rằng bạn có một lỗi đánh máy. Bạn có thể có nghĩa là để sử dụng seconds=5440thay vì seconds=5540. Tôi thích câu trả lời của bạn, mặc dù!
JL

2

giờ (h) được tính bằng cách chia sàn (bằng //) giây bằng 3600 (60 phút / giờ * 60 giây / phút)

phút (m) được tính bằng cách chia tầng của các giây còn lại (phần còn lại từ tính toán giờ, theo%) cho 60 (60 giây / phút)

tương tự, giây (s) bằng phần còn lại của giờ và phút tính toán.

Phần còn lại chỉ là định dạng chuỗi!

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

Mặc dù mã này có thể cung cấp giải pháp cho câu hỏi của OP, tốt hơn hết là thêm ngữ cảnh vào lý do tại sao / cách thức hoạt động của nó. Điều này có thể giúp người dùng trong tương lai tìm hiểu và áp dụng kiến ​​thức đó vào mã của riêng họ. Bạn cũng có thể có phản hồi tích cực từ người dùng dưới dạng upvote, khi mã được giải thích.
borchvm

2
Vừa mới làm, Cảm ơn @borchvm đã chỉ ra!
Sam

-2

Bạn có thể chia giây cho 60 để có được số phút

import time
seconds = time.time()
minutes = seconds / 60
print(minutes)

Khi bạn chia nó cho 60 lần nữa, bạn sẽ nhận được số giờ


-3

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

PS Mã của tôi không chuyên nghiệp


2
này, câu hỏi yêu cầu một định dạng trong giờ: phút: giây, không phải là một phép chia đơn giản ..
StoolWolf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.