1
votes

I have some text files with dates of the form

2015-09-08 14:38:03

2015-09-08 14:38:03.1

2015-09-08 14:38:03.2

that I want to convert into Matlab date/time format. As you can see, the text strings have a different time format regarding the milliseconds. In the first case, no milliseconds are given; in the seconds case, milliseconds are given with one digit only. This gives a sampling rate of 20Hz for measuring data.

So far, only

x = datenum(file.dateColumn, 'yyyy-mm-dd HH:MM:SS');

is working, but of course misses the milliseconds. A conversion like

x = datenum(file.dateColumn, 'yyyy-mm-dd HH:MM:SS.FFF');

does not work as the milliseconds are either zero (full seconds) or have one digit after the '.' delimiter. A workaround like

x = datestr(file.dateColumn, 'yyyy-mm-dd HH:MM:SS.FFF');

x = datenum(file.dateColumn, 'yyyy-mm-dd HH:MM:SS.FFF');

i.e. converting the text string into a Matlab string (and giving it additional FFF/FF digits) and then converting that one into a date/time number works - but this is such time-cosuming that I cannot use it for my data. I have millions of time rows in different files.

Do you have any ideas?

Greetings, Arne

3

3 Answers

1
votes

Thanks to Nick I found a way to solve it:

dataVelPres = readtable(fileName, ...
    'ReadVariableNames', false, ...
    'HeaderLines', 4 );

dataVelPres.Properties.VariableNames = {'date' 'velU' 'velV' 'velW' 'pres'};

dateMill = datetime(dataVelPres.date, 'inputformat', 'yyyy-MM-dd HH:mm:ss.S');
dateFull = datetime(dataVelPres.date, 'inputformat', 'yyyy-MM-dd HH:mm:ss');

dateNaT = isnat(dateMill);
dateMill(dateNaT) = dateFull(dateNaT);
dataVelPres.dateTime = dateMill;
dataVelPres.date = datenum(dataVelPres.dateTime); % Convert to number format if needed

This works with two tables - one for millisec. and one without - and puts both together, as both give NaT entries in case the inputformat does not match.

Is there a more elegant way?

0
votes

You may try something like:

a='2015-09-08 14:38:03';
s=strsplit(a,{'-',':',' '})
x=datenum(cellfun(@str2num,s(1:end)))
0
votes

I highly recommend using the new datetime object:

strings = {'2015-09-08 14:38:03', '2015-09-08 14:38:03.1', '2015-09-08 14:38:03.2'};
dates = {};

for d = strings
    d = d{1};

    try
        dt = datetime(d, 'inputformat', 'yyyy-MM-dd HH:mm:ss.S');
    catch
        dt = datetime(d, 'inputformat', 'yyyy-MM-dd HH:mm:ss');
    end

    dates{end + 1} = dt;
end

>> dates

dates =

[08-Sep-2015 14:38:03]    [08-Sep-2015 14:38:03]    [08-Sep-2015 14:38:03]

>> dates{end}.Second

ans =

    3.2000

It's also easy convert from a datetime object to a datenum:

>> x = [datetime('now'), datetime('yesterday')]
x = 
   10-Dec-2015 12:53:40   09-Dec-2015 00:00:00
>> datenum(x)
ans =
   1.0e+05 *
    7.3631    7.3631
>>