Cara menghitung interval waktu antara dua string waktu

169

Saya memiliki dua kali, waktu mulai dan berhenti, dalam format 10:33:26 (HH: MM: SS). Saya perlu perbedaan antara dua kali. Saya telah mencari melalui dokumentasi untuk Python dan mencari online dan saya akan membayangkan itu ada hubungannya dengan datetime dan / atau modul waktu. Saya tidak bisa membuatnya berfungsi dengan baik dan terus menemukan hanya bagaimana melakukan ini ketika kencan terlibat.

Pada akhirnya, saya perlu menghitung rata-rata dari beberapa durasi waktu. Saya mendapat perbedaan waktu untuk bekerja dan saya menyimpannya dalam daftar. Sekarang saya perlu menghitung rata-rata. Saya menggunakan ekspresi reguler untuk memilah-milah waktu asli dan kemudian melakukan perbedaan.

Untuk rata-rata, haruskah saya mengonversi ke detik dan kemudian rata-rata?

Hannah
sumber
2
Bisakah Anda memposting kode yang sudah Anda coba dan kami bisa mulai dari sana?
Anthony Forloney

Jawaban:

201

Ya, pasti datetimeitulah yang Anda butuhkan di sini. Secara khusus, strptimefungsi, yang mem-parsing string menjadi objek waktu.

from datetime import datetime
s1 = '10:33:26'
s2 = '11:15:49' # for example
FMT = '%H:%M:%S'
tdelta = datetime.strptime(s2, FMT) - datetime.strptime(s1, FMT)

Itu membuat Anda timedeltaobjek yang berisi perbedaan antara dua kali. Anda dapat melakukan apa pun yang Anda inginkan dengan itu, mis. Mengubahnya menjadi detik atau menambahkannya ke yang lain datetime.

Ini akan mengembalikan hasil negatif jika waktu akhir lebih awal dari waktu mulai, misalnya s1 = 12:00:00dan s2 = 05:00:00. Jika Anda ingin kode untuk menganggap interval melintasi tengah malam dalam kasus ini (artinya harus menganggap waktu akhir tidak pernah lebih awal dari waktu mulai), Anda dapat menambahkan baris berikut ke kode di atas:

if tdelta.days < 0:
    tdelta = timedelta(days=0,
                seconds=tdelta.seconds, microseconds=tdelta.microseconds)

(tentu saja Anda perlu memasukkan from datetime import timedeltasuatu tempat). Terima kasih kepada JF Sebastian karena menunjukkan kasus penggunaan ini.

David Z
sumber
Hack waktu negatif tidak akan berfungsi ketika days= -2dan di atas dalam objek tdelta.
CKM
@chreshresh Ya, tetapi daystidak akan pernah bisa menjadi -2 atau kurang tanpa ada informasi tambahan (khususnya, tanggal) di luar apa yang dijelaskan dalam pertanyaan. Sehingga situasinya tidak relevan di sini.
David Z
3
Petunjuk: Untuk mendapatkan delta waktu dalam beberapa detik Anda harus menelepon tdelta.total_seconds().
scai
156

Coba ini - efisien untuk menentukan waktu acara jangka pendek. Jika sesuatu memakan waktu lebih dari satu jam, maka tampilan akhir mungkin akan membutuhkan beberapa format ramah.

import time
start = time.time()

time.sleep(10)  # or do something more productive

done = time.time()
elapsed = done - start
print(elapsed)

Perbedaan waktu dikembalikan sebagai jumlah detik yang berlalu.

Bill Grava
sumber
5
Mengapa ini bukan jawaban yang diterima? Sangat sederhana, ia memberikan nilai yang dapat dibandingkan dengan sesuatu (apakah perintah saya membutuhkan lebih dari 2,5 detik untuk dieksekusi?) Dan itu bekerja di v2.7
Mawg mengatakan mengembalikan Monica
11
@ Mawg Karena tidak menjawab pertanyaan OP. Dia bertanya bagaimana membandingkan dua waktu berbeda yang telah dia miliki dalam format tertentu, bukan bagaimana menghasilkannya dengan menghitung waktu suatu peristiwa dalam kodenya. Mereka masalah yang sangat berbeda.
Natsukane
2
Anda seharusnya tidak menggunakan ini; gunakan waktu monoton sebagai gantinya ( time.monotonic()dengan Python). time.time()dapat mundur (mis., ketika waktu pada mesin berubah, termasuk koreksi NTP).
nemequ
1
Tidak relevan untuk dipertanyakan
patricktokeeffe
14

Berikut adalah solusi yang mendukung menemukan perbedaan bahkan jika waktu akhir kurang dari waktu mulai (lebih dari interval tengah malam) seperti 23:55:00-00:25:00(durasi setengah jam):

#!/usr/bin/env python
from datetime import datetime, time as datetime_time, timedelta

def time_diff(start, end):
    if isinstance(start, datetime_time): # convert to datetime
        assert isinstance(end, datetime_time)
        start, end = [datetime.combine(datetime.min, t) for t in [start, end]]
    if start <= end: # e.g., 10:33:26-11:15:49
        return end - start
    else: # end < start e.g., 23:55:00-00:25:00
        end += timedelta(1) # +day
        assert end > start
        return end - start

for time_range in ['10:33:26-11:15:49', '23:55:00-00:25:00']:
    s, e = [datetime.strptime(t, '%H:%M:%S') for t in time_range.split('-')]
    print(time_diff(s, e))
    assert time_diff(s, e) == time_diff(s.time(), e.time())

Keluaran

0:42:23
0:30:00

time_diff()mengembalikan objek timedelta yang dapat Anda lewati (sebagai bagian dari urutan) ke mean()fungsi langsung misalnya:

#!/usr/bin/env python
from datetime import timedelta

def mean(data, start=timedelta(0)):
    """Find arithmetic average."""
    return sum(data, start) / len(data)

data = [timedelta(minutes=42, seconds=23), # 0:42:23
        timedelta(minutes=30)] # 0:30:00
print(repr(mean(data)))
# -> datetime.timedelta(0, 2171, 500000) # days, seconds, microseconds

The mean()Hasilnya juga timedelta()objek yang Anda dapat dikonversi ke detik ( td.total_seconds()metode (sejak Python 2,7)), jam ( td / timedelta(hours=1)(Python 3)), dll

jfs
sumber
@ JF Saya ingin tahu apakah fungsi statistik mean dan varians bekerja langsung dengan objek timedelta sekarang? Adakah pemikiran tentang itu? Juga, bantuan apa pun untuk menghitung varian objek timedelta akan berguna.
CKM
@chresh: tidak didukung. Anda dapat mengonversi ke detik / mikrodetik untuk menghitung statistik matematika dari timedeltas.
jfs
11

Struktur yang mewakili perbedaan waktu dalam Python disebut timedelta . Jika Anda memiliki start_timedan end_timesebagai datetimetipe, Anda dapat menghitung perbedaan menggunakan -operator seperti:

diff = end_time - start_time

Anda harus melakukan ini sebelum mengonversi ke format string particualr (mis. sebelum start_time.strftime (...)). Jika Anda sudah memiliki representasi string, Anda perlu mengubahnya kembali ke waktu / datetime dengan menggunakan metode strptime .

dzida
sumber
10

Situs ini mengatakan untuk mencoba:

import datetime as dt
start="09:35:23"
end="10:23:00"
start_dt = dt.datetime.strptime(start, '%H:%M:%S')
end_dt = dt.datetime.strptime(end, '%H:%M:%S')
diff = (end_dt - start_dt) 
diff.seconds/60 

Forum ini menggunakan time.mktime ()

Kyra
sumber
Pastikan bahwa jika Anda menggunakan% p (AM / PM) yang Anda gunakan% I (12 jam) alih-alih% H (24 jam): docs.python.org/2/library/…
Andrew
6

Saya suka bagaimana orang ini melakukannya - https://amalgjose.com/2015/02/19/python-code-for-calculating-the-difference-between-two-time-stamps . Tidak yakin apakah ada kontra.

Tapi terlihat rapi untuk saya :)

from datetime import datetime
from dateutil.relativedelta import relativedelta

t_a = datetime.now()
t_b = datetime.now()

def diff(t_a, t_b):
    t_diff = relativedelta(t_b, t_a)  # later/end time comes first!
    return '{h}h {m}m {s}s'.format(h=t_diff.hours, m=t_diff.minutes, s=t_diff.seconds)

Mengenai pertanyaan Anda masih perlu menggunakan datetime.strptime()seperti orang lain katakan sebelumnya.

antonavy
sumber
3

Coba ini

import datetime
import time
start_time = datetime.datetime.now().time().strftime('%H:%M:%S')
time.sleep(5)
end_time = datetime.datetime.now().time().strftime('%H:%M:%S')
total_time=(datetime.datetime.strptime(end_time,'%H:%M:%S') - datetime.datetime.strptime(start_time,'%H:%M:%S'))
print total_time

OUTPUT:

0:00:05
Dipnesh Parakhiya
sumber
Inti dari jawaban ini tidak berbeda sama sekali dari jawaban yang diterima enam tahun dan sangat tervvatifikasi. Apakah Anda benar-benar punya sesuatu untuk ditambahkan? Tidak ada gunanya mengirimkan jawaban yang sepenuhnya berlebihan.
Blckknght
2
import datetime as dt
from dateutil.relativedelta import relativedelta

start = "09:35:23"
end = "10:23:00"
start_dt = dt.datetime.strptime(start, "%H:%M:%S")
end_dt = dt.datetime.strptime(end, "%H:%M:%S")
timedelta_obj = relativedelta(start_dt, end_dt)
print(
    timedelta_obj.years,
    timedelta_obj.months,
    timedelta_obj.days,
    timedelta_obj.hours,
    timedelta_obj.minutes,
    timedelta_obj.seconds,
)

hasil: 0 0 0 0 -47 -37

hu goao
sumber
1

Keduanya timedan datetimememiliki komponen tanggal.

Biasanya jika Anda hanya berurusan dengan bagian waktu Anda akan memberikan tanggal default. Jika Anda hanya tertarik pada perbedaan dan tahu bahwa kedua waktu berada pada hari yang sama maka buatlah datetimemasing-masing dengan hari yang ditetapkan untuk hari ini dan kurangi mulai dari waktu berhenti untuk mendapatkan interval ( timedelta).

ChrisF
sumber
1

Lihatlah modul datetime dan objek timedelta. Anda harus membangun objek datetime untuk waktu mulai dan berhenti, dan ketika Anda menguranginya, Anda mendapatkan timedelta.

Menembus
sumber
0

Ringkas jika Anda hanya tertarik pada waktu yang telah berlalu yaitu di bawah 24 jam. Anda dapat memformat output sesuai kebutuhan dalam pernyataan pengembalian:

import datetime
def elapsed_interval(start,end):
    elapsed = end - start
    min,secs=divmod(elapsed.days * 86400 + elapsed.seconds, 60)
    hour, minutes = divmod(min, 60)
    return '%.2d:%.2d:%.2d' % (hour,minutes,secs)

if __name__ == '__main__':
    time_start=datetime.datetime.now()
    """ do your process """
    time_end=datetime.datetime.now()
    total_time=elapsed_interval(time_start,time_end)
pengguna2654744
sumber