Bagaimana cara menemukan perbedaan waktu antara dua objek waktu dalam python?

354

Bagaimana cara mengetahui perbedaan waktu dalam menit antara dua datetimeobjek?

Hobhouse
sumber

Jawaban:

374
>>> 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

Mengurangkan waktu kemudian dari pertama kali difference = later_time - first_timemenciptakan objek datetime yang hanya menyimpan perbedaan. Dalam contoh di atas adalah 0 menit, 8 detik dan 562000 mikrodetik.

SilentGhost
sumber
2
Referensi: docs.python.org/library/datetime.html#datetime-objects . Baca "operasi yang didukung".
S.Lott
@ SilentGhost, Cara mendapatkan jam, minuits, detik
Mulagala
1
@markcial: deloreanmisrepresents datetime, pytzapproach eg, contoh kode memulai dapat ditulis sebagai d = datetime.now(timezone(EST))(satu baris yang dapat dibaca alih-alih lima).
jfs
1
Catatan: Anda harus berhati-hati saat melakukan aritmatika tanggal / waktu pada objek datetime naif yang mewakili waktu lokal. Mungkin gagal misalnya, sekitar transisi DST. Lihat tautan dengan perincian lebih lanjut dalam jawaban saya
jfs
Bagaimana c digunakan untuk menemukan perbedaan dalam hal hari, mnt, dtk?
Zeeshan Mahmood
152

Baru di Python 2.7 adalah timedeltametode contoh .total_seconds(). Dari dokumen Python, ini setara dengan (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6.

Referensi: 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
Ryan Stanley
sumber
107

Menggunakan contoh datetime

>>> 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

Durasi bertahun-tahun

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

Durasi dalam beberapa hari

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

Durasi dalam hitungan jam

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

Durasi dalam hitungan menit

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

Durasi dalam hitungan detik

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

Durasi dalam mikrodetik

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

Total durasi antara kedua tanggal

>>> 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]))

atau hanya:

>>> print(now - then)

Sunting 2019 Karena jawaban ini mendapatkan daya tarik, saya akan menambahkan fungsi, yang mungkin menyederhanakan penggunaan untuk beberapa

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
Attaque
sumber
7
Saya tidak tahu mengapa tidak ada yang mengucapkan terima kasih. Terima kasih banyak atas jawaban yang tepat. @Attaque
Amandeep Singh Sawhney
Saya mendapatkan TypeError: 'float' object is not subscriptablethen = datetime(2017, 8, 11, 15, 58, tzinfo=pytz.UTC) now = datetime(2018, 8, 11, 15, 58, tzinfo=pytz.UTC) getDuration(then, now, 'years')
pesan
1
Itu karena saya tidak dapat menghitung jumlah detik dalam setahun :) 365 * 24 * 60 * 60 = 31536000 dan bukan 31556926. Saya memperbarui jawaban dan fungsinya dan seharusnya berfungsi sekarang.
Attaque
1
Ini harus menjadi jawaban yang diterima.
saran3h
28

Cukup kurangi satu dari yang lain. Anda mendapatkan timedeltaobjek dengan perbedaan.

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

Anda dapat mengonversi dd.days, dd.secondsdan dd.microsecondsmenjadi beberapa menit.

Vinay Sajip
sumber
Apa saja parameternya? Komentar akan menyenangkan
TheRealChx101
22

Jika a, badalah objek datetime maka untuk menemukan perbedaan waktu di antara mereka dalam Python 3:

from datetime import timedelta

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

Pada versi Python sebelumnya:

time_difference_in_minutes = time_difference.total_seconds() / 60

Jika a, badalah objek datetime naif seperti dikembalikan pada datetime.now()saat itu maka hasilnya mungkin salah jika objek mewakili waktu lokal dengan offset UTC yang berbeda misalnya, sekitar transisi DST atau untuk tanggal masa lalu / masa depan. Lebih detail: Temukan apakah 24 jam telah lewat di antara waktu-waktu - Python .

Untuk mendapatkan hasil yang andal, gunakan objek waktu-waktu UTC atau sadar zona waktu.

jfs
sumber
17

Gunakan divmod:

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)
sia-sia
sumber
1
Ini harus dimasukkan ke dalam modul datetime. Saya tidak mengerti mengapa hanya digunakan beberapa hari, detik, dan milis ...
paulochf
Ini tidak menjawab pertanyaan tentang objek datetime.
elec3647
10

Ini adalah bagaimana saya mendapatkan jumlah jam yang berlalu antara dua objek datetime.datetime:

before = datetime.datetime.now()
after  = datetime.datetime.now()
hours  = math.floor(((after - before).seconds) / 3600)
Tony
sumber
9
Ini tidak akan berhasil: timedelta.secondshanya memberikan jumlah detik disimpan secara eksplisit - yang jaminan dokumentasi akan berjumlah kurang dari satu hari. Anda ingin (after - before).total_seconds(), yang memberikan jumlah detik yang menjangkau seluruh delta.
lvc
1
(after - before).total_seconds() // 3600(Python 2.7) atau (after - before) // timedelta(seconds=3600)(Python 3)
jfs
@ lvc Kode lama saya sebenarnya ditulis seperti itu, dan saya pikir saya menjadi pintar dan "memperbaikinya". Terima kasih atas koreksinya.
Tony
@ JSFSebastian Terima kasih untuk itu, saya lupa tentang operator //. Dan saya suka sintaks py3 lebih baik, tetapi saya menggunakan 2.7.
Tony
9

Untuk hanya menemukan jumlah hari: timedelta memiliki atribut 'hari'. Anda bisa menanyakannya.

>>>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
griknus17
sumber
5

Hanya berpikir mungkin berguna untuk menyebutkan pemformatan juga dalam hal timedelta. strptime () mem-parsing string yang mewakili waktu sesuai dengan format.

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)

Ini akan menampilkan: 0: 05: 00.518000

burung gereja
sumber
3

Saya menggunakan sesuatu seperti ini:

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
Softmixt
sumber
2
Anda mendapatkan datetime yang sangat baik, mengapa Anda menyalinnya? itu 75% dari kode Anda dapat diekspresikan olehreturn t1-t2
Patrick Artner
2

ini untuk menemukan perbedaan antara waktu sekarang dan jam 9.30 pagi

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

Ini adalah pendekatan saya menggunakan mktime .

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
Eduardo
sumber
mktime()mengharapkan waktu lokal sebagai input. Waktu setempat mungkin ambigu dan mktime()dapat mengembalikan jawaban yang salah dalam kasus ini. Gunakan a - bsebagai gantinya (a, b - objek waktu) . mktime()tidak perlu dan kadang-kadang salah. Jangan menggunakannya dalam kasus ini.
jfs
@AnneTheAgile, diperbaiki, kesalahan saya pada impor. Diuji dengan Python 2.7.12
Eduardo
1

Dengan cara lain untuk mendapatkan perbedaan antara tanggal;

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)

Jadi dapatkan output dalam Min.

Terima kasih

Anurag Pandey
sumber
1

Saya telah menggunakan perbedaan waktu untuk pengujian integrasi berkelanjutan untuk memeriksa dan meningkatkan fungsi saya. Berikut adalah kode sederhana jika seseorang membutuhkannya

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()

Menggunakan:

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')

dan saya punya sesuatu seperti itu di log output

2019-12-20 17:19:23.635297 tl -----------> 0.00007
2019-12-20 17:19:28.147656 tl -----------> 4.51234   Tests finished
Serg Smyk
sumber
0

Berdasarkan jawaban hebat @Attaque , saya mengusulkan versi sederhana dari kalkulator perbedaan waktu:

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]

Saya telah mengubahnya untuk menghindari mendeklarasikan fungsi berulang, menghapus interval default cetak cantik dan menambahkan dukungan untuk milidetik, minggu dan bulan ISO (bulan-bulan dalam pikiran hanya perkiraan, berdasarkan asumsi bahwa setiap bulan sama dengan 365/12).

Yang menghasilkan:

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
Voy
sumber