Reputation: 175
My objective is to get the next closest date (in the future, not past) to today's date from a list. For simplicity's sake, the list (in the format of e.g. 2017-01-31
; YYYY-MM-DD
) is each football game in the season and I am trying to create a script that in part finds the "next" football game.
I have searched the internet and Stack Overflow for answers and found a promising post, however the solutions provided are using a different format and when I try to tailor it to mine, it trips exceptions.
My logic includes parsing an RSS feed, so I am just going to provide the raw list instead. With this in mind, my simplified code is as follows:
today = str(datetime.date.today())
print(today)
scheduledatelist = ['2017-09-01', '2017-09-09', '2017-09-16', '2017-09-23', '2017-09-30', '2017-10-07', '2017-10-14', '2017-10-21', '2017-10-27', '2017-11-11', '2017-11-18', '2017-11-25']
scheduledatelist = list(reversed(scheduledatelist)) #purpose: to have earliest dates first
This is my attempt at adapting the previous post's solution (I am not well versed in functional programming, so I may not be adapting it right):
get_datetime = lambda s: datetime.datetime.strptime(s, "%Y-%m-%d")
base = get_datetime(today)
later = filter(lambda d: today(d[0]) > today, scheduledatelist)
closest_date = min(later, key = lambda d: today(d[0]))
print(closest_date)
Regardless of my attempt (which may not be the best in my situation as it changes the format and I need the end value to still be YYYY-MM-DD
), is there an easier way of doing this? I need that next game (closest to today) value as that will continue on to be used in my logic. So to recap, how can I find the closest date in my list, looking toward the future, from today. Thank you for your help!
Upvotes: 1
Views: 7125
Reputation: 103714
You can do:
min(scheduledatelist, key=lambda s:
datetime.datetime.strptime(s, "%Y-%m-%d").date()-datetime.date.today())
For the single closest date to today.
You can use the same function to sort by distance from today:
sorted(scheduledatelist, key=lambda s:
datetime.datetime.strptime(s, "%Y-%m-%d").date()-datetime.date.today())
And the returned list will be in increasing distance in days from today. Works if the dates are before or after today.
If you want only dates in the future, filter out the dates in the past. Since the date strings are in ISO 8601 format, you can compare lexically:
min([d for d in scheduledatelist if d>str(datetime.date.today())], key=lambda s:
datetime.datetime.strptime(s, "%Y-%m-%d").date()-datetime.date.today())
Upvotes: 3
Reputation: 10953
first of all let's create datetime.date
objects from strings using datetime.datetime.strptime
and datetime.datetime.date
methods since datetime.date
objects are ordered and easier to work with:
date_format = '%Y-%m-%d'
dates = [datetime.datetime.strptime(date_string,
date_format).date()
then let's filter out dates that take place in future (after today)
today = datetime.date.today()
future_dates = [date
for date in dates
if date >= today]
then we can simply find next closest date using min
next_closest_date = min(future_dates)
which gives us
>>>next_closest_date
2017-09-01
for given example
If there is no dates going after today this will cause error like
ValueError: min() arg is an empty sequence
if it's ok then we can leave it, but if we don't want to get errors – we can specify default value for min
in case of empty sequence like
next_closest_date = min(future_dates, default=None)
Finally we can write a function as follows
import datetime
# `default` value is returned when there is no future date strings found
def get_next_closest_date(date_strings, date_format, default=None):
today = datetime.date.today()
dates = [datetime.datetime.strptime(date_string,
date_format).date()
for date_string in date_strings]
future_dates = [date
for date in dates
if date >= today]
return min(future_dates, default)
and use it like
scheduledatelist = ['2017-09-01', '2017-09-09', '2017-09-16', '2017-09-23',
'2017-09-30', '2017-10-07', '2017-10-14', '2017-10-21',
'2017-10-27', '2017-11-11', '2017-11-18', '2017-11-25']
next_closest_date = get_next_closest_date(date_strings=scheduledatelist,
date_format='%Y-%m-%d')
print(next_closest_date)
Upvotes: 2