Ini adalah cara terbaik, IMHO, karena Anda dapat menggunakan aritmatika pada timedelta dan objek datetime apa pun.
Matthew Schinckel
13
Ini berfungsi selama beberapa hari: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
hyprnick
3
str(datetime.timedelta(seconds=round(666666.55)))membuat hari dengan benar; menekan detik desimal.
CPBL
1
timedeltatidak overflow aman dan tidak dapat melakukan operasi matematika dengan benar, misalnya str(timedelta(hours=8) - timedelta(hours=10))hasilnya '-1 day, 22:00:00'dan solusi berbasis integer tepat untuk situasi di mana Anda butuhkan '-02:00:00'.
cprn
1
+1. Jawaban ini dapat dimodifikasi dengan sangat mudah. Misalnya, jika Anda ingin menghilangkan bidang saat mencetak, gunakan ini: stackoverflow.com/questions/7999935/…
eric_kernfeld
616
Dengan menggunakan divmod()fungsi, yang hanya melakukan satu divisi untuk menghasilkan hasil bagi dan sisanya, Anda dapat memiliki hasilnya dengan sangat cepat dengan hanya dua operasi matematika:
m, s = divmod(seconds,60)
h, m = divmod(m,60)
Dan kemudian gunakan pemformatan string untuk mengubah hasil menjadi output yang Anda inginkan:
print('{:d}:{:02d}:{:02d}'.format(h, m, s))# Python 3print(f'{h:d}:{m:02d}:{s:02d}')# Python 3.6+
Jika Anda lebih suka operator daripada fungsi, gunakan modulo; misalnya (hanya beberapa menit / detik):'%d:%02dmn' % (seconds / 60, seconds % 60)
bufh
18
Dan Anda dapat memperpanjang untuk hari: d, h = divmod(h, 24).
Mark Ransom
14
@ Markarkom: dan kemudian ke bulan m, d = divmod(m, 31). Aduh, tidak, kamu tidak bisa. Lebih buruk lagi, kode Anda akan salah jika lompatan detik masuk ke dalam permainan. Singkat cerita: gunakan timedeltadan jangan main-main dengan kalender, itu akan menggigit Anda.
4
@Tibo tidak timedeltaberurusan dengan detik kabisat? Saya kira tidak. Ada banyak aplikasi di mana matematika sederhana ini lebih dari cukup.
Mark Ransom
1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))hasilnya adalah '-1 hari, 22:00:00' jadi ... idk jika bekerja dengan detik kabisat tetapi tidak bekerja dengan angka negatif.
cprn
70
Saya hampir tidak dapat menyebutkannya dengan cara yang mudah (setidaknya saya tidak dapat mengingat sintaks), tetapi dimungkinkan untuk menggunakan time.strftime , yang memberikan lebih banyak kontrol atas pemformatan:
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 digunakan untuk mengonversi detik ke format tuple khusus yang strftime()memerlukan.
Sayangnya metode ini mulai mengukur hari dari 1 sehingga tidak dirancang untuk mewakili delta waktu, dan karenanya merupakan kecelakaan yang menunggu untuk terjadi. Misalnya dengan time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 hari, 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
gagal jika delta kurang dari satu detik:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs
1
Untuk orang lain: without ':0>8':Contohnya tidak ada 0. {:0>8}nol bantalan di sebelah kiri nol nol.
TankorSmash
2
Dalam python 3.5.2, saya mendapatkan TypeError. Saya memformat time.time()-startvariabel. Adakah wawasan? TypeError: non-empty format string passed to object.__format__
medley56
Saya mencoba menggunakan datetime.now()alih-alih time.time()untuk menghasilkan objek timedelta saya dan saya mendapatkan kesalahan yang sama.
medley56
@ medley56 Bila menggunakan Python3, Anda perlu menggunakan str()jika Anda akan menggunakan format seperti 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Periksa jawaban ini untuk info lebih lanjut.
Berriel
22
Ini trik cepat saya:
from humanfriendly import format_timespan
secondsPassed =1302
format_timespan(secondsPassed)# '21 minutes and 42 seconds'
Alih-alih 1Anda dapat menggunakan angka lebih besar dari 0. Di sini kami menggunakan fakta bahwa datetime.fromordinalakan selalu mengembalikan datetimeobjek dengan timekomponen menjadi nol.
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)
Saya mendapatkan hasil yang berbeda dari milik Anda, yang membuat saya berpikir Anda salah ketik. Anda mungkin dimaksudkan untuk menggunakan seconds=5440bukan seconds=5540. Saya suka jawaban Anda!
JL
2
jam (h) dihitung berdasarkan pembagian lantai (dengan //) detik oleh 3600 (60 mnt / jam * 60 dt / mnt)
menit (m) dihitung berdasarkan pembagian lantai detik yang tersisa (sisa dari perhitungan jam, dengan%) sebesar 60 (60 detik / mnt)
sama halnya, detik dengan sisa perhitungan jam dan menit.
Istirahat hanyalah pemformatan string!
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
Meskipun kode ini dapat memberikan solusi untuk pertanyaan OP, lebih baik menambahkan konteks mengapa / cara kerjanya. Ini dapat membantu pengguna di masa depan belajar, dan menerapkan pengetahuan itu ke kode mereka sendiri. Anda juga cenderung mendapat umpan balik positif dari pengguna dalam bentuk upvotes, ketika kode dijelaskan.
borchvm
2
Baru saja melakukannya, Terima kasih @borchvm untuk menunjukkan!
Sam
-2
Anda dapat membagi detik dengan 60 untuk mendapatkan menit
import time
seconds = time.time()
minutes = seconds /60print(minutes)
Ketika Anda membaginya dengan 60 lagi, Anda akan mendapatkan jam
Jawaban:
Anda dapat menggunakan
datetime.timedelta
fungsi:sumber
str(datetime.timedelta(seconds=60*60*24+1))
='1 day, 0:00:01'
str(datetime.timedelta(seconds=round(666666.55)))
membuat hari dengan benar; menekan detik desimal.timedelta
tidak overflow aman dan tidak dapat melakukan operasi matematika dengan benar, misalnyastr(timedelta(hours=8) - timedelta(hours=10))
hasilnya'-1 day, 22:00:00'
dan solusi berbasis integer tepat untuk situasi di mana Anda butuhkan'-02:00:00'
.Dengan menggunakan
divmod()
fungsi, yang hanya melakukan satu divisi untuk menghasilkan hasil bagi dan sisanya, Anda dapat memiliki hasilnya dengan sangat cepat dengan hanya dua operasi matematika:Dan kemudian gunakan pemformatan string untuk mengubah hasil menjadi output yang Anda inginkan:
sumber
'%d:%02dmn' % (seconds / 60, seconds % 60)
d, h = divmod(h, 24)
.m, d = divmod(m, 31)
. Aduh, tidak, kamu tidak bisa. Lebih buruk lagi, kode Anda akan salah jika lompatan detik masuk ke dalam permainan. Singkat cerita: gunakantimedelta
dan jangan main-main dengan kalender, itu akan menggigit Anda.timedelta
berurusan dengan detik kabisat? Saya kira tidak. Ada banyak aplikasi di mana matematika sederhana ini lebih dari cukup.str(timedelta(hours=8) - timedelta(hours=10))
hasilnya adalah '-1 hari, 22:00:00' jadi ... idk jika bekerja dengan detik kabisat tetapi tidak bekerja dengan angka negatif.Saya hampir tidak dapat menyebutkannya dengan cara yang mudah (setidaknya saya tidak dapat mengingat sintaks), tetapi dimungkinkan untuk menggunakan time.strftime , yang memberikan lebih banyak kontrol atas pemformatan:
gmtime digunakan untuk mengonversi detik ke format tuple khusus yang
strftime()
memerlukan.sumber
time.strftime('%d %H:%M:%S', time.gmtime(1))
=> '1 hari, 0:00:01'.Menggunakan
datetime
:Dengan
':0>8'
format:Tanpa
':0>8'
format:Menggunakan
time
:sumber
"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
without ':0>8':
Contohnya tidak ada 0.{:0>8}
nol bantalan di sebelah kiri nol nol.time.time()-start
variabel. Adakah wawasan?TypeError: non-empty format string passed to object.__format__
datetime.now()
alih-alihtime.time()
untuk menghasilkan objek timedelta saya dan saya mendapatkan kesalahan yang sama.str()
jika Anda akan menggunakan format seperti0>8
:"{:0>8}".format(str(datetime.timedelta(seconds=666777)))
. Periksa jawaban ini untuk info lebih lanjut.Ini trik cepat saya:
Untuk info lebih lanjut Kunjungi: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan
sumber
Jika Anda perlu mendapatkan
datetime.time
nilai, Anda dapat menggunakan trik ini:Anda tidak dapat menambahkan
timedelta
untuktime
, tetapi dapat menambahkannya kedatetime
.UPD : Variasi lain dari teknik yang sama:
Alih-alih
1
Anda dapat menggunakan angka lebih besar dari 0. Di sini kami menggunakan fakta bahwadatetime.fromordinal
akan selalu mengembalikandatetime
objek dengantime
komponen menjadi nol.sumber
Ini adalah bagaimana saya mendapatkannya.
Beberapa contoh:
sumber
str(datetime.timedelta(seconds=666))
666.0
dan666.1
nilai.Set berikut bekerja untuk saya.
sumber
dateutil.relativedelta
nyaman jika Anda perlu mengakses jam, menit dan detik juga mengapung.datetime.timedelta
tidak menyediakan antarmuka yang sama.Cetakan
sumber
seconds=5440
bukanseconds=5540
. Saya suka jawaban Anda!jam (h) dihitung berdasarkan pembagian lantai (dengan //) detik oleh 3600 (60 mnt / jam * 60 dt / mnt)
menit (m) dihitung berdasarkan pembagian lantai detik yang tersisa (sisa dari perhitungan jam, dengan%) sebesar 60 (60 detik / mnt)
sama halnya, detik dengan sisa perhitungan jam dan menit.
Istirahat hanyalah pemformatan string!
sumber
Anda dapat membagi detik dengan 60 untuk mendapatkan menit
Ketika Anda membaginya dengan 60 lagi, Anda akan mendapatkan jam
sumber
PS Kode saya tidak profesional
sumber