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)) |
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()
- Here’s an alternative approach using numpy’s linspace() function, which generates N evenly spaced points between two dates:
- Import numpy and datetime modules:
- Define the start and end dates:
- Define N, the number of equal durations:
- Use linspace() to generate N evenly spaced points between start_date and end_date:
- Convert the Unix timestamps back to datetime objects and format them as desired:
- 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:
- Import the pandas library.
- Define the start and end dates as test_date1 and test_date2, respectively.
- Define the number of equal durations as N.
- Calculate the duration between the start and end dates by subtracting test_date1 from test_date2.
- Divide the duration by N to get the frequency.
- Use the date_range() function to generate the range of dates with the specified frequency.
- Convert the resulting dates to the desired format using the strftime() method.
- 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)
Please Login to comment...