How to keep the precision of datetime when taking into consideration time offsets

I am writing a code that will convert the time into different readable (plotable) formats. For instance I have data that is reported in milliseconds, I would like to convert it to a 'HH:mm:ss.SSS' format. I am able to write code to do this. The issue is when I take into consideration a time offset, in a format 'HH:mm:ss.SSS', I lose the millisecond detail. Below is part of my code, I cannot share all of it.
if nargin < 4
pTimeOffsets = datetime('00:00:00.000',...
'Format','HH:mm:ss.SSS'); % this is the Time Offset, it is an optional argument and if left out is defaulted to nothing.
end
...
pConvertedTime = datetime(strcat(string(lHH),':',...
string(lmm),':',...
string(lss),'.',...
string(lSSS)),...
'Format','HH:mm:ss.SSS'); % this will take the milliseconds and convert into a datetime object.
%The desired precision is kept.
If I were to do this:
pConvertedTime = datetime(strcat(string(lHH),':',...%lHH is hour number
string(lmm),':',...%lmm is minute number
string(lss),'.',...%lss is second number
string(lSSS)),...%lSSS is millisecond number
'Format','HH:mm:ss.SSS') - pTimeOffsets; % offsets loses milliseconds precision
Any suggestions?

2 Comments

Provide a minimum working example that illustrates the problem, please...
Below is the working code exert, again I can't share the entire code for business reasons. Notice that pConvertedTime is saved in 'HH:mm:ss' format. If pConvertedTime does not take pTimeOffsets into consideration then the format is 'HH:mm:ss.SSS'.
pTimeInput = double([30102794;30102924;30103039;30103170;...
30103293;30103407;30103517;30103600;30103699;30103799]);
pTimeOffsets = datetime('00:00:00.000',...
'Format','HH:mm:ss.SSS');
lSSS = round(((pTimeInput/1000) - floor(pTimeInput/1000))*1000,0 );
lss = (pTimeInput - lSSS)/1000;
lHH = floor(lss/3600);
lmm = floor((lss/60) - lHH*60);
lss = floor( lss - (lmm*60) - (lHH*3600) );
pConvertedTime = datetime(strcat(string(lHH),':',...
string(lmm),':',...
string(lss),'.',...
string(lSSS)),...
'Format','HH:mm:ss.SSS') - pTimeOffsets;

Sign in to comment.

 Accepted Answer

You don't actually want a datetime array, you want a duration array. That's easy. First remove the fractional seconds. There's no need to perform division, rounding, and multiplication for your lSSS.
lSSS2 = rem(pTimeInput, 1000);
The rest of your number is the number of seconds you want your duration to represent.
numSeconds = (pTimeInput-lSSS2)/1000;
Now build your duration.
d = seconds(numSeconds)+seconds(lSSS2)/1000
Because I built d using seconds it displays as seconds, but you can change its display Format. [This was, I believe, the main issue with your original code, but I find using seconds to be easier to explain than the arithmetic.]
d.Format = 'hh:mm:ss.SSS'
That looks to be in agreement with your pTimeInput data. Let's see them side-by-side to compare.
format longg
tt = timetable(d, pTimeInput)

1 Comment

Works perfectly; I tried to use duration arrays earlier, but misused it and moved on. Thanks!

Sign in to comment.

More Answers (1)

I came up with a solution. I could not figure out how to modify datetime objects.
Instead of converting everything to datetime objects I converted into milliseconds performed the offset and then converted into datetime object.
The code is designed to output multiple different units and take in differnt units so there was some fluidity in how the code could be constructed. I initially used datetime as the midpoint as this is generally what will be the final result.
John

Categories

Products

Release

R2019b

Community Treasure Hunt

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

Start Hunting!