Reading dates/times into MATLAB and saving as a numeric vector

I am reading in *.txt files that contain a column of dates (i.e. 17.11.2017 09:57:24.06). Each row is a signal at a frequency of 0.01 seconds. I want to be able to bring this in as a numeric vector so that I can determined time elapsed between selected rows. Using x = datenum(filename) gives me 736696.4149 (number of days from Jan 0, 0000) for both 17.11.2017 09:57:24.06 and 17.11.2017 09:57:29.96. These are 5.90 seconds apart. How do I read these dates/times in so that I can maintain the precision I need to maintain (0.01 seconds)?

 Accepted Answer

Unless you are using a pretty old version of MATLAB, I recommend you don't use datenum and datestr. Try datetime. For example:
>> t = datetime({'17.11.2017 09:57:24.06';'17.11.2017 09:57:29.96'},'Format','dd.MM.yyyy HH:mm:ss.SS')
t =
2×1 datetime array
17.11.2017 09:57:24.06
17.11.2017 09:57:29.96
>> dt = diff(t) % or dt(2) - dt(1)
dt =
duration
00:00:05
>> dt.Format = 's'
dt =
duration
5.9 sec

3 Comments

This works great. However, it causes trouble when I merge it with a 2D numeric array (having different units of measure) of the same number of rows. The resultant matrix has the "sec" as the unit for all columns.
>> dt = dt(1:5,:)
dt =
5×1 duration array
0 sec
0.01 sec
0.02 sec
0.03 sec
0.04 sec
>> other = ts_info(1:5,1:3)
other =
0 72 162
0 72 162
0 72 162
0 72 162
0 72 162
>> final = [dt other]
final =
5×4 duration array
0 sec 0 sec 6.2208e+06 sec 1.3997e+07 sec
0.01 sec 0 sec 6.2208e+06 sec 1.3997e+07 sec
0.02 sec 0 sec 6.2208e+06 sec 1.3997e+07 sec
0.03 sec 0 sec 6.2208e+06 sec 1.3997e+07 sec
0.04 sec 0 sec 6.2208e+06 sec 1.3997e+07 sec
Well, duration and double are two different datatypes, so you can't put them in one homogeneous array without converting one way or the other. What you are seeing above is the automatic conversion of those numeric values, treated as numbers of days (a.k.a. datenums) into durations.
You might want to do one of two things:
1) Those numbers are numbers, with their own names and units. Make a timetable with all four things:
>> dt = seconds(0:.1:.4)';
>> other = ...
[0 72 162
0 72 162
0 72 162
0 72 162
0 72 162];
>> tt = array2timetable(other,'RowTimes',dt)
tt =
5×3 timetable
Time other1 other2 other3
_______ ______ ______ ______
0 sec 0 72 162
0.1 sec 0 72 162
0.2 sec 0 72 162
0.3 sec 0 72 162
0.4 sec 0 72 162
And then maybe give the last three vars in that timetable meaningful names.
2) Those numbers represent time in some unit, maybe seconds. Convert before concatenating:
>> final = [dt seconds(other)]
final =
5×4 duration array
0 sec 0 sec 72 sec 162 sec
0.1 sec 0 sec 72 sec 162 sec
0.2 sec 0 sec 72 sec 162 sec
0.3 sec 0 sec 72 sec 162 sec
0.4 sec 0 sec 72 sec 162 sec
3) Or convert to all numeric:
>> final = [seconds(dt) other]
final =
0 0 72 162
0.1 0 72 162
0.2 0 72 162
0.3 0 72 162
0.4 0 72 162
If I were a betting man, I'd guess (1). Prior to R2016b, you could do essentially the same thing with a table.

Sign in to comment.

More Answers (1)

Don't worry. The precision is kept.
a=datenum('17.11.2017 09:57:29.96');
b=datenum('17.11.2017 09:57:24.06');
datestr(a-b,'HH:MM:SS.FFF')
datevec(a-b)
second(a-b)
ans =
'00:00:05.900'
ans =
0 0 0 0 0 5.9000
ans =
5.9000

Categories

Tags

Community Treasure Hunt

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

Start Hunting!