find the closest datetime
139 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Luis Eduardo Cofré Lizama
el 2 de Mzo. de 2023
Comentada: Peter Perkins
el 13 de Mzo. de 2023
Hi All, I'm struggling with this one that seems not difficult. I have a datetime column with the format HH:mm:ss.SSSS and for which I'm loooking for the closest datapoint to a time in a format HH:mm:ss. I tried a simple substraction of my reference time from all elements in the timedate column to look for the minimum, however, the results are pretty odd. For example, if a substract my referecnce time 09:39:16 from a datetime point, e.g., 09:39:11.3333, the results is 1079663:59:55?. Below is what Im trying to use to get the closest time to a reference one:
a = min(abs(Datetimepoints - ReferenceDatetime));
In concrete I need to find a way to get the index of the closest datetime.
Thanks
0 comentarios
Respuesta aceptada
Stephen23
el 2 de Mzo. de 2023
Editada: Stephen23
el 2 de Mzo. de 2023
I have a datetime column with the format HH:mm:ss.SSSS and for which I'm loooking for the closest datapoint to a time in a format HH:mm:ss. I tried a simple substraction of my reference time from all elements in the timedate column to look for the minimum, however, the results are pretty odd. For example, if a substract my referecnce time 09:39:16 from a datetime point, e.g., 09:39:11.3333, the results is 1079663:59:55?"
Explanation
The reason is very simple (but so far no one picked up on this): you are subtracting DATETIMEs with very very different dates. Possibly because you thought that by changing the FORMAT it would only compare the time units. But in actual fact, changing the FORMAT makes absolutely no difference to the stored values and makes absolutely no difference to the values that get subtracted: those will always be the complete DATETIME, including all date units. Just because you can't see them does not not mean that they are not there.
This is very easy to demonstrate. With quick a bit of experimenting it seems that you used something a bit like an Excel date as the source, with an epoch around 1900:
dt1 = duration(09,39,16) + datetime(1900,0,0,1079663,59,55)
Now lets create a reference datetime (which also always includes date units, even if you hide them with the FORMAT):
dt0 = datetime(1900,0,0,09,39,16)
Now lets subtract them.
Subtracting two DATETIMEs returns a DURATION object showing the hours, minutes and seconds:
dt1-dt0
So far no surprises here: we just subtracted two points in time that are some 120 years apart, so of course there will be many many many hours between them. So far everything is behaving just as expected.
Solutions
1) Pay more attention to the epoch when importing/converting the data to DATETIME. For example, there are options the let you specify the epoch or date type e.g.:
2) Pay more attention to the differences between DATETIME and DURATION objects:
3) Use TIMEOFDAY to remove the date units and get pure DURATION objects:
d1 = timeofday(dt1)
d0 = timeofday(dt0)
d1-d0
And there are your five seconds.
3 comentarios
Stephen23
el 2 de Mzo. de 2023
Editada: Stephen23
el 2 de Mzo. de 2023
"However, I get a series of errors. Any suggestion?"
If you only need to compare the time of day, why not use TIMEOFDAY as I showed in my answer? Then the date values are irrelevant.
Otherwise please save the variable ReferenceDatetime in a MAT file and upload it here by clicking the paperclip button (or even better, upload the original data file).
Peter Perkins
el 13 de Mzo. de 2023
datetime(ReferenceDatetime, 'ConvertFrom','excel', ...) is expecting ReferenceDatetime to be an Excel day number. These are numeric values, e.g.
exceltime(datetime)
You are probably passing in something else. Stephen23's advice is on-target: it seems like you should be working with durations, not datetimes.
BTW, in case any thinks that
dt0 = datetime(1900,0,0,09,39,16)
is weird or wrong: what's the 0th month of 1900? Dec 1899. What's the 0th day of Dec 1899? 30 Nov 1899.
Más respuestas (2)
Steven Lord
el 2 de Mzo. de 2023
Let's make some sample dates and times within two-ish days of right now.
n = 10;
rightNow = datetime('now')
A = rightNow + hours(randi([-48 48], n, 1)) ...
+ minutes(randi([-60 60], n, 1)) ...
+ seconds(randi([-60 60], n, 1))
What's closest to right now?
interp1(A, A, rightNow, 'nearest')
Check:
results = table(A, abs(A-rightNow), VariableNames=["Date and Time", "Absolute Difference"])
Visual inspection of the Absolute Difference variable agrees with the result of interp1.
0 comentarios
DUY Nguyen
el 2 de Mzo. de 2023
Hi Luis,
You may check your datetime data again. You can have a look at the code below!
% Create some sample datetime points
Datetimepoints = datetime({'09:39:11.3333', '09:39:12.4444', '09:39:15.5555', '09:39:16.6666' }, 'Format', 'HH:mm:ss.SSSS');
% Define reference datetime
ReferenceDatetime = datetime('09:39:16', 'Format', 'HH:mm:ss');
% Compute the minimum difference between reference datetime and all datetime points
diffs = abs(Datetimepoints - ReferenceDatetime);
[min_diff, idx] = min(diffs);
% Print the closest datetime point and its index
fprintf('Closest datetime point: %s, Index: %d\n', Datetimepoints(idx), idx);
0 comentarios
Ver también
Categorías
Más información sobre Dates and Time en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!