Split Time range into multiple time periods based on interval in Python

Question:

I have a time-range and an interval, I need to split the time range into multiple time periods based on interval value.

For example, time range is 9:30 to 11:30 and the interval is 30, the output time periods should be in a list as datetime objects

Output:

[
2020-08-24 9:30 - 2020-08-24 10:00,
2020-08-24 10:00 - 2020-08-24 10:30 
2020-08-24 10:30 - 2020-08-24 11:00, 
2020-08-24 11:00 - 2020-08-24 11:30
]
Asked By: Dinesh

||

Answers:

You can do arithmetic on datetime objects by adding timedelta objects.

You probably need to decide exactly what behaviour is required if the interval per period is not an exact divisor of the total, but this example would give a final short period in that case.

import datetime

tstart = datetime.datetime(2020,8,24,9,30)
tend = datetime.datetime(2020,8,24,11,30)
interval = datetime.timedelta(minutes=30)

periods = []

period_start = tstart
while period_start < tend:
    period_end = min(period_start + interval, tend)
    periods.append((period_start, period_end))
    period_start = period_end

print(periods)

This gives (with newlines inserted for readability):

[(datetime.datetime(2020, 8, 24, 9, 30), datetime.datetime(2020, 8, 24, 10, 0)),
 (datetime.datetime(2020, 8, 24, 10, 0), datetime.datetime(2020, 8, 24, 10, 30)),
 (datetime.datetime(2020, 8, 24, 10, 30), datetime.datetime(2020, 8, 24, 11, 0)),
 (datetime.datetime(2020, 8, 24, 11, 0), datetime.datetime(2020, 8, 24, 11, 30))]

For the string output format that you want, you could do something like this:

def format_time(dt):
    return dt.strftime("%Y-%m-%d %H:%M")

print(['{} - {}'.format(format_time(start), format_time(end))
       for start, end in periods])

to give:

['2020-08-24 09:30 - 2020-08-24 10:00',
 '2020-08-24 10:00 - 2020-08-24 10:30',
 '2020-08-24 10:30 - 2020-08-24 11:00',
 '2020-08-24 11:00 - 2020-08-24 11:30']
Answered By: alani

Using pandas.date_range

import pandas as pd

bins = pd.date_range(start='2020-08-24 9:30', end='2020-08-24 11:30', freq='30min').astype(str)
res = [' - '.join(x) for x in zip(bins[: -1], bins[1: ])]

print(res)

Output:

['2020-08-24 09:30:00 - 2020-08-24 10:00:00',
 '2020-08-24 10:00:00 - 2020-08-24 10:30:00',
 '2020-08-24 10:30:00 - 2020-08-24 11:00:00',
 '2020-08-24 11:00:00 - 2020-08-24 11:30:00']
Answered By: deadshot
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.