İki zaman dizesi arasındaki zaman aralığı nasıl hesaplanır


169

10:33:26 (SS: DD: SS) biçiminde iki kez bir başlangıç ​​ve bitiş zamanım var. İki kez arasındaki farka ihtiyacım var. Ben Python belgelerine bakarak ve çevrimiçi arama ve ben datetime ve / veya zaman modülleri ile ilgili bir şey olacağını hayal ediyorum. Düzgün çalışması ve sadece bir tarih söz konusu olduğunda bunun nasıl yapılacağını bulmaya devam edemiyorum.

Sonuçta, çoklu zaman sürelerinin ortalamalarını hesaplamam gerekiyor. Çalışmak için zaman farkları var ve bunları bir listede saklıyorum. Şimdi ortalamayı hesaplamam gerekiyor. Orijinal zamanları ayrıştırmak ve daha sonra farklılıkları yapmak için düzenli ifadeler kullanıyorum.

Ortalama için saniye ve sonra ortalamaya dönmeli miyim?


2
Denediğiniz kodu gönderebilir misiniz ve oradan başlayabiliriz?
Anthony Forloney

related:
Tarihler

Yanıtlar:


201

Evet, kesinlikle datetimeburada ihtiyacınız olan şey. Özellikle, strptimebir dizeyi bir zaman nesnesine ayrıştıran işlev.

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)

Bu size timedeltaiki kez arasındaki farkı içeren bir nesne getirir. Bununla istediğinizi yapabilirsiniz, örneğin saniyeye dönüştürmek veya başka birine eklemek datetime.

Bitiş zamanı başlangıç ​​zamanından önce ise, bu negatif bir sonuç döndürür, örneğin s1 = 12:00:00ve s2 = 05:00:00. Kodun bu durumda aralık gece yarısını geçtiğini varsaymak istiyorsanız (yani bitiş zamanının başlangıç ​​zamanından daha önce olmadığını varsayarsak), yukarıdaki koda aşağıdaki satırları ekleyebilirsiniz:

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

(tabii ki bir from datetime import timedeltayere dahil etmeniz gerekir ). Bu kullanım durumunu işaret ettiği için JF Sebastian'a teşekkürler.


Negatif zaman kesmek days= -2, tdelta nesnesinde ve üstünde çalışmaz.
CKM

@ chandresh Evet, ancak dayssoruda açıklananın ötesinde ek bilgi (özellikle tarihler) olmadan asla -2 veya daha az olamaz. Yani bu durum burada geçerli değil.
David Z

3
İpucu: Zaman deltasını saniye cinsinden almak için aramanız gerekir tdelta.total_seconds().
scai

156

Bunu deneyin - kısa vadeli olayları zamanlamak için etkilidir. Bir şey bir saatten fazla sürerse, son ekran muhtemelen bazı kolay biçimlendirme isteyecektir.

import time
start = time.time()

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

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

Zaman farkı geçen saniye sayısı olarak döndürülür.


5
Bu neden kabul edilen cevap değildi? Çok basit, bir şeyle karşılaştırılabilecek bir değer veriyor (komutumun yürütülmesi 2,5 saniyeden fazla sürdü mü?) Ve
v2.7'de

11
@Mawg Çünkü OP sorusuna cevap vermiyor. Kodunda bir olayı zamanlayarak nasıl oluşturulacağını değil, zaten belirli bir biçimde sahip olduğu iki farklı zamanı nasıl karşılaştıracağını soruyordu. Bunlar oldukça farklı problemler.
Natsukane

2
Bunu kullanmamalısınız; bunun yerine monoton zamanı kullanın ( time.monotonic()Python'da). time.time()geriye doğru gidebilir (örn. NTP düzeltmeleri de dahil olmak üzere makinedeki zaman değiştiğinde).
nemequ

1
Soru ile ilgisiz
patricktokeeffe

14

Bitiş zamanı, başlangıç ​​zamanından (gece yarısı aralığının üzerinde) daha düşük olsa bile 23:55:00-00:25:00(yarım saatlik bir süre) farkın bulunmasını destekleyen bir çözümdür :

#!/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())

Çıktı

0:42:23
0:30:00

time_diff()(dizinin bir parçası olarak) mean()doğrudan bir işleve geçirebileceğiniz bir timedelta nesnesi döndürür örn:

#!/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

mean()Sonuç da timedelta()(saniye dönüştürmek nesne td.total_seconds()(Beri Python 2,7) yöntemi), saat ( td / timedelta(hours=1)(Python 3)), vb


@JF İstatistiklerin ortalama ve varyans fonksiyonlarının doğrudan timedelta nesnesiyle çalışıp çalışmadığını merak ediyorum. Bunun hakkında bir fikrin var mı? Ayrıca, timedelta nesnelerinin varyansını hesaplamak için herhangi bir yardım yararlı olacaktır.
CKM

@ chandresh: desteklenmez. Zaman çizelgelerinin matematiksel istatistiklerini hesaplamak için saniyeye / mikrosaniyeye dönüştürebilirsiniz.
jfs

11

Python'da zaman farkını temsil eden yapıya timedelta denir . Eğer tipiniz varsa start_timeve tip end_timeolarak operatör gibi datetimekullanarak farkı hesaplayabilirsiniz -:

diff = end_time - start_time

bunu partualr string biçimine dönüştürmeden önce yapmalısınız (örn. start_time.strftime (...) öncesi). Zaten dize temsili varsa strptime yöntemini kullanarak onu zaman / tarih saatine dönüştürmeniz gerekir .


10

Bu site denemek için diyor:

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 

Bu forumda time.mktime () kullanılıyor


% H (24 saat) yerine% I (12 saat) kullandığınızda% p (AM / PM) kullanıyorsanız: docs.python.org/2/library/…
Andrew

6

Bu adamın nasıl yaptığını seviyorum - https://amalgjose.com/2015/02/19/python-code-for-calculating-the-difference-between-two-time-stamps . Bazı eksileri olup olmadığından emin değilim.

Ama benim için düzgün görünüyor :)

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)

Soruyla ilgili olarak, datetime.strptime()daha önce başkalarının söylediği gibi kullanmanız gerekiyor .


3

Bunu dene

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

ÇIKTI :

0:00:05

Bu cevabın temeli altı yaşındaki ve son derece onaylanmış kabul edilen cevaptan hiç farklı değil. Eklemek istediğiniz bir şey var mı? Tamamen gereksiz yanıt göndermenin bir anlamı yok.
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,
)

sonuç: 0 0 0 0-47-37


1

Hem timeve datetimetarih bileşeni var.

Normalde yalnızca zaman bölümüyle ilgileniyorsanız varsayılan bir tarih girersiniz. Sadece farkla ilgileniyorsanız ve her iki zamanın da aynı gün olduğunu biliyorsanız, o datetimegüne ayarlanmış günle her biri için bir a oluşturun ve aralığını ( timedelta) almak için durma zamanından başlangıcı çıkarın .


1

Datetime modülüne ve timedelta nesnelerine bir göz atın. Başlangıç ​​ve bitiş zamanları için bir datetime nesnesi oluşturmalısınız ve bunları çıkardığınızda bir zaman çizelgesi elde edersiniz.


0

Sadece geçen süreyle ilgileniyorsanız, 24 saatin altında olanlara dikkat edin. Çıktıyı return ifadesinde gerektiği gibi biçimlendirebilirsiniz:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.