Konversikan timedelta menjadi hari, jam, dan menit

242

Saya punya timedelta. Saya ingin hari, jam dan menit dari itu - baik sebagai tuple atau kamus ... Saya tidak sibuk.

Saya pasti telah melakukan ini selusin kali dalam selusin bahasa selama bertahun-tahun, tetapi Python biasanya memiliki jawaban sederhana untuk semuanya, jadi saya pikir saya akan bertanya di sini sebelum mengeluarkan beberapa matematika sederhana (belum bertele-tele) yang memuakkan.

Tuan Fooz memunculkan poin yang bagus.

Saya sedang berurusan dengan "daftar" (sedikit seperti daftar ebay) di mana masing-masing memiliki durasi. Saya mencoba mencari waktu yang tersisa dengan melakukanwhen_added + duration - now

Apakah saya benar mengatakan bahwa tidak akan menjelaskan DST? Jika tidak, apa cara paling sederhana untuk menambah / mengurangi satu jam?

Oli
sumber
Jika hanya untuk mendapatkannya sebagai string dalam format HH: mm: ss, katakan "0:19:37" dari timedeltaobjek "datetime.timedelta (seconds = 1177)" : cukup gunakan str ()
Peter Mortensen

Jawaban:

343

Jika Anda memiliki datetime.timedeltanilai td, td.dayssudah memberi Anda "hari" yang Anda inginkan. timedeltanilai menjaga fraksi sehari sebagai detik (tidak langsung berjam-jam atau menit) sehingga Anda memang harus melakukan "matematika sederhana yang memuakkan", misalnya:

def days_hours_minutes(td):
    return td.days, td.seconds//3600, (td.seconds//60)%60
Alex Martelli
sumber
1
Ingatlah bahwa jika tdnegatif, -1 // 3600adalah -1.
jcrs
4
mengapa //? bukannya /
Mohammed Shareef C
10
//digunakan bukan /untuk mendapatkan bilangan bulat, bukan float. //adalah operator divisi lantai: "divisi yang menghasilkan bilangan bulat disesuaikan ke kiri di garis bilangan", lihat di sini .
Eerik Sven Puudist
1
@ EerikSvenPuudist seperti yang jcrsditunjukkan, -1//3600adalah -1, jadi mengapa tidak menggunakan int(td.seconds/3600)sebagai gantinya mengubah -1detik menjadi 0jam daripada 1jam mundur?
simpleuser
bagaimana dengan menambahkan detik yang tersisa juga? days, hours, minutes = x.days, x.seconds // 3600, x.seconds %3600//60dan kemudian seconds = x.seconds - hours*3600 - minutes*60
raphael
73

Ini sedikit lebih kompak, Anda mendapatkan jam, menit, dan detik dalam dua baris.

days = td.days
hours, remainder = divmod(td.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# If you want to take into account fractions of a second
seconds += td.microseconds / 1e6
mberacochea
sumber
7
tidak benar jika td.daysbukan nol. Kamu butuh hours += td.days*24. Jika Anda ingin memperhitungkan fraksi akun per detik (OP tidak); seconds += td.microseconds / 1e6bisa digunakan.
jfs
30
days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

Sedangkan untuk DST, saya pikir yang terbaik adalah mengubah kedua datetimeobjek menjadi detik. Dengan cara ini sistem menghitung DST untuk Anda.

>>> m13 = datetime(2010, 3, 13, 8, 0, 0)  # 2010 March 13 8:00 AM
>>> m14 = datetime(2010, 3, 14, 8, 0, 0)  # DST starts on this day, in my time zone
>>> mktime(m14.timetuple()) - mktime(m13.timetuple())     # difference in seconds
82800.0
>>> _/3600                                                # convert to hours
23.0
Jason Orendorff
sumber
1
mktime()mungkin gagal jika zona waktu lokal memiliki offset utc yang berbeda pada waktu yang berbeda (banyak yang melakukannya) - Anda dapat menggunakan pytzmodul untuk mendapatkan akses ke basis data tz dengan cara deteministik portabel. Juga, waktu setempat mungkin ambigu (kemungkinan 50% kesalahan) - Anda memerlukan beberapa info tambahan untuk mengaburkan misalnya, sering (tidak selalu) tanggal dalam file log bersifat monoton . Lihat Bagaimana saya bisa mengurangi satu hari dari tanggal python? yang mungkin harus berurusan dengan masalah serupa.
jfs
7

Saya tidak mengerti

days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

bagaimana dengan ini

days, hours, minutes = td.days, td.seconds // 3600, td.seconds % 3600 / 60.0

Anda mendapatkan menit dan detik sebagai float.

bel pintu
sumber
0

Saya menggunakan yang berikut ini:

delta = timedelta()
totalMinute, second = divmod(delta.seconds, 60)
hour, minute = divmod(totalMinute, 60)
print(f"{hour}h{minute:02}m{second:02}s")
Mathieu CAROFF
sumber
-2

timedeltas memiliki daysdan secondsatribut .. Anda dapat mengonversinya sendiri dengan mudah.

Jochen Ritzel
sumber