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
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?
You may try something like:
a='2015-09-08 14:38:03';
s=strsplit(a,{'-',':',' '})
x=datenum(cellfun(#str2num,s(1:end)))
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
>>
Related
Im trying to convert the first two columns of a cell into a Matlab time. First column {1,1} is the date in YYYY-MM-DD format and the second is the time in HH:MM format.
Any ideas where I'm going wrong? My code:
file = 'D:\Beach Erosion and Recovery\Bournemouth\Bournemouth Tidal
Data\tidal_data_jtide.txt'
fileID = fopen(file);
LT_celldata = textscan(fileID,'%D%D%D%D%d%[^\n\r]','delimiter',',');
formattime = 'yyyy-mm-dd HH:MM'
date = LT_celldata{1,1};
time = LT_celldata{1,2};
date_time = datenum('date','time'); code
Screenshot below is LT_celldata{1,1} :
You can combine variables date and time with the following code:
date = datetime(LT_celldata{1,1},'InputFormat','yyyy-MM-dd');
time = datetime(LT_celldata{1,2},'InputFormat','HH:mm:ss','Format','HH:mm:ss');
myDatetime = datetime(date + timeofday(time),'Format','yyyy-MM-dd HH:mm:ss');
The code uses timeofday function to combine date and time information from the two different variables. You may find more information and examples at this documentation page.
How to reverse convert InputFormat of datetime constructor in Matlab?
datestr doesn't work:
>> startTime = datetime('2014/06/01-00:00', 'InputFormat', 'yyyy/MM/dd-HH:mm')
startTime =
datetime
01-Jun-2014 00:00:00
>> datestr(startTime, 'yyyy/MM/dd-HH:mm')
ans =
2014/00/01-00:06
As you see, it turns months into minutes.
How to overcome?
UPDATE
Format should not be hardcoded, solution should work in both ways with one given format string.
Set the 'Format' of your datetime object to the desired output and use char():
tfmt = 'yyyy/MM/dd-HH:mm';
startTime = datetime('2014/06/01-00:00', 'InputFormat', tfmt, 'Format', tfmt);
char(startTime)
Which returns:
>> SOcode
ans =
'2014/06/01-00:00'
Note that this is a documented limitation of datestr
Note
The symbolic identifiers describing date and time formats are different from those that describe the display formats of datetime arrays.
Rearranging the out format (very small change) of datestr worked:
startTime = datetime('2014/06/01-00:00', 'InputFormat', 'yyyy/MM/dd-HH:mm')
startTime =
01-Jun-2014 00:00:00
datestr(startTime, 'yyyy/mm/dd-HH:MM')
ans =
2014/06/01-00:00
I have an array of timestamps, these are just three examples:
time_1 = '23/01/2013 00:47:00'
time_2 = '04/02/2013 00:00:00'
time_3 = '27/01/2013 03:31:00'
I want to use 'datevec' on these timestamps:
tVec_1 = datevec(datenum(time_1,'dd/mm/yyyy HH:MM:SS'));
tVec_2 = datevec(datenum(time_2,'dd/mm/yyyy HH:MM:SS'));
tVec_3 = datevec(datenum(time_3,'dd/mm/yyyy HH:MM:SS'));
for the tVec_1 and tVec_3 timestamp it works nicely, but it crashes for the tVec_2:
Error using dtstr2dtvecmx
Failed on converting date string to date number.
Error in datevec (line 117)
y = dtstr2dtvecmx(t,icu_dtformat);
I suspect, that the problem comes from "zero time" which is not treated properly by my format 'dd/mm/yyyy HH:MM:SS' (if I remove the last "HH:MM:SS" then it works).
Unfortunately, I could not find anything useful on matlab website.
Suggestions are welcome!
Thanks!
I have some time as string format in my data. Can anyone help me to convert this date to milliseconds in Matlab.
This is an example how date looks like '00:26:16:926', So, that is 0 hours 26 minutes 16 seconds and 926 milliseconds. After converting this time, I need to get only milliseconds such as 1576926 milliseconds for the time that I gave above. Thank you in advance.
Why don't you try using datevec instead? datevec is designed to take in various time and date strings and it parses the string and spits out useful information for you. There's no need to use regexp or split up your string in any way. Here's a quick example:
[~,~,~,hours,minutes,seconds] = datevec('00:26:16:926', 'HH:MM:SS:FFF');
out = 1000*(3600*hours + 60*minutes + seconds);
out =
1576926
In this format, the output of datevec will be a 6 element vector which outputs the year, month, day, hours, minutes and seconds respectively. The millisecond resolution will be added on to the sixth element of datevec's output, so all you have to do is convert the fourth to sixth elements into milliseconds and add them all up, which is what is done above. If you don't specify the actual day, it just defaults to January 1st of the current year... but we're not using the date anyway... we just want the time!
The beauty with datevec is that it can accept multiple strings so you're not just limited to a single input. Simply put all of your strings into a single cell array, then use datevec in the following way:
times = {'00:26:16:926','00:27:16:926', '00:28:16:926'};
[~,~,~,hours,minutes,seconds] = datevec(times, 'HH:MM:SS:FFF');
out = 1000*(3600*hours + 60*minutes + seconds);
out =
1576926
1636926
1696926
One solution could be:
timeString = '00:26:16:926';
cellfun(#(x)str2num(x),regexp(timeString,':','split'))*[3600000;60000;1000;1]
Result:
1576926
Assuming that your date string comes in that format consistently, you could use something as simple as this:
test = '00:26:16:926';
H = str2num(test(1:2)); % hours
M = str2num(test(4:5)); % minutes
S = str2num(test(7:8)); % seconds
MS = str2num(test(10:12)); % milliseconds
totalMS = MS + 1000*S + 1000*60*M + 1000*60*60*H;
Output:
1576926.00
you can convert a single string with a date or even a vector by using datevec for conversion and the dot product
a = ['00:26:16:926' ; '08:42:12:936']
datevec(a,'HH:MM:SS:FFF') * [0 0 0 3600e3 60e3 1e3]'
ans =
1576926
31332936
I have some data files with Unix timestamps (in this case, number of milliseconds since Jan 1, 1970 00:00 UTC). I would like to convert these to human-friendly date/time strings (e.g. 31-Aug-2012 11:36:24) in Matlab. Is there an easy way to do this in Matlab, or am I better off using an external library (e.g. java.text.SimpleDateFormat)?
How about
date = datestr(unix_time/86400 + datenum(1970,1,1))
if unix_time is given in seconds, unix_time/86400 will give the number of days since Jan. 1st 1970. Add to that the offset used by Matlab's datenum (datenum(0000,1,1) == 1), and you have the amount of days since Jan. 1st, 0000. This can be easily converted to human-readable form by Matlab's datestr.
If you have milliseconds, just use
date = datestr(unix_time/86400/1000 + datenum(1970,1,1))
Wrapped in functions, these would be
function dn = unixtime_to_datenum( unix_time )
dn = unix_time/86400 + 719529; %# == datenum(1970,1,1)
end
function dn = unixtime_in_ms_to_datenum( unix_time_ms )
dn = unix_time_ms/86400000 + 719529; %# == datenum(1970,1,1)
end
datestr( unixtime_to_datenum( unix_time ) )
Newer versions of MATLAB (verified in R2015a) have a datetime type that is useful for working with and formatting dates and times. You can convert UNIX timestamps into a MATLAB datetime with
dt = datetime( unix_time, 'ConvertFrom', 'posixtime' );
and then use datestr as before for formatting as a string
datestr( dt )