#python #datetime #time #timedelta #srt
Вопрос:
Я хотел бы добавить серию расколов в Python. Время начинается строками типа «00:08:30.291». Я, кажется, не могу найти правильный способ использовать объекты Python или API, чтобы сделать это удобным/элегантным. Похоже, что объект time не использует микросекунды, поэтому я использую strptime datetime для успешного разбора строк. Но тогда время, похоже, не добавляется, и я действительно предпочитаю не разбиваться на дни (т. Е. 23 2 часа = 25 часов). Я могу использовать время.время, но они тоже не добавляют. Timedelt может показаться подходящим, но, кажется, немного неудобно конвертировать из/в другие вещи. Возможно, я упускаю здесь что-то очевидное. Я хотел бы иметь возможность:
for timestring in times:
t = datetime.strptime("%H:%M:%S.%f", timestring).time
total_duration = total_duration t
print total_duration.strftime("%H:%M:%S.%f")
Комментарии:
1. Я предпочитаю не растекаться по дням . Что это значит? чему должны равняться 23 часа 2 часа?
2. @SilentGhost: Я бы предположил, что всего несколько часов, то есть 25 в этом случае.
3. да, предпочтительно 25. считайте это несущественным, если хотите.
4. @Сэм Брайтман, ты имеешь в виду
duration.days*24*60*60 duration.seconds
? Если вы это имеете в виду, пожалуйста, напишите это в вопросе.5. С. Лотт: Я не понимаю, что вы хотите, чтобы я прояснил
Ответ №1:
То, с чем вы работаете, — это разница во времени, поэтому использование datetime.timedelta
здесь уместно только здесь:
>>> import datetime
>>> d1 = datetime.datetime.strptime("00:08:30.291", "%H:%M:%S.%f")
>>> d1
datetime.datetime(1900, 1, 1, 0, 8, 30, 291000)
>>> d2
datetime.datetime(1900, 1, 1, 0, 2, 30, 291000)
>>> dt1 = datetime.timedelta(minutes=d1.minute, seconds=d1.second, microseconds=d1.microsecond)
>>> dt2 = datetime.timedelta(minutes=d2.minute, seconds=d2.second, microseconds=d2.microsecond)
>>> fin = dt1 dt2
>>> fin
datetime.timedelta(0, 660, 582000)
>>> str(fin)
'0:11:00.582000'
Кроме того, пожалуйста, не используйте такие имена, как sum
для ваших переменных, вы затеняете встроенное.
Комментарии:
1. Безусловно, работает, но неэлегантно разбирать структуру и воссоздавать, особенно для прототипирования. Есть ли более аккуратный/быстрый способ использовать текущий API? Кажется, что у timedelta должно быть время strp или что-то в этом роде.
2. Я переименовал переменную в вопросе.
3. Аналогично, он исключен из strftime, и, похоже, не так просто конвертировать четное время и дату/время: d1.время по-прежнему является временем даты.
Ответ №2:
import numpy as np
# read file with one duration per line
with open('clean_times.txt', 'r') as f:
x = f.read()
# Convert string to list of '00:02:12.31'
# I had to drop last item (empty string)
tmp = x.split('n')[:-1]
# get list of ['00', 02, '12.31']
tmp = [i.split(':') for i in tmp.copy()]
# create numpy array with floats
np_tmp = np.array(tmp, dtype=np.float)
# sum via columns and divide
# hours/24 minutes/60 milliseconds/1000
# X will be a float array [days, hours, seconds]
# Something like `array([ 0. , 15.68333333, 7.4189 ])`
X = np_tmp.sum(axis=0) / np.array([24, 60, 1000])
Я был счастлив здесь, но если вам нужна необычная строка, например '15:41:07.518'
, в качестве вывода, продолжайте читать
# X will be a float array [hours, hours, seconds]
X = np_tmp.sum(axis=0) / np.array([1, 60, 1000])
# ugly part
# Hours are integer parts
H = int(X[0]) int(X[1])
# Minutes are hour fractional part and integer minutes part
tmp_M = (X[0] % 1 X[1] % 1) * 60
M = int(tmp_M)
# Seconds are minutes fractional part and integer seconds part
tmp_S = tmp_M % 1 * 60 X[2]
S = int(tmp_S)
# Milliseconds are seconds fractional part
MS = int(tmp_S % 1 * 1000)
# merge string for output
# Something like '15:41:07.518'
result = f'{H:02}:{M:02}:{S:02}.{MS:03}'