Cách tính khoảng thời gian giữa hai chuỗi thời gian


169

Tôi có hai lần, thời gian bắt đầu và thời gian dừng, ở định dạng 10:33:26 (HH: MM: SS). Tôi cần sự khác biệt giữa hai lần. Tôi đã xem qua tài liệu về Python và tìm kiếm trực tuyến và tôi sẽ tưởng tượng nó sẽ có liên quan gì đến các mô đun thời gian và / hoặc thời gian. Tôi không thể làm cho nó hoạt động đúng và chỉ tìm cách làm điều này khi có một ngày.

Cuối cùng, tôi cần tính trung bình của nhiều khoảng thời gian. Tôi có sự khác biệt về thời gian để làm việc và tôi đang lưu trữ chúng trong một danh sách. Bây giờ tôi cần tính trung bình. Tôi đang sử dụng các biểu thức chính quy để phân tích thời gian ban đầu và sau đó thực hiện các khác biệt.

Để tính trung bình, tôi có nên chuyển đổi thành giây và sau đó trung bình không?


2
Bạn có thể gửi mã của bạn mà bạn đã thử và chúng tôi có thể bắt đầu từ đó?
Anthony Forloney

Câu trả lời:


200

Vâng, chắc chắn datetimelà những gì bạn cần ở đây. Cụ thể, strptimehàm phân tích một chuỗi thành một đối tượng thời gian.

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)

Điều đó giúp bạn có một timedeltađối tượng chứa sự khác biệt giữa hai lần. Bạn có thể làm bất cứ điều gì bạn muốn với điều đó, ví dụ như chuyển đổi nó thành giây hoặc thêm nó vào một cái khác datetime.

Điều này sẽ trả về kết quả âm nếu thời gian kết thúc sớm hơn thời gian bắt đầu, ví dụ s1 = 12:00:00s2 = 05:00:00. Nếu bạn muốn mã giả định khoảng thời gian vượt qua nửa đêm trong trường hợp này (nghĩa là thời gian kết thúc sẽ không bao giờ sớm hơn thời gian bắt đầu), bạn có thể thêm các dòng sau vào mã trên:

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

(tất nhiên bạn cần bao gồm from datetime import timedeltamột nơi nào đó). Cảm ơn JF Sebastian đã chỉ ra trường hợp sử dụng này.


Hack thời gian tiêu cực sẽ không hoạt động khi days= -2và ở trên trong đối tượng tdelta.
CKM

@ Vendresh Có, nhưng dayskhông bao giờ có thể là -2 hoặc ít hơn mà không có thông tin bổ sung (cụ thể là ngày) ngoài những gì được mô tả trong câu hỏi. Vì vậy, tình hình đó không liên quan ở đây.
David Z

3
Gợi ý: Để có được đồng bằng thời gian tính bằng giây, bạn phải gọi tdelta.total_seconds().
scai

156

Hãy thử điều này - nó hiệu quả để định thời gian cho các sự kiện ngắn hạn. Nếu một cái gì đó mất hơn một giờ, thì màn hình cuối cùng có thể sẽ muốn một số định dạng thân thiện.

import time
start = time.time()

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

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

Chênh lệch thời gian được trả về là số giây đã trôi qua.


5
Tại sao đây không phải là câu trả lời được chấp nhận? Thật đơn giản, nó mang lại một giá trị có thể so sánh với một thứ gì đó (lệnh của tôi có mất hơn 2,5 giây để thực thi không?) Và nó hoạt động trong
phiên bản 2.7

11
@Mawg Bởi vì nó không trả lời câu hỏi OP. Anh ta hỏi làm thế nào để so sánh hai thời điểm khác nhau mà anh ta đã có trong một định dạng nhất định, chứ không phải làm thế nào để tạo ra chúng bằng cách định thời gian cho một sự kiện trong mã của anh ta. Chúng là những vấn đề khá khác nhau.
Natsukane

2
Bạn không nên sử dụng cái này; sử dụng thời gian đơn điệu thay thế ( time.monotonic()bằng Python). time.time()có thể quay ngược (ví dụ: khi thời gian trên máy thay đổi, bao gồm cả hiệu chỉnh NTP).
nemequ

1
Không liên quan đến câu hỏi
patricktokeeffe

14

Đây là một giải pháp hỗ trợ tìm kiếm sự khác biệt ngay cả khi thời gian kết thúc ít hơn thời gian bắt đầu (khoảng thời gian nửa đêm), chẳng hạn như 23:55:00-00:25:00(thời lượng nửa giờ):

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

Đầu ra

0:42:23
0:30:00

time_diff()trả về một đối tượng timedelta mà bạn có thể truyền (như một phần của chuỗi) cho một mean()hàm trực tiếp, ví dụ:

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

Các mean()kết quả cũng là timedelta()đối tượng mà bạn có thể chuyển đổi sang giây ( td.total_seconds()phương pháp (vì Python 2.7)), giờ ( td / timedelta(hours=1)(Python 3)), vv


@JF Tôi tự hỏi nếu số liệu thống kê trung bình và các hàm phương sai làm việc trực tiếp với đối tượng timedelta bây giờ? Bất cứ suy nghĩ về điều đó? Ngoài ra, bất kỳ trợ giúp để tính toán phương sai của các đối tượng timedelta sẽ hữu ích.
CKM

@ Vendresh: nó không được hỗ trợ. Bạn có thể chuyển đổi thành giây / micro giây để tính toán thống kê toán học của các mốc thời gian.
jfs

11

Cấu trúc thể hiện sự khác biệt về thời gian trong Python được gọi là timedelta . Nếu bạn có start_timeend_timetheo datetimeloại, bạn có thể tính toán sự khác biệt bằng cách sử dụng -toán tử như:

diff = end_time - start_time

bạn nên làm điều này trước khi chuyển đổi sang định dạng chuỗi particualr (ví dụ: trước start_time.strftime (...)). Trong trường hợp bạn đã có biểu diễn chuỗi, bạn cần chuyển đổi nó trở lại thời gian / thời gian bằng cách sử dụng phương thức strptime .


10

Trang web này nói hãy thử:

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 

Diễn đàn này sử dụng time.mktime ()


Đảm bảo rằng nếu bạn sử dụng% p (AM / PM) mà bạn sử dụng% I (12 giờ) thay vì% H (24 giờ): docs.python.org/2/l Library / Lỗi
Andrew

6

Tôi thích cách anh chàng này làm điều đó - https://amalgjose.com/2015/02/19/python-code-for-calculating-the-difference-b between - two - time - stamp . Không chắc chắn nếu nó có một số khuyết điểm.

Nhưng trông gọn gàng với tôi :)

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)

Liên quan đến câu hỏi bạn vẫn cần sử dụng datetime.strptime()như những người khác đã nói trước đó.


3

Thử cái này

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

ĐẦU RA:

0:00:05

Cốt lõi của câu trả lời này hoàn toàn không khác biệt với câu trả lời được chấp nhận sáu năm tuổi và được đánh giá cao. Bạn có thực sự có bất cứ điều gì để thêm? Không có điểm nào trong việc gửi một câu trả lời hoàn toàn dư thừa.
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,
)

kết quả: 0 0 0 0 -47 -37


1

Cả hai timedatetimecó một thành phần ngày.

Thông thường nếu bạn chỉ giao dịch với phần thời gian bạn sẽ cung cấp một ngày mặc định. Nếu bạn chỉ quan tâm đến sự khác biệt và biết rằng cả hai thời gian đều trong cùng một ngày thì hãy tạo một datetimekhoảng thời gian cho mỗi ngày được đặt thành ngày hôm nay và trừ điểm bắt đầu từ thời gian dừng để có khoảng ( timedelta).


1

Hãy xem mô-đun datetime và các đối tượng timedelta. Bạn nên kết thúc việc xây dựng một đối tượng datetime cho thời gian bắt đầu và dừng lại, và khi bạn trừ chúng, bạn sẽ có được một timedelta.


0

Súc tích nếu bạn chỉ quan tâm đến thời gian trôi qua dưới 24 giờ. Bạn có thể định dạng đầu ra khi cần trong câu lệnh return:

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