Làm cách nào để tìm chênh lệch thời gian giữa hai đối tượng datetime trong python?


Câu trả lời:


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

Trừ đi lần sau từ lần đầu tiên difference = later_time - first_timetạo ra một đối tượng datetime chỉ giữ sự khác biệt. Trong ví dụ trên là 0 phút, 8 giây và 562000 micro giây.


2
Tham khảo: docs.python.org/l Library / datetime.html # datatetime-objects . Đọc "các hoạt động được hỗ trợ".
S.Lott

@SilentGhost, Cách nhận hàng giờ, bộ đồ, giây
Mulagala

1
@markcial: deloreantrình bày sai datetime, pytzcách tiếp cận , ví dụ, ví dụ mã bắt đầu có thể được viết dưới dạng d = datetime.now(timezone(EST))(một dòng có thể đọc được thay vì năm).
jfs

1
lưu ý: bạn nên cẩn thận khi thực hiện các số liệu ngày / giờ trên các đối tượng datetime ngây thơ đại diện cho giờ địa phương. Nó có thể thất bại, ví dụ, xung quanh các chuyển tiếp DST. Xem liên kết với nhiều chi tiết hơn trong câu trả lời của tôi
jfs

Làm thế nào c được sử dụng để tìm sự khác biệt về ngày, phút, giây?
Zeeshan Mahmood

152

Mới ở Python 2.7 là timedeltaphương thức ví dụ .total_seconds(). Từ các tài liệu Python, điều này tương đương với (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6.

Tham khảo: http://docs.python.org/2/l 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

Sử dụng ví dụ 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

Thời gian tính bằng năm

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

Thời lượng tính theo ngày

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

Thời lượng tính theo giờ

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

Thời lượng tính bằng phút

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

Thời lượng tính bằng giây

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

Thời lượng tính bằng micro giây

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

Tổng thời lượng giữa hai ngày

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

hoặc đơn giản:

>>> print(now - then)

Chỉnh sửa 2019 Vì câu trả lời này đã đạt được lực kéo, tôi sẽ thêm một chức năng, có thể đơn giản hóa việc sử dụng cho một số

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
Tôi không biết tại sao không ai cảm ơn bạn. Cảm ơn bạn rất nhiều vì một câu trả lời chính xác như vậy. @Attaque
Amandeep Singh Sawhney

Tôi đã gặp lỗi TypeError: 'float' object is not subscriptablekhi sử dụng cho: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
Đó là bởi vì tôi không thể đếm số giây trong một năm :) 365 * 24 * 60 * 60 = 31536000 chứ không phải 31556926. Tôi đã cập nhật câu trả lời và các chức năng và nó sẽ hoạt động ngay bây giờ.
Attaque

1
Đây phải là câu trả lời được chấp nhận.
saran3h

28

Chỉ cần trừ đi cái khác. Bạn nhận được một timedeltađối tượng với sự khác biệt.

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

Bạn có thể chuyển đổi dd.days, dd.secondsdd.microsecondsđến phút.


Những thông số đó là gì? Nhận xét sẽ rất tuyệt
TheRealChx101

22

Nếu a, blà các đối tượng datetime thì để tìm chênh lệch thời gian giữa chúng trong Python 3:

from datetime import timedelta

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

Trên các phiên bản Python trước:

time_difference_in_minutes = time_difference.total_seconds() / 60

Nếu a, blà các đối tượng datetime ngây thơ như được trả về datetime.now()thì kết quả có thể sai nếu các đối tượng biểu thị thời gian cục bộ với các độ lệch UTC khác nhau, ví dụ, xung quanh các chuyển tiếp DST hoặc cho các ngày trong quá khứ / tương lai. Thêm chi tiết: Tìm nếu 24 giờ đã trôi qua giữa thời gian - Python .

Để có kết quả đáng tin cậy, hãy sử dụng các đối tượng datetime nhận biết thời gian hoặc múi giờ UTC.


17

Sử dụng 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)

1
Điều này nên được đưa vào mô-đun datetime. Tôi chỉ không thể hiểu tại sao nó chỉ sử dụng ngày, giây và mili ...
paulochf

Điều này không trả lời câu hỏi liên quan đến các đối tượng datetime.
elec3647

10

Đây là cách tôi có được số giờ trôi qua giữa hai đối tượng datetime.datetime:

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

9
Điều này sẽ không hoạt động: timedelta.secondschỉ đưa ra số giây được lưu trữ rõ ràng - mà tài liệu đảm bảo sẽ có tổng số ít hơn một ngày. Bạn muốn (after - before).total_seconds(), cung cấp số giây trải dài trên toàn bộ delta.
lvc

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

@lvc Mã cũ của tôi thực sự được viết theo cách đó và tôi nghĩ rằng mình đang thông minh và "sửa chữa" nó. Cảm ơn vì sự đúng đắn của bạn.
Tony

@JFSebastian Cảm ơn vì điều đó, tôi đã quên toán tử //. Và tôi thích cú pháp py3 hơn, nhưng đang sử dụng 2.7.
Tony

9

Để chỉ tìm số ngày: timedelta có thuộc tính 'ngày'. Bạn chỉ có thể truy vấn đó.

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

Chỉ cần nghĩ rằng nó có thể hữu ích để đề cập đến định dạng cũng liên quan đến timedelta. strptime () phân tích một chuỗi biểu thị thời gian theo một định dạng.

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)

Điều này sẽ xuất ra: 0: 05: 00.518000


3

Tôi sử dụng đôi khi như thế này:

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
bạn có được datetimes hoàn toàn tốt, tại sao bạn sao chép chúng? đó là 75% mã của bạn có thể được thể hiện bằngreturn t1-t2
Patrick Artner

2

điều này là để tìm sự khác biệt giữa thời gian hiện tại và 9h30 sáng

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

1

Đây là cách tiếp cận của tôi bằng cách sử dụng 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

mktime()mong đợi thời gian địa phương là một đầu vào. Giờ địa phương có thể mơ hồ và mktime()có thể trả lời sai trong trường hợp này. Sử dụng a - bthay thế (a, b - đối tượng datetime) . mktime()là không cần thiết và đôi khi nó là sai. Đừng sử dụng nó trong trường hợp này.
JFS

@AnneTheAgile, đã sửa, lỗi của tôi khi nhập. Đã thử nghiệm trên Python 2.7.12
Eduardo

1

Theo những cách khác để có được sự khác biệt giữa ngày;

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)

Vì vậy, nhận đầu ra trong Min.

Cảm ơn


1

Tôi đã sử dụng sự khác biệt về thời gian cho các bài kiểm tra tích hợp liên tục để kiểm tra và cải thiện các chức năng của mình. Đây là mã đơn giản nếu ai đó cần nó

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

Sử dụng:

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

và tôi có một cái gì đó như thế trong đầu ra đăng nhập

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

0

Dựa trên câu trả lời tuyệt vời @Attaque , tôi đề xuất một phiên bản đơn giản hóa ngắn hơn của máy tính chênh lệch thời gian:

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]

Tôi đã thay đổi nó để tránh khai báo các hàm lặp lại, xóa khoảng thời gian mặc định in đẹp và thêm hỗ trợ cho mili giây, tuần và tháng ISO (tháng đầu tiên chỉ là gần đúng, dựa trên giả định rằng mỗi tháng bằng 365/12 ).

Sản xuất:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.