Позвольте мне помочь вам разобраться с логикой в ваших задачах, часть реализации должна быть простой, либо на Python / Pandas, либо на другом языке программирования.
См. Следующую диаграмму. Я разделил окно на 6 зон на 8AM
и 8PM
в течение 1-2 последовательных дней (зависит от установленного времени прибытия и времени отправления, о которых я расскажу ниже):
+---day1--+---day2--+
| z1 | z4 |
+---------+---------+<-- 8AM (a8)
| z2 | z5 |
(p8) 8PM -->+---------+---------+
| z3 | z6 |
+---------+---------+
Сначала мы вычисляем delta_in_days между двумя временными метками t1 и t2 ,
каждый отдельный дельта-день дает вам дополнительные 12 часов на итоговую сумму.
Добавление delta_in_days ко времени прибытия, чтобы мы могли сосредоточиться на окне, которое находится в пределах 1 дня (24 часа). Предположим, ts - это скорректированное время прибытия, а te - время отправления. (Примечание: я изначально определил их как время начала и время окончания, назвав их ts и te ) затем
- ts = t1 + delta_in_days
- te = t2
Также установлено:
p8
в тот же день, что и ts
, но в 8 вечера
a8
в тот же день, что и te
, но в 8:00
Ниже приведен список возможных случаев с псевдокодом:
Дело-1:
ts и te в тот же день - в основном в day2 и p8 > a8
if both in the same zone: z4(te < a8) or z6(ts > p8):
total = te - ts
else:
total = max(0, te - p8) + max(0, a8 - ts)
Дело-2:
ts , te в разные дни, если te в z6, то ts должно быть в z3. Помните, что после установленного времени прибытия ts и te должны находиться в пределах 24-часового окна.
if te > p8 + 1day:
total = (te - p8 - 1day) + (a8 - ts)
Дело-3:
ts , te в разные дни, если ts в z1, то te должно быть в z4
if ts < a8 - 1day
total = (a8 - 1day - ts) + (te - p8)
Дело-4:
ts в [z2, z3], а te в [z4, z5]
total = min(a8, te) - max(p8, ts)
Код в Python:
import pandas as pd
from io import StringIO
str="""Jan 1, 15:00 to Jan 1, 18:35
Jan 3, 09:12 to Jan 5, 10:54
Jan 5, 21:00 to Jan 6, 23:48
Jan 5, 23:00 to Jan 6, 20:48
Jan 5, 03:00 to Jan 6, 02:48
Jan 5, 10:00 to Jan 6, 05:48
Jan 5, 21:00 to Jan 6, 10:48
"""
df = pd.read_table(StringIO(str)
, sep='\s*to\s*'
, engine='python'
, names=['t1','t2']
)
for field in ['t1', 't2']:
df[field] = pd.to_datetime(df[field], format="%b %d, %H:%M")
delta_1_day = pd.Timedelta('1 days')
# add 12 hours for each delta_1_day
ns_spent_in_1_day = int(delta_1_day.value*12/24)
# the total time is counted in nano seconds
def count_off_hour_in_ns(x):
t1 = x['t1']
t2 = x['t2']
# number of days from t1 to t2
delta_days = (t2 - t1).days
if delta_days <= 0:
return 0
# add delta_days to start-time so ts and te in 1-day window
# define the start-time(ts) and end-time(te) of the window
ts = t1 + pd.Timedelta('{} days'.format(delta_days))
te = t2
# 8PM the same day as ts
p8 = ts.replace(hour=20, minute=0, second=0)
# 8AM the same day as te
a8 = te.replace(hour=8, minute=0, second=0)
# Case-1: te and ts on the same day
if p8 > a8:
if te < a8 or ts > p8:
total = (te - ts).value
else:
total = max(0, (te - p8).value) + max(0, (a8 - ts).value)
# Below ts and te all in different days
# Case-2: te in z6
elif te > p8 + delta_1_day:
total = (te - p8 - delta_1_day + a8 - ts).value
# Case-3: ts in z1
elif ts < a8 - delta_1_day:
total = (a8 - delta_1_day - ts + te - p8).value
# Case-4: other cases
else:
total = (min(te, a8) - max(ts, p8)).value
return total + delta_days * ns_spent_in_1_day
df['total'] = df.apply(count_off_hour_in_ns, axis=1)
print(df)
t1 t2 total
0 1900-01-01 15:00:00 1900-01-01 18:35:00 0
1 1900-01-03 09:12:00 1900-01-05 10:54:00 86400000000000
2 1900-01-05 21:00:00 1900-01-06 23:48:00 53280000000000
3 1900-01-05 23:00:00 1900-01-06 20:48:00 35280000000000
4 1900-01-05 03:00:00 1900-01-06 02:48:00 42480000000000
5 1900-01-05 10:00:00 1900-01-06 05:48:00 35280000000000
6 1900-01-05 21:00:00 1900-01-06 10:48:00 39600000000000
Дайте мне знать, если это работает.