0

If I have an array of dates like the following:

array = [{'date': '09-Jul-2018'}, 
         {'date': '09-Aug-2018'}, 
         {'date': '09-Sep-2018'}]

and I have a date like the following 17-Aug-2018.

can anyone advise the best way to check for the closest date, always in the past?

I have tried the following, but to no avail.

closest_date

 for i in range(len(array)):
    if(date > array[i].date and date < array[i + 1].date):
        closest_date = array[i]
peter flanagan
  • 9,195
  • 26
  • 73
  • 127

5 Answers5

2

My approach first creates a list of datetime objects from your list of dicts, and then simply sorts the dates while comparing with the input date.

input_dt = datetime.strptime('17-Aug-2018', '%d-%b-%Y')
sorted(
    map(lambda date: datetime.strptime(date['date'], '%d-%b-%Y'), array),
    key=lambda dt: (input_dt - dt).total_seconds() if dt < input_dt else float("inf"),
)[0].strftime('%d-%b-%Y')
ruhaib
  • 604
  • 5
  • 12
2

Follows yet another approach:

from datetime import datetime

convert = lambda e: datetime.strptime(e, '%d-%b-%Y')

array = [{'date': '09-Jul-2018'}, 
         {'date': '09-Aug-2018'}, 
         {'date': '09-Sep-2018'}]

ref = convert("17-Aug-2018")

transform = ((convert(elem['date']), elem['date']) for elem in array)
_, closest_date = max((elem for elem in transform if (elem[0] - ref).days < 0), key = lambda e: e[0])
print(closest_date)

Output is

09-Aug-2018

Hope this helps.

Simone
  • 11,655
  • 1
  • 30
  • 43
1

If the dates in your dictionary are timestamps here is a way to do it :

from datetime import date

closest_date = min([x['date'] for x in array])
date = date(2018, 8, 17)

for element in array:
    current_date = element['date']
    if  current_date < date and current_date>closest_date:
        closest_date = current_date
# Output : datetime.date(2018, 8, 9)

If your dates are not in the timestamp format, here is a way to convert them easily :

from datetime import datetime

array = [ {'date' : datetime.strptime(s['date'],'%d-%b-%Y')} for s in array] 
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
vlemaistre
  • 3,301
  • 13
  • 30
1

This is one approach.

Ex:

import datetime

array = [{'date': '09-Jul-2018'}, 
         {'date': '09-Aug-2018'}, 
         {'date': '09-Sep-2018'}]

to_check = "17-Aug-2018"
to_check = datetime.datetime.strptime(to_check, "%d-%b-%Y")

closest_dates = []
val = 0
for date in array:
    date_val = datetime.datetime.strptime(date["date"], "%d-%b-%Y")
    if date_val <= to_check:
        closest_dates.append({(to_check - date_val).days: date["date"]})
print(min(closest_dates, key=lambda x: x.items()[0]))

Output:

{8: '09-Aug-2018'}
Rakesh
  • 81,458
  • 17
  • 76
  • 113
0

I would advise you to use always vectorised operations in NumPy. It is always much faster :D. I would do it this way:

import numpy as np
import datetime
dates = np.array(list(map(lambda d: datetime.datetime.strptime(d["date"], "%d-%b-%Y"), array)))

differences = dates - datetime.datetime.strptime("17-Aug-2018", "%d-%b-%Y")
differences = np.vectorize(lambda d: d.days)(differences) 
differences[differences >= 0] = -9e9

most_recent_date = dates[np.argmax(differences)]
ivallesp
  • 2,018
  • 1
  • 14
  • 21