Open In App

Python – Divide date range to N equal duration

Last Updated : 17 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two dates, the task is to divide it into equal time duration and get the exact time of each division point.

Input : test_date1 = datetime.datetime(1997, 1, 4), test_date2 = datetime.datetime(1997, 1, 30)  N = 7
Output : [datetime.datetime(1997, 1, 4, 0, 0), datetime.datetime(1997, 1, 7, 17, 8, 34, 285714), datetime.datetime(1997, 1, 11, 10, 17, 8, 571428), datetime.datetime(1997, 1, 15, 3, 25, 42, 857142), datetime.datetime(1997, 1, 18, 20, 34, 17, 142856), datetime.datetime(1997, 1, 22, 13, 42, 51, 428570), datetime.datetime(1997, 1, 26, 6, 51, 25, 714284)]
Explanation : List of dates of size 7 are returned with each date having equal delta between them.

Input : test_date1 = datetime.datetime(1997, 1, 4), test_date2 = datetime.datetime(1997, 1, 30) N = 4
Output : [datetime.datetime(1997, 1, 4, 0, 0), datetime.datetime(1997, 1, 10, 12, 0), datetime.datetime(1997, 1, 17, 0, 0), datetime.datetime(1997, 1, 23, 12, 0)]
Explanation : List of dates of size 4 are returned with each date having equal delta between them.

Method #1: Using loop

In this, we compute each segment duration using division of whole duration by N. Post that, each date is built using segment duration multiplication in loop.

Python3




# Python3 code to demonstrate working of
# Convert date range to N equal durations
# Using loop
import datetime
 
# initializing dates
test_date1 = datetime.datetime(1997, 1, 4)
test_date2 = datetime.datetime(1997, 1, 30)
              
# printing original dates
print("The original date 1 is : " + str(test_date1))
print("The original date 2 is : " + str(test_date2))
 
# initializing N
N = 7
 
temp = []
 
# getting diff.
diff = ( test_date2 - test_date1) // N
for idx in range(0, N):
     
    # computing new dates
    temp.append((test_date1 + idx * diff))
 
# using strftime to convert to userfriendly
# format
res = []
for sub in temp:
  res.append(sub.strftime("%Y/%m/%d %H:%M:%S"))
 
# printing result
print("N equal duration dates : " + str(res))


Output:

The original date 1 is : 1997-01-04 00:00:00

The original date 2 is : 1997-01-30 00:00:00

N equal duration dates : [‘1997/01/04 00:00:00’, ‘1997/01/07 17:08:34’, ‘1997/01/11 10:17:08’, ‘1997/01/15 03:25:42’, ‘1997/01/18 20:34:17’, ‘1997/01/22 13:42:51’, ‘1997/01/26 06:51:25’]

Time complexity: The time complexity of the program is O(N), where N is the number of equal durations. 

Auxiliary space: The auxiliary space complexity of the program is O(N) because we are using a temporary list temp to store N equal duration dates, and another list res to store the result after converting the dates to user-friendly format using strftime(). The size of both lists is N,

Method #2: Using generator function

In this, we perform task of yielding intermediate result using generator function rather than loop approach. Only difference is that intermediate result is returned. 

Python3




# Python3 code to demonstrate working of
# Convert date range to N equal durations
# Using generator function
import datetime
 
def group_util(test_date1, test_date2, N):
     
    diff = (test_date2  - test_date1 ) / N
    for idx in range(N):
         
        # using generator function to solve problem
        # returns intermediate result
        yield (test_date1 + diff * idx)
    yield test_date2
     
# initializing dates
test_date1 = datetime.datetime(1997, 1, 4)
test_date2 = datetime.datetime(1997, 1, 30)
              
# printing original dates
print("The original date 1 is : " + str(test_date1))
print("The original date 2 is : " + str(test_date2))
 
# initializing N
N = 7
 
# calling generator expression
temp = list(group_util(test_date1, test_date2, N))
 
# using strftime to convert to userfriendly format
res = []
for sub in temp:
  res.append(sub.strftime("%Y/%m/%d %H:%M:%S"))
 
# printing result
print("N equal duration dates : " + str(res))


Output:

The original date 1 is : 1997-01-04 00:00:00

The original date 2 is : 1997-01-30 00:00:00

N equal duration dates : [‘1997/01/04 00:00:00’, ‘1997/01/07 17:08:34’, ‘1997/01/11 10:17:08’, ‘1997/01/15 03:25:42’, ‘1997/01/18 20:34:17’, ‘1997/01/22 13:42:51’, ‘1997/01/26 06:51:25’, ‘1997/01/30 00:00:00’]

Time complexity: O(N) for the generator function, where N is the number of equal durations to be generated.

Auxiliary space: O(N) for the temporary list, where N is the number of equal durations to be generated. 

Method #3: Using list comprehension

This code produces the same output as the original code. The group_util function now returns a list instead of a generator, and the list comprehension is used to convert the dates to strings in the desired format.

Python3




import datetime
 
def group_util(test_date1, test_date2, N):
    diff = (test_date2 - test_date1) / N
    return [test_date1 + diff * idx for idx in range(N)] + [test_date2]
 
test_date1 = datetime.datetime(1997, 1, 4)
test_date2 = datetime.datetime(1997, 1, 30)
N = 7
 
res = [date.strftime("%Y/%m/%d %H:%M:%S") for date in group_util(test_date1, test_date2, N)]
 
print("N equal duration dates : " + str(res))


Output

N equal duration dates : ['1997/01/04 00:00:00', '1997/01/07 17:08:34', '1997/01/11 10:17:08', '1997/01/15 03:25:42', '1997/01/18 20:34:17', '1997/01/22 13:42:51', '1997/01/26 06:51:25', '1997/01/30 00:00:00']

Time complexity: O(N), where N is the number of equal durations to generate.
Auxiliary space: O(N), where N is the number of equal durations to generate. 

Method #4: Using numpy.linspace()

  1. Here’s an alternative approach using numpy’s linspace() function, which generates N evenly spaced points between two dates:
  2. Import numpy and datetime modules:
  3. Define the start and end dates:
  4. Define N, the number of equal durations:
  5. Use linspace() to generate N evenly spaced points between start_date and end_date:
  6. Convert the Unix timestamps back to datetime objects and format them as desired:
  7. Print the result:

Python3




import numpy as np
import datetime
 
# Define start and end dates
start_date = datetime.datetime(1997, 1, 4)
end_date = datetime.datetime(1997, 1, 30)
 
# Define N, the number of equal durations
N = 7
 
# Generate N evenly spaced points between start_date and end_date
durations = np.linspace(start_date.timestamp(), end_date.timestamp(), N)
 
# Convert the Unix timestamps back to datetime objects and format them as desired
res = [datetime.datetime.fromtimestamp(duration).strftime("%Y/%m/%d %H:%M:%S") for duration in durations]
 
# Print the result
print("N equal duration dates: " + str(res))


OUTPUT: 

N equal duration dates: ['1997/01/04 00:00:00', '1997/01/08 08:00:00', '1997/01/12 16:00:00', '1997/01/17 00:00:00', '1997/01/21 08:00:00', '1997/01/25 16:00:00', '1997/01/30 00:00:00']

Time complexity: O(N), where N is the number of equal durations.

Auxiliary space: O(N), since we store N datetime objects in the durations list.

Method #5: Using pandas.date_range()

The pandas library in Python provides a built-in function date_range() which can be used to generate a range of dates with specified frequency. We can use this function to solve the problem of converting a date range to N equal durations.

step-by-step approach:

  1. Import the pandas library.
  2. Define the start and end dates as test_date1 and test_date2, respectively.
  3. Define the number of equal durations as N.
  4. Calculate the duration between the start and end dates by subtracting test_date1 from test_date2.
  5. Divide the duration by N to get the frequency.
  6. Use the date_range() function to generate the range of dates with the specified frequency.
  7. Convert the resulting dates to the desired format using the strftime() method.
  8. Print the result.

Python3




import pandas as pd
import datetime
 
# initializing dates
test_date1 = datetime.datetime(1997, 1, 4)
test_date2 = datetime.datetime(1997, 1, 30)
              
# printing original dates
print("The original date 1 is : " + str(test_date1))
print("The original date 2 is : " + str(test_date2))
 
# initializing N
N = 7
 
# calculating frequency
duration = test_date2 - test_date1
freq = duration // N
 
# using pandas date_range to generate the range of dates
date_range = pd.date_range(start=test_date1, end=test_date2, freq=freq)
 
# converting to desired format
res = date_range.strftime("%Y/%m/%d %H:%M:%S").tolist()
 
# printing result
print("N equal duration dates : " + str(res))


OUTPUT :
The original date 1 is : 1997-01-04 00:00:00
The original date 2 is : 1997-01-30 00:00:00
N equal duration dates : ['1997/01/04 00:00:00', '1997/01/07 17:08:34', '1997/01/11 10:17:08', '1997/01/15 03:25:42', '1997/01/18 20:34:17', '1997/01/22 13:42:51', '1997/01/26 06:51:25', '1997/01/29 23:59:59']

Time complexity: O(1) (since the number of iterations is constant)
Auxiliary space: O(N) (for storing the list of dates)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads