How to subtract time in million second precision?

I have 2 table arrays of date(1st column) and time (2nd column) and I would like to check the time difference. Could you kindly advise?
My second values are in million second precision, e.g., 11:34:08.471810 and 11.34.06.471840 (as attached picture) How may I go about getting the time difference? I understand some of MATLAB function has limitation till millisecond. Have tried a few stuff (datevec, datenum, etc.) but not getting the precise results.
Thank you.

 Accepted Answer

The picture you attached shows 5 decimal places of seconds. That is right at the boundary of accuracy possible with datenum; datenum cannot actually represent down to 10^-5 seconds, but it can represent to 1.0058E-5 seconds -- at least for modern times.
Your question, though, lists down to 10^-6 seconds, which definitely more accurate than datenum can justify.
My advice would be to use datetime() instead of datenum().
in_datestr = strcat(tab.carlog_date_final, {' '}, tab.carlog_time_final);
in_dates = datetime(in_datestr,'InputFormat', 'd-M-yyyy hh:mm:ss.SSSSS', 'Format', 'yyyy/MM/dd hh:mm:ss.SSSSS');
After that you can
seconds(diff(in_dates)) * 10^6
or as appropriate for the time scale you wish to pay attention to.
(Note: you do not actually need the 'Format' option for the datetime() call if you are only looking at the differences -- but it is nice to be able to debug that the milliseconds have been converted properly.)

12 Comments

Hi Walter thank you for the reply. However, I am using datetime but the difference value is not accurate.. My actual motive is to find the closest match of time between two time array and then copy the closest time's speed (3rd column in carlog) to another new array.. so as to sync the closest time..
e.g. if second column is time (its in HH:MM:SS.SSSSSS format but I am just stating as Min.Sec format for simplicity below)
a(1,2) = 2.2s , a(2,2) = 3.1s, a(3,2) = 4.5s..
b(1,2) = 2s, b(2,2) = 3s, etc..
Since b(1,2) value is closest to a( 1,2).. c(1) = a(1,3) %third column has the speed information.. so it should get the index of the closest match of time and get third column of a and copy to a new array c. I would like to get speed info for all the 3487 gsr data (with respect to closest match of time with carlog)..
My partial code is as the following..
for i = 1:numcarlog %this has 31982 x 7 data
for j = 1:numgsrdata %this has 3487 x 2 data
carlogtime = datetime(carlogvalstr,'Format','HH:mm:ss.SSSSSS'); %works ok..
gsrtime = datetime(gsrvalstr,'Format','HH:mm:ss.SSSSSS') %works ok..
t2 = abs(carlogtime - gsrtime) %does not work.. it just changes the precision to HH.MM.SS
[idx idx] = min(t2) %index of closest value.. does not work.. just shows as [1 1]
speed_gsr1 = carlog_values(idx,3) %does not work
end % end of j
speed_gsr(j,:) = speed_gsr1 %does not work
end % end of i
Please feel free to comment
If your carlogvalstr and gsrvalstr are not changing inside the loop, then you should be pre-calculating the datetime before the loop for efficiency.
As your two values do not appear to be changing, the conversion is always going to give the same result, and the min() would always give the same result (whatever it turned out to be.) If carlogvalstr and gsrvalstr do not encode multiple times then carlogtime and gsrtime are going to be scalars and min() of a scalar is alwas going to give index 1.
apologies, they are changing.. I just did not put the whole thing so as not to confuse you..
for i = 1:numcarlog
for j = 1:numgsrdata
format long
carlogvalstr = cell2mat(carlog_start_date_time(i,2)); %i had put date and time as cell data to test if it works.. %same result as table, this is working..
carlogtime = datetime(carlogvalstr,'Format','HH:mm:ss.SSSSSS'); %works fine
format long
gsrvalstr = cell2mat(final_start_date_time(j,2)); %works fine
gsrtime = datetime(gsrvalstr,'Format','HH:mm:ss.SSSSSS'); %works fine
t2 = abs(carlogtime - gsrtime)
[idx idx] = min(t2) %index of closest value
speed_gsr1 = carlog_values(idx,3)
end
speed_gsr(j,:) = speed_gsr1
end
You need InputFormat not just Format I suspect.
Datetime is working well. It's the difference and closest index not working..
But you are pulling out individual times so the difference is a scalar and the index of the min() of a scalar is always 1.
You should be converting all of your times before the loop.
temp = abs(bsxfun(@minus, carlogtimes(:), gpstimes(:).'))
Now
[~, idx] = min(temp,[], 2)
idx is now a vector of indexes, one for each carlogtimes, of the closest location in the gpstimes. No looping required for that part.
Dont think it applies to get difference of time... received error
Error using bsxfun Operands must be numeric arrays.
Error in timesync2 (line 138) temp = abs(bsxfun(@minus, carlogtime(:), gsrtime(:)))
repmat the column vector carlogtime to have as many columns as length of gsrtime. repmat the row vector gsrtime to have as many columns as length of carlogtime. Subtract the two. Take abs()
With R2016b or later, instead of using repmat, use
temp = abs(carlogtime(:) - gsrtime(:).')
Note: the transpose is important for this. I notice you omitted the transpose in your bsxfun attempt; that would have caused a problem if bsxfun were able to handle datetime or duration arrays.
temp = abs(carlogtime(:) - gsrtime(:).');
Error using timesync2 (line 178)
Matrix dimensions must agree.
>> temp = abs(bsxfun(@minus, carlogtime(:), gsrtime(:).'))
Error using bsxfun
Operands must be numeric arrays.
... and are you in fact using R2016b or later?
If not, then like I wrote above,
abs(repmat(carlogtime(:), 1, length(gsrtime)) - repmat(gsrtime(:).', length(carlogtime), 1))
It worked!! And saves a lot of computing time.. Thank you so much..

Sign in to comment.

More Answers (1)

It might also be worth noting that since you already have the time as a separate thing, you can also do this:
>> t1 = duration(11,34,08,471.810,'Format','hh:mm:ss.SSSSSS')
t1 =
duration
11:34:08.471810
>> t2 = duration(11,34,06,471.840,'Format','hh:mm:ss.SSSSSS')
t2 =
duration
11:34:06.471840
>> t1 - t2
ans =
duration
00:00:01.999969

1 Comment

this works well, thank you. As I put a break point and checked the difference and index of minimum value all working good but the computing time is very long (almost 12 hours) as its comparing 3487 gsr data with 31982 carlog data in each loop and getting the minimum index each time. Have any other way to do it faster?

Sign in to comment.

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!