Python – Divide date range to N equal duration

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)

Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out - check it out now!

Previous
Next