ฉันจะแปลงวินาทีเป็นชั่วโมงนาทีและวินาทีได้อย่างไร


471

ฉันมีฟังก์ชั่นที่คืนค่าข้อมูลเป็นวินาที แต่ฉันต้องการเก็บข้อมูลนั้นเป็นชั่วโมง: นาที: วินาที

มีวิธีง่าย ๆ ในการแปลงวินาทีเป็นรูปแบบนี้ใน Python หรือไม่?


20
สามารถพบการผกผันของปัญหานี้ได้ที่วิธีแปลงสตริงเวลา H: MM: SS เป็นวินาทีใน Python
ฮิวจ์

คำตอบ:


763

คุณสามารถใช้datetime.timedeltaฟังก์ชั่น:

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

9
นี่เป็นวิธีที่ดีที่สุด IMHO ในขณะที่คุณสามารถใช้เลขคณิตกับ timedelta และวัตถุ datetime ใด ๆ
Matthew Schinckel

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

615

ด้วยการใช้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)และคุณสามารถขยายไปยังวันที่:
Mark Ransom

14
@MarkRansom: m, d = divmod(m, 31)แล้วเดือน Oooops ไม่คุณทำไม่ได้ รหัสของคุณจะผิดถ้าเผ่นวินาทีเข้ามาในเกม เรื่องสั้นสั้น ๆ : ใช้timedeltaและไม่ยุ่งกับปฏิทินมันจะกัดคุณ

4
@Tibo timedeltaจัดการกับเผ่นวินาทีหรือไม่ ฉันไม่สงสัย มีแอปพลิเคชั่นมากมายที่คณิตศาสตร์อย่างง่ายนี้เพียงพอมากกว่า
Mark Ransom

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ใช้ในการแปลงวินาทีเป็นรูปแบบ tuple พิเศษที่strftime()ต้องการ

หมายเหตุ: ตัดทอนหลังจาก 23:59:59 น


คำตอบมีให้ที่นี่จริง ๆ - stackoverflow.com/questions/1384406/ …
Anatoly techtonik

13
น่าเสียดายที่วิธีนี้เริ่มต้นการวัดจำนวนวันตั้งแต่วันที่ 1 ดังนั้นจึงไม่ได้ออกแบบมาเพื่อเป็นตัวแทนของเดลต้าเวลาและดังนั้นจึงเป็นอุบัติเหตุที่รอให้เกิดขึ้น ตัวอย่างเช่นกับ time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 วัน, 0:00:01'
Riaz Rizvi

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)))ตรวจสอบคำตอบนี้สำหรับข้อมูลเพิ่มเติม
Berriel

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


คุณไม่รู้ว่าฉันกำลังมองหาคำตอบนี้นานแค่ไหน ขอบคุณมาก. ฉันหวังว่าฉันจะให้มากกว่า +1
Peppa

9

หากคุณต้องการความdatetime.timeคุ้มค่าคุณสามารถใช้เคล็ดลับนี้:

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

คุณไม่สามารถเพิ่มtimedeltaไปแต่สามารถเพิ่มไปยังtimedatetime

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

ชั่วโมง (h) คำนวณโดยการแบ่งชั้น (โดย //) วินาทีโดย 3600 (60 นาที / ชม. * 60 วินาที / นาที)

นาที (m) คำนวณโดยการแบ่งชั้นของวินาทีที่เหลือ (ส่วนที่เหลือจากการคำนวณชั่วโมงโดย%) 60 (60 วินาที / นาที)

ในทำนองเดียวกันวินาที (s) โดยส่วนที่เหลือของการคำนวณชั่วโมงและนาที

ส่วนที่เหลือเป็นเพียงการจัดรูปแบบสตริง!

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

ในขณะที่รหัสนี้อาจให้คำตอบสำหรับคำถามของ OP แต่ก็ควรเพิ่มบริบทว่าทำไมมันถึงทำงานอย่างไร สิ่งนี้สามารถช่วยผู้ใช้ในอนาคตเรียนรู้และนำความรู้นั้นไปใช้กับรหัสของตนเอง คุณมีแนวโน้มที่จะได้รับการตอบรับเชิงบวกจากผู้ใช้ในรูปแบบ upvotes เมื่อมีการอธิบายรหัส
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
เฮ้คำถามถามหารูปแบบในชั่วโมง: นาที: วินาทีไม่ใช่การแบ่งง่าย ..
27826
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.