Python'da iki datetime nesnesi arasındaki zaman farkını nasıl bulabilirim?


Yanıtlar:


375
>>> import datetime
>>> first_time = datetime.datetime.now()
>>> later_time = datetime.datetime.now()
>>> difference = later_time - first_time
>>> seconds_in_day = 24 * 60 * 60
datetime.timedelta(0, 8, 562000)
>>> divmod(difference.days * seconds_in_day + difference.seconds, 60)
(0, 8)      # 0 minutes, 8 seconds

Daha sonraki süreyi ilk kez difference = later_time - first_timeçıkarmak, sadece farkı tutan bir datetime nesnesi oluşturur. Yukarıdaki örnekte 0 dakika, 8 saniye ve 562000 mikrosaniyedir.


2
Referans: docs.python.org/library/datetime.html#datetime-objects . "Desteklenen işlemler" bölümünü okuyun.
S.Lott

@SilentGhost, Saat, minuits, saniye ile nasıl gidilir
Mulagala

1
@markcial: deloreanyanlış temsil datetime, pytzyaklaşım, örneğin, başlangıç ​​kodu örneğid = datetime.now(timezone(EST)) (beş yerine bir okunabilir satır) olarak yazılabilir .
jfs

1
not: yerel saati temsil eden naif datetime nesneleri üzerinde tarih / saat aritmetiği yaparken dikkatli olmalısınız. Örneğin, DST geçişleri etrafında başarısız olabilir.
Cevabımda

C gün, dakika, saniye cinsinden farkı bulmak için nasıl kullanılır?
Zeeshan Mahmood

152

Python 2.7'deki yenilikler timedeltaörnek yöntemdir .total_seconds(). Python belgelerinden, bu eşdeğerdir (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6.

Referans: http://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds

>>> import datetime
>>> time1 = datetime.datetime.now()
>>> time2 = datetime.datetime.now() # waited a few minutes before pressing enter
>>> elapsedTime = time2 - time1
>>> elapsedTime
datetime.timedelta(0, 125, 749430)
>>> divmod(elapsedTime.total_seconds(), 60)
(2.0, 5.749430000000004) # divmod returns quotient and remainder
# 2 minutes, 5.74943 seconds


107

Datetime örneğini kullanma

>>> from datetime import datetime
>>> then = datetime(2012, 3, 5, 23, 8, 15)        # Random date in the past
>>> now  = datetime.now()                         # Now
>>> duration = now - then                         # For build-in functions
>>> duration_in_s = duration.total_seconds()      # Total number of seconds between dates

Yıl cinsinden süre

>>> years = divmod(duration_in_s, 31536000)[0]    # Seconds in a year=365*24*60*60 = 31536000.

Gün cinsinden süre

>>> days  = duration.days                         # Build-in datetime function
>>> days  = divmod(duration_in_s, 86400)[0]       # Seconds in a day = 86400

Saat cinsinden süre

>>> hours = divmod(duration_in_s, 3600)[0]        # Seconds in an hour = 3600

Dakika cinsinden süre

>>> minutes = divmod(duration_in_s, 60)[0]        # Seconds in a minute = 60

Saniye cinsinden süre

>>> seconds = duration.seconds                    # Build-in datetime function
>>> seconds = duration_in_s

Mikrosaniye cinsinden süre

>>> microseconds = duration.microseconds          # Build-in datetime function  

İki tarih arasındaki toplam süre

>>> days    = divmod(duration_in_s, 86400)        # Get days (without [0]!)
>>> hours   = divmod(days[1], 3600)               # Use remainder of days to calc hours
>>> minutes = divmod(hours[1], 60)                # Use remainder of hours to calc minutes
>>> seconds = divmod(minutes[1], 1)               # Use remainder of minutes to calc seconds
>>> print("Time between dates: %d days, %d hours, %d minutes and %d seconds" % (days[0], hours[0], minutes[0], seconds[0]))

ya da sadece:

>>> print(now - then)

2019'u Düzenle Bu yanıt çekildiğinden, bazılarının kullanımını basitleştirebilecek bir işlev ekleyeceğim

from datetime import datetime

def getDuration(then, now = datetime.now(), interval = "default"):

    # Returns a duration as specified by variable interval
    # Functions, except totalDuration, returns [quotient, remainder]

    duration = now - then # For build-in functions
    duration_in_s = duration.total_seconds() 

    def years():
      return divmod(duration_in_s, 31536000) # Seconds in a year=31536000.

    def days(seconds = None):
      return divmod(seconds if seconds != None else duration_in_s, 86400) # Seconds in a day = 86400

    def hours(seconds = None):
      return divmod(seconds if seconds != None else duration_in_s, 3600) # Seconds in an hour = 3600

    def minutes(seconds = None):
      return divmod(seconds if seconds != None else duration_in_s, 60) # Seconds in a minute = 60

    def seconds(seconds = None):
      if seconds != None:
        return divmod(seconds, 1)   
      return duration_in_s

    def totalDuration():
        y = years()
        d = days(y[1]) # Use remainder to calculate next variable
        h = hours(d[1])
        m = minutes(h[1])
        s = seconds(m[1])

        return "Time between dates: {} years, {} days, {} hours, {} minutes and {} seconds".format(int(y[0]), int(d[0]), int(h[0]), int(m[0]), int(s[0]))

    return {
        'years': int(years()[0]),
        'days': int(days()[0]),
        'hours': int(hours()[0]),
        'minutes': int(minutes()[0]),
        'seconds': int(seconds()),
        'default': totalDuration()
    }[interval]

# Example usage
then = datetime(2012, 3, 5, 23, 8, 15)
now = datetime.now()

print(getDuration(then)) # E.g. Time between dates: 7 years, 208 days, 21 hours, 19 minutes and 15 seconds
print(getDuration(then, now, 'years'))      # Prints duration in years
print(getDuration(then, now, 'days'))       #                    days
print(getDuration(then, now, 'hours'))      #                    hours
print(getDuration(then, now, 'minutes'))    #                    minutes
print(getDuration(then, now, 'seconds'))    #                    seconds

7
Neden kimsenin sana teşekkür etmediğini bilmiyorum, bu kadar kesin bir cevap için çok teşekkür ederim. Attika
Amandeep Singh Sawhney

Ne TypeError: 'float' object is not subscriptablezaman kullanım için hata var :then = datetime(2017, 8, 11, 15, 58, tzinfo=pytz.UTC) now = datetime(2018, 8, 11, 15, 58, tzinfo=pytz.UTC) getDuration(then, now, 'years')
Piotr Wasilewicz

1
Çünkü bir yılda saniye sayısını sayamıyorum :) 365 * 24 * 60 * 60 = 31536000, 31556926 değil. Cevabı ve fonksiyonları güncelledim ve şimdi çalışmalı.
Attaque

28

Sadece birini diğerinden çıkarın. timedeltaFarkı olan bir nesne elde edersiniz .

>>> import datetime
>>> d1 = datetime.datetime.now()
>>> d2 = datetime.datetime.now() # after a 5-second or so pause
>>> d2 - d1
datetime.timedelta(0, 5, 203000)

Sen dönüştürebilirsiniz dd.days, dd.secondsve dd.microsecondsdakika.


Bu parametreler nelerdir? Yorumlar güzel olurdu
TheRealChx101

22

Eğer a, bdatetime nesneleri Python 3'te aralarındaki zaman farkını bulmak için:

from datetime import timedelta

time_difference = a - b
time_difference_in_minutes = time_difference / timedelta(minutes=1)

Önceki Python sürümlerinde:

time_difference_in_minutes = time_difference.total_seconds() / 60

Eğer a, btarafından döndürülen naif datetime böyle nesneleri olan datetime.now()nesneler, UTC uzaklıklar örneğin farklı etrafında DST geçişlerle veya geçmiş / gelecek tarihlerde yerel saati temsil eğer yanlış olabilir o zaman sonuç. Ek bilgi: Tarihler arasında 24 saat geçtiyse bulun - Python .

Güvenilir sonuçlar elde etmek için UTC zamanını veya saat dilimine duyarlı tarih / saat nesnelerini kullanın.


17

Divmod kullanın:

now = int(time.time()) # epoch seconds
then = now - 90000 # some time in the past

d = divmod(now-then,86400)  # days
h = divmod(d[1],3600)  # hours
m = divmod(h[1],60)  # minutes
s = m[1]  # seconds

print '%d days, %d hours, %d minutes, %d seconds' % (d[0],h[0],m[0],s)

1
Bu datetime modülüne konulmalıdır. Neden sadece gün, saniye ve milis kullandığını anlayamıyorum ...
paulochf

Bu tarih-saat nesneleri ile ilgili soruya cevap vermez.
elec3647

10

İki datetime.datetime nesnesi arasında geçen saat sayısını şöyle elde ederim:

before = datetime.datetime.now()
after  = datetime.datetime.now()
hours  = math.floor(((after - before).seconds) / 3600)

9
Bu pek işe yaramayacak: timedelta.secondsyalnızca açıkça saklanan saniye sayısını verir - dokümantasyon garantilerinin toplamı bir günden az olacaktır. İsterseniz (after - before).total_seconds(), tüm deltayı geçen saniye sayısını verir .
lvc

1
(after - before).total_seconds() // 3600(Python 2.7) veya (after - before) // timedelta(seconds=3600)(Python 3)
jfs

@lvc Benim eski kod aslında bu şekilde yazılmıştır ve ben akıllı olmak ve bunu "tamir" düşündüm. Düzeltme için teşekkürler.
Tony

@JFSebastian Bunun için teşekkürler, // operatörünü unuttum. Ve ben py3 sözdizimini daha çok seviyorum, ama 2.7 kullanıyorum.
Tony,

9

Sadece gün sayısını bulmak için: timedelta 'days' özelliğine sahiptir. Bunu sadece sorgulayabilirsiniz.

>>>from datetime import datetime, timedelta
>>>d1 = datetime(2015, 9, 12, 13, 9, 45)
>>>d2 = datetime(2015, 8, 29, 21, 10, 12)
>>>d3 = d1- d2
>>>print d3
13 days, 15:59:33
>>>print d3.days
13

5

Sadece timedelta açısından da biçimlendirmeden bahsetmenin yararlı olabileceğini düşündüm. strptime (), bir biçimi temsil eden bir dizeyi biçime göre ayrıştırır.

from datetime import datetime

datetimeFormat = '%Y/%m/%d %H:%M:%S.%f'    
time1 = '2016/03/16 10:01:28.585'
time2 = '2016/03/16 09:56:28.067'  
time_dif = datetime.strptime(time1, datetimeFormat) - datetime.strptime(time2,datetimeFormat)
print(time_dif)

Bu çıktı: 0: 05: 00.518000


3

Ben böyle bir şey kullanın:

from datetime import datetime

def check_time_difference(t1: datetime, t2: datetime):
    t1_date = datetime(
        t1.year,
        t1.month,
        t1.day,
        t1.hour,
        t1.minute,
        t1.second)

    t2_date = datetime(
        t2.year,
        t2.month,
        t2.day,
        t2.hour,
        t2.minute,
        t2.second)

    t_elapsed = t1_date - t2_date

    return t_elapsed

# usage 
f = "%Y-%m-%d %H:%M:%S+01:00"
t1 = datetime.strptime("2018-03-07 22:56:57+01:00", f)
t2 = datetime.strptime("2018-03-07 22:48:05+01:00", f)
elapsed_time = check_time_difference(t1, t2)

print(elapsed_time)
#return : 0:08:52

2
iyi zaman geçirirsin, neden onları kopyalarsın? kodunuzun% 75'i şu şekilde ifade edilebilirreturn t1-t2
Patrick Artner

2

bu şimdiki zaman ile 9.30 arasındaki farkı bulmak için

t=datetime.now()-datetime.now().replace(hour=9,minute=30)

1

Bu benim mktime kullanarak yaklaşımım .

from datetime import datetime, timedelta
from time import mktime

yesterday = datetime.now() - timedelta(days=1)
today = datetime.now()

difference_in_seconds = abs(mktime(yesterday.timetuple()) - mktime(today.timetuple()))
difference_in_minutes = difference_in_seconds / 60

mktime()yerel saati girdi olarak bekler. Yerel saat belirsiz mktime()olabilir ve bu durumda yanlış bir cevap verebilir. Bunun yerine kullanın a - b(a, b - datetime nesneleri) . mktime()gereksizdir ve bazen yanlıştır. Bu durumda kullanmayın.
jfs

@AnneTheAgile, düzeltildi, içe aktarmadaki hatam. Python 2.7.12
Eduardo

1

Tarih arasında fark elde etmenin diğer yollarında;

import dateutil.parser
import datetime
last_sent_date = "" # date string
timeDifference = current_date - dateutil.parser.parse(last_sent_date)
time_difference_in_minutes = (int(timeDifference.days) * 24 * 60) + int((timeDifference.seconds) / 60)

Yani Min.

Teşekkürler


1

Fonksiyonlarımı kontrol etmek ve geliştirmek için sürekli entegrasyon testleri için zaman farklılıkları kullandım. Birinin ihtiyacı varsa basit kod İşte

from datetime import datetime

class TimeLogger:
    time_cursor = None

    def pin_time(self):
        global time_cursor
        time_cursor = datetime.now()

    def log(self, text=None) -> float:
        global time_cursor

        if not time_cursor:
            time_cursor = datetime.now()

        now = datetime.now()
        t_delta = now - time_cursor

        seconds = t_delta.total_seconds()

        result = str(now) + ' tl -----------> %.5f' % seconds
        if text:
            result += "   " + text
        print(result)

        self.pin_time()

        return seconds


time_logger = TimeLogger()

Kullanımı:

from .tests_time_logger import time_logger
class Tests(TestCase):
    def test_workflow(self):
    time_logger.pin_time()

    ... my functions here ...

    time_logger.log()

    ... other function(s) ...

    time_logger.log(text='Tests finished')

ve günlük çıktısında böyle bir şey var

2019-12-20 17:19:23.635297 tl -----------> 0.00007
2019-12-20 17:19:28.147656 tl -----------> 4.51234   Tests finished

0

@Attaque harika cevabına dayanarak , datetime farkı hesaplayıcının daha kısa basitleştirilmiş bir sürümünü öneriyorum:

seconds_mapping = {
    'y': 31536000,
    'm': 2628002.88, # this is approximate, 365 / 12; use with caution
    'w': 604800,
    'd': 86400,
    'h': 3600,
    'min': 60,
    's': 1,
    'mil': 0.001,
}

def get_duration(d1, d2, interval, with_reminder=False):
    if with_reminder:
        return divmod((d2 - d1).total_seconds(), seconds_mapping[interval])
    else:
        return (d2 - d1).total_seconds() / seconds_mapping[interval]

Tekrarlayan işlevler bildirmekten kaçınmak için değiştirdim, güzel yazdırma varsayılan aralığını kaldırdım ve milisaniye, hafta ve ISO ayları için destek ekledim (her ayın eşit olduğu varsayımına dayanarak çıplak aylar sadece yaklaşıktır 365/12).

Hangi üretir:

d1 = datetime(2011, 3, 1, 1, 1, 1, 1000)
d2 = datetime(2011, 4, 1, 1, 1, 1, 2500)

print(get_duration(d1, d2, 'y', True))      # => (0.0, 2678400.0015)
print(get_duration(d1, d2, 'm', True))      # => (1.0, 50397.12149999989)
print(get_duration(d1, d2, 'w', True))      # => (4.0, 259200.00149999978)
print(get_duration(d1, d2, 'd', True))      # => (31.0, 0.0014999997802078724)
print(get_duration(d1, d2, 'h', True))      # => (744.0, 0.0014999997802078724)
print(get_duration(d1, d2, 'min', True))    # => (44640.0, 0.0014999997802078724)
print(get_duration(d1, d2, 's', True))      # => (2678400.0, 0.0014999997802078724)
print(get_duration(d1, d2, 'mil', True))    # => (2678400001.0, 0.0004999997244524721)

print(get_duration(d1, d2, 'y', False))     # => 0.08493150689687975
print(get_duration(d1, d2, 'm', False))     # => 1.019176965856293
print(get_duration(d1, d2, 'w', False))     # => 4.428571431051587
print(get_duration(d1, d2, 'd', False))     # => 31.00000001736111
print(get_duration(d1, d2, 'h', False))     # => 744.0000004166666
print(get_duration(d1, d2, 'min', False))   # => 44640.000024999994
print(get_duration(d1, d2, 's', False))     # => 2678400.0015
print(get_duration(d1, d2, 'mil', False))   # => 2678400001.4999995
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.