Reputation: 3485
I have a list of dates. And given a specific input date, want to find the previous date in the list. Example is:
my_dates_list = ['2019-01-31', '2019-02-28', '2019-03-31', '2019-04-30', '2019-05-31', '2019-06-30'].
InputDate = '2019-07-15'
the output should be '2019-06-30' because it is the previous date of the InputDate
found in the list. Note that the InputDate
is not necessarily found in the my_dates_list
.
Another example: if InputDate
is '2019-03-01', the output should be 2019-02-28
.
Upvotes: 1
Views: 1908
Reputation: 1
A solution using bisect(Python Standard Library):
from bisect import bisect
def get_previous_date(dt: datetime, dates_list: list):
dt_index = bisect(dates_list, dt)
return sorted_list[dt_index-1] if dt_index != 0 else dt
Upvotes: 0
Reputation: 1
Аnother simple solution. It's not only suitable for dates.
def previous_date(dt: datetime, dates_list: list):
""" get previous date"""
dates_list.append(dt)
sorted_list = sorted(set(dates_list))
dt_index = sorted_list.index(dt)
return sorted_list[dt_index-1] if dt_index != 0 else dt
Upvotes: 0
Reputation: 88226
One approach could be to subtract the InputDate
to each date in the list, find the minimum element (greater than 0) in the list and use it to index my_dates_list
:
import datetime as datetime
in_date = datetime.datetime.strptime(InputDate, '%Y-%m-%d')
l = [in_date - datetime.datetime.strptime(i, '%Y-%m-%d') for i in my_dates_list]
# [datetime.timedelta(165), datetime.timedelta(137), datetime.timedelta(106)...
my_dates_list[l.index(min(i for i in l if i>datetime.timedelta(0)))]
# '2019-06-30'
Upvotes: 1
Reputation: 2757
Filter the list of dates which is no bigger than InputDate, then take the 'largest' value.
max([x for x in my_dates_list if InputDate >= x])
or
max(my_dates_list, key= lambda x:x if x<=InputDate else '0')
Upvotes: 0
Reputation: 82755
Try using min
with a custom key
Ex:
import datetime
my_dates_list = ['2019-01-31', '2019-02-28', '2019-03-31', '2019-04-30', '2019-05-31', '2019-06-30']
InputDate = datetime.datetime.strptime('2019-07-15', '%Y-%m-%d')
print(min(my_dates_list, key=lambda x: InputDate - datetime.datetime.strptime(x, '%Y-%m-%d')))
# --> 2019-06-30
Upvotes: 0
Reputation: 587
A solution using pandas.
import pandas as pd
my_dates_list = ['2019-01-31', '2019-02-28', '2019-03-31', '2019-04-30', '2019-05-31', '2019-06-30']
test_date = '2019-03-01'
# change to datetime
my_dates_list = pd.to_datetime(my_dates_list)
test_date = pd.to_datetime(test_date)
# get less than test date, sort and take first value
my_dates_list[my_dates_list < test_date].sort_values(ascending=False)[0]
Upvotes: 1
Reputation: 61
The easiest way is to combine the search of year/month/day and put an if-condition in a while-loop to check if the date is in the list; otherwise, it has to decrease the day maintaining the same month/year. If the search gives out no results, then it has to decrease the month, and eventually the year. It is a brute force solution, but it should work.
Upvotes: 0
Reputation: 306
You could convert the strings into datetime objects (for example pd.datetime
) and then just find the maximum value that is smaller than the date you are looking for:
import pandas as pd
my_dates_list = ['2019-01-31', '2019-02-28', '2019-03-31', '2019-04-30', '2019-05-31', '2019-06-30']
InputDate = '2019-07-15'
my_dates_list = pd.to_datetime(my_dates_list)
InputDate = pd.to_datetime(InputDate)
print(max(my_dates_list[my_dates_list<InputDate]))
This returns
2019-06-30 00:00:00
Upvotes: 0