Split date range with time by day

Question:

I have a range of dates over time.
Example:

diapason = ["2020-11-02 17:40", "2020-11-05 10:00"]

and I want to get such a split:

diapason = [(2020-11-02 17:40, 2020-11-03 00:00), (2020-11-03 00:00, 2020-11-04 00:00), (2020-11-04 00:00, 2020-11-05 00:00), (2020-11-05 00:00, 2020-11-05 10:00)]

How can i do this? So far, I only manage to divide by 24 hours something like this:

from datetime import datetime,timedelta
diapason = ["2020-11-02 17:40", "2020-11-05 10:00"]

start = datetime.strptime(diapason[0], "%Y-%m-%d %H:%M")
end = datetime.strptime(diapason[1], "%Y-%m-%d %H:%M")
r = [(start + timedelta(days=i)).strftime("%Y-%m-%d %H:%M:%S.%f") for i in range(0, (end-start).days, 1)]

print(r)
Asked By: De1f

||

Answers:

First generate all the possible dates and add start and end timestamps. Sort them and finally iterate to get all the possible couples od timestamps.
Here an example:

diapason = ["2020-11-02 17:40", "2020-11-05 10:00"]
start = datetime.strptime(diapason[0], "%Y-%m-%d %H:%M")
end = datetime.strptime(diapason[-1], "%Y-%m-%d %H:%M")

dates = [datetime.strptime(str(date), "%Y-%m-%d %H:%M:%S") for date in pd.date_range(start.date() + timedelta(1), end.date())] + [start, end]
dates = sorted(dates)

diapason = []
for i in range(len(dates)-1):
    diapason.append((dates[i], dates[i+1]))

Which gives you:

[(datetime.datetime(2020, 11, 2, 17, 40), datetime.datetime(2020, 11, 3, 0, 0)),
 (datetime.datetime(2020, 11, 3, 0, 0), datetime.datetime(2020, 11, 4, 0, 0)),
 (datetime.datetime(2020, 11, 4, 0, 0), datetime.datetime(2020, 11, 5, 0, 0)),
 (datetime.datetime(2020, 11, 5, 0, 0), datetime.datetime(2020, 11, 5, 10, 0))]

You can then cast them as strings or reformat them if you prefer.

Answered By: Davide Anghileri

You can use:

diapason = ["2020-11-02 17:40", "2020-11-05 10:00"]

start = datetime.strptime(diapason[0], "%Y-%m-%d %H:%M")
end = datetime.strptime(diapason[1], "%Y-%m-%d %H:%M")

def d(date): return timedelta(hours=date.hour, minutes=date.minute, seconds=date.second)

r = [(start - d(start) + timedelta(days=i)).strftime("%Y-%m-%d %H:%M:%S.%f") for i in range(1, (end-start).days + 2)]
r = r + diapason
r.sort()
print(r)

which gives you

['2020-11-02 17:40',
 '2020-11-03 00:00:00.000000',
 '2020-11-04 00:00:00.000000',
 '2020-11-05 00:00:00.000000',
 '2020-11-05 10:00']
Answered By: Albo

Create a date range with the elements being lists, replace first and last elements with start / end datetime and format to tuples of strings:

from datetime import datetime, timedelta

diapason = ["2020-11-02 17:40", "2020-11-05 10:00"]
# diapason = ['2023-03-07 16:00:00','2023-03-14 19:00:00']

start, end = [datetime.fromisoformat(d) for d in diapason]
offset = 1 if start.time() <= end.time() else 2

output = [
    [start.date() + timedelta(d), start.date() + timedelta(d + 1)]
    for d in range((end - start).days + offset)
]

output[0][0], output[-1][-1] = start, end

output = [
    (l[0].strftime("%Y-%m-%d %H:%M"), l[1].strftime("%Y-%m-%d %H:%M")) for l in output
]

# output
# [('2020-11-02 17:40', '2020-11-03 00:00'),
#  ('2020-11-03 00:00', '2020-11-04 00:00'),
#  ('2020-11-04 00:00', '2020-11-05 00:00'),
#  ('2020-11-05 00:00', '2020-11-05 10:00')]
Answered By: FObersteiner
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.