Olga
Olga

Reputation: 103

Split the date range by days and make list of list date interval with Python

I have range of dates like "2017-05-01", "2017-05-18". So, I want to split this range by daily intervals and get such result: [["2017-05-01","2017-05-02"], ["2017-05-3","2017-05-04"], ....]

Upvotes: 4

Views: 5352

Answers (3)

rsz
rsz

Reputation: 177

Create duos

Here is a solution with datetime.timedelta(days=1). You can easily reduce this code.

import datetime


input_dates = ['2017-05-01', '2017-05-17']
date_format = "%Y-%m-%d" # Format

# Set the range
start_date = datetime.datetime.strptime(input_dates[0], date_format)
end_date = datetime.datetime.strptime(input_dates[1], date_format)

# You can have the difference in days with this :
delta = (end_date - start_date)
diff_days = delta.days
print "Days diff : {}".format(diff_days) # Comment it

duos_list = []

for step in xrange(0, diff_days + 1, 2):
    date_1 = start_date + (datetime.timedelta(days=1) * step)
    date_2 = date_1 + datetime.timedelta(days=1)

    duo = [date_1.strftime(date_format)]
    # Not append date_2 if not in range
    if date_2 <= end_date:
        duo.append(date_2.strftime(date_format))

    # Append the duo of date on the result list
    duos_list.append( duo )

print repr(duos_list)

Output :

Days diff : 16
[['2017-05-01', '2017-05-02'], ['2017-05-03', '2017-05-04'], ..., ['2017-05-17']]

or chunk it

In other approach (better way I think), you can also chunk the list :

import datetime


input_dates = ['2017-05-01', '2017-05-17']
date_format = "%Y-%m-%d" # Format
chunk_size = 2

# Set the range
start_date = datetime.datetime.strptime(input_dates[0], date_format)
end_date = datetime.datetime.strptime(input_dates[1], date_format)

# You can have the difference in days with this :
delta = (end_date - start_date)
diff_days = delta.days

print "Days diff : {}".format(diff_days)

# Create the list of date
date_list = [ (start_date + (datetime.timedelta(days=1) * x)).strftime(date_format)  for x in xrange(0, diff_days + 1)]

# Chunk this with correct size (2)
chunked_list = [date_list[i:i + chunk_size] for i in xrange(0, len(date_list), chunk_size)]

print repr(chunked_list)

Output :

Days diff : 16
[['2017-05-01', '2017-05-02'], ['2017-05-03', '2017-05-04'], ..., ['2017-05-17']]

Upvotes: 0

Phil H
Phil H

Reputation: 20131

Firstly, decompose this into two steps:

  1. Generate every day from one date to another
  2. Convert a list [a,b,c,d] into pairs [[a,b],[c,d]]

For the first step, there is an answer here: Iterating through a range of dates in Python in which the following generator is defined:

from datetime import timedelta, date

def daterange(start_date, end_date):
    for n in range(int ((end_date - start_date).days)):
        yield start_date + timedelta(n)

If we then pair those using this definition from the itertools documentation:

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

So then we can compose those together to make the required generator:

daypairs = grouper(daterange(start_date, end_date), 2)

And listify it thus:

daypairslist = list(daypairs)

etc.

Upvotes: 3

McGrady
McGrady

Reputation: 11477

You can try this, first convert strings to datetime and get the interval and use a list comprehension to generate the list:

from datetime import datetime,timedelta
st=["2017-05-01", "2017-05-19"]
n=2

start=datetime.strptime(st[0],"%Y-%m-%d")
end=datetime.strptime(st[1],"%Y-%m-%d")

r = [[(start+ timedelta(days=i)).strftime("%Y-%m-%d"),(start+ timedelta(days=i+1)).strftime("%Y-%m-%d")] if i!=(end-start).days else [(start+ timedelta(days=i)).strftime("%Y-%m-%d")] for i in range(0,(end-start).days+1,2)]

print r

Result:

[['2017-05-01', '2017-05-02'], ['2017-05-03', '2017-05-04'], ['2017-05-05', '2017-05-06'], ['2017-05-07', '2017-05-08'], ['2017-05-09', '2017-05-10'], ['2017-05-11', '2017-05-12'], ['2017-05-13', '2017-05-14'], ['2017-05-15', '2017-05-16'], ['2017-05-17', '2017-05-18'], ['2017-05-19']]

Upvotes: 2

Related Questions