# Closest date to another

30 views (last 30 days)
Curious Mind on 6 Feb 2020
Commented: Adam Danz on 14 Feb 2020
I have the code below which compares and extract the closest date & time in data1 to data2. It works well but I don’t want duplicates. That is if a closest date in data1 is already assigned to another date in data2, that closest date cannot be assigned again. Instead the nearest closest date should be chosen. No closest data in data1 should be used twice.
[~,ind1] = min(abs(datenum(data2)-datenum(data1))); closest_time = data2(ind1,:)
Any thoughts?
Thanks!

Adam Danz on 6 Feb 2020
Edited: Adam Danz on 6 Feb 2020
A simple, readable, and fast method would be to loop through the dates in date1, find the closest date in date2, and then replace that date in date2 with NaT so it won't be chosen again. That's what this demo does.
Inputs: two row vectors of dates in datetime format: dates1 & dates2
Outputs: nearestIdx(j) is the closest non-repeated date in date2 to date1(j); m is a nx2 matrix of paired dates.
% Create two arrays of random dates (may contain repeated dates)
dates1 = datetime(2019,1,1)+days(sort(randi(364,1,100)));
dates2 = datetime(2018,12,28)+days(sort(randi(364,1,100)));
% Loop through the dates in date1
nearestIdx = nan(size(dates1)); % Pre allocation
dates2Temp = dates2; % Make a temp copy of dates2 for NaT replacement
for i = 1:numel(dates1)
[~, nearestIdx(i)] = min(abs(dates2Temp - dates1(i))); % find index of closest date
dates2Temp(nearestIdx(i)) = NaT; % replace that date with NaT
end
% Sanity check: all of the values in nearestIdx should be unique
assert(numel(unique(nearestIdx))==numel(dates1),'Sanity check failure: unique date matching error.')
% Match the dates (dates1 and dates2 must have same size)
m = [dates1.', dates2(nearestIdx).']

Curious Mind on 11 Feb 2020
Perfect. Makes sense. Thanks!
Curious Mind on 13 Feb 2020
@Adam Danz. So everything looks great! Compared the dates and extracted the closest datetime and it’s corresponding data! As you know, for the current code, if I have 2/1/2016 11:42, 2/1/2016 11:43, and 2/1/2016 11:44. The closest value datetime to 2/1/2016 11:43 is 2/1/2016 11:42. Now what if I want to select the second highest datetime to 2/1/2016 11:43? In this case it will be 2/1/2016 11:44. I want to insert a function in the loop to do this. Compare dates1 to dates2 and select the indexes of all second nearest/highest datetime in dates2 to dates1. As usual, no datetime in dates2 can be selected twice. I appreciate it. I’m still learning.
Adam Danz on 14 Feb 2020