# Add a 1 minute tolerance when comparing datetimes

2 views (last 30 days)
Arthur Romeu on 5 Feb 2020
Commented: Star Strider on 7 Feb 2020
Hello there!
I currently have a loop that compares two sets of datetimes and if there is no match, then it adds the time in question to an array. It goes as follows:
c = 1
for k = 1:size(TR_SoftStart,1)
if find(PC_SoftStart == TR_SoftStart.Data(k)) ~= 0,
disp(k)
else
errors_SoftStart(c,:) = TR_SoftStart(k,:);
c = c + 1;
end
end
I'll attach PC_SoftStart and TS_SoftStart for a better understanding.
However, I need to add a +1min -1min tolerance to that comparison, and I truly don't know how to do it.
In essence, I need to compare two sets of datetimes (PC_SoftStart and TS_SoftStart) and log every 2min+ discrepancy on errors_SoftStart.
Does anyone have a clue on where to begin?
Arthur.

Star Strider on 6 Feb 2020
I am not certain what you want, since the tables are difficult to interpret.
Try this to see if it provides the necessary result:
c = 1
for k = 1:size(TR_SoftStart,1)
Years = abs(year(PC_SoftStart) - year(TR_SoftStart.Data(k))) < 1; % Same Year
Months = abs(month(PC_SoftStart) - month(TR_SoftStart.Data(k))) < 1; % Same Month
Days = abs(day(PC_SoftStart) - day(TR_SoftStart.Data(k))) < 1; % Same Day
Hours = abs(hour(PC_SoftStart) - hour(TR_SoftStart.Data(k))) < 1; % Same Hour
Minutes = abs(minute(PC_SoftStart) - minute(TR_SoftStart.Data(k))) <= 1; % ±1 Minute
Test = Years & Months & Days & Hours & Minutes; % Logical ‘and’
if any(Test,'all') % The ‘find’ Call Is Not Necessary (Not Returning Any Indices)
disp(k)
else
errors_SoftStart(c,:) = TR_SoftStart(k,:);
c = c + 1;
end
end
end
I did my best to document how the code works in the comments. Briefly, rather than doing a direct equality comparison, it subtracts the relevant parts of the datetime variables, and then the minute values of the datetime values in the two table arrays from each other, takes the absolute value of the difference (implicitly accounting for the ±1 minute), and tests to see if it is less than or equal to 1. (The results of the subtraction are integers, so floating-point approximation error is not a concern.) It then uses the any function to see if there are any values in the ‘Test’ logical matrix, and proceeds with the rest of your code. I eliminated the find call, since it is redundant here (you are not returning any indices).
I checked the code by printing (here for the minute values, also for the others):
Check1 = minute(PC_SoftStart(1:4,:)) - minute(TR_SoftStart.Data(k))
Check2 = abs(minute(PC_SoftStart(1:4,:)) - minute(TR_SoftStart.Data(k)))
Check3 = Test(1:4,:)
View = [any(Test,'all') sum(Test,'all')]
to the Command Window to be certain the code does what I want it to for the first two iterations of the loop, and it does. (I did not include those assignments in the code I posted here, since they are diagnostic only. I include them in the event you want to check that yourself.)
I did not get good results from subtracting the complete datetime values, so I decided to do the subtraction on each part of the datetime values, then logically combine them (&) to get the result. It might be possible to do this with datenum arrays, however they introduce other problems, so I decided to do this with datetime arrays instead.
I thought about I would approach this for most of the day, and finally came up with this code, that appears to work. It is an interesting problem, and I learned a bit in the process of creating it!

Arthur Romeu on 7 Feb 2020
Once again you've chosen a brilliant path to execute this. Thank you! I learn a lot from your answers too.
Star Strider on 7 Feb 2020
As always, my pleasure!
Thank you!