How to generate a date-time array in MATLAB? - matlab

How do I generate this 480x1 array of date-times in Matlab?
1982-01-01
1982-02-01
1982-03-01
1982-03-01
1982-04-01
.
.
.
2015-12-01

This is made easy with the datetime function (introduced in R2014b) and following the documentation to Generate Sequence of Dates and Time.
% MATLAB 2019a
t1 = datetime(1982,1,1);
t2 = datetime(2015,12,1);
t = t1:t2;
t = t(:); % Force column
Alternatively, you can specify the number of linearly-spaced points between two dates using the linspace command.
t_alt = linspace(t1,t2,480).';
You can convert to the y-M-d format you specified with datetime as well.
t_format = datetime(t,'Format','y-M-d')
References:
1. Dates and Time (in MATLAB)
2. Represent Dates and Times in MATLAB
3. Set Date and Time Display Format
4. Generate Sequence of Dates and Time

Related

In MATLAB How to calculate a time between two dates with a custom format?

I have two dates with bellow format and want to calculate the time between these times:
t1=datestr(clock,'dd-mm-yyyy HH:MM:SS:FFF');
t2=datestr(clock,'dd-mm-yyyy HH:MM:SS:FFF');
My output should be in this format:
(YY:MM:DD:HH:MM:SS:FFF)
as an example
(0:0:1:2:3:44:25:330)
You can first convert the t1 and t2 char arrays to numeric format
using datenum() function then you can calculate the difference between
the calculated numeric dates back to the required format using
datestr() function.
The code illustrating the procedure is given below.
% storing the two times
t1=datestr(clock,'dd-mm-yyyy HH:MM:SS:FFF')
t2=datestr(clock,'dd-mm-yyyy HH:MM:SS:FFF')
% convertine the stored times to numeric format
% using datenum()
numeric_t1 = datenum(t1, 'dd-mm-yyyy HH:MM:SS:FFF');
numeric_t2 = datenum(t2, 'dd-mm-yyyy HH:MM:SS:FFF');
% calculating the time difference
time_diff = datestr((numeric_t2 - numeric_t1), 'yy:mm:dd:HH:MM:SS:FFF')
Command Window Output

Matlab :: Change Day, Month Year of serial date number

I want to change the Day, Month and Year of a serial date number in matlab
e.g.: 7.367985930307407e+05
gives me 13-Apr-2017 14:13:57.
I need: 01-Jan-2017 14:13:57
I get the serial date number from a simulink model, where is a matlab emb. code block with:
function t = sysTime
coder.extrinsic('now');
t=0;
t = now
end
Anyone can help? Read the matlab datenum and now docu but I still couldnt figure it out :(
You can use a datetime object to alter specific portions of the date
d = 7.367985930307407e+05;
dt = datetime(datevec(d));
dt.Month = 1;
dt.Day = 1;
% 01-Jan-2017 14:13:57
% And if you need the serial date number back:
result = datenum(dt);
In your function sysTime, the output is set to now, which gives you the current time as returned by your system. Try the following instead:
function t = sysTime
coder.extrinsic('now');
t=0;
t=datenum(2017,1,1) + rem(now,1);
end
Matlab date numbers are numbers of type double that represent the number of days since a reference date. Thus, the number before the decimal point gives you a date, the nubers after the decimal point give you the time of day.
With the datenum function you can get the date number for your desired date and add the fractional part of the system time to get what you want. In the long run it would probably be better to parameterize your reference date in the matlab block.

Using matlab to arrange and sort data

My data is an excel file with two columns in this format:
Date Type
3/12/06 A
3/12/06 B
3/12/06 B
3/12/06 C
6/01/07 A
6/01/07 A
8/01/07 B
...
Column A are dates and can be repeated while column B are types of observations on these dates.
In MATLAB I want to plot each type as a function of time, however first I need to arrange my data. There are often multiple identical rows that correspond to multiple observations of the same type on the same date. So I think first I need to count how many times a certain type occurred on the same day?
Any help would be great! I'm still at the stage of trying to read the dates in the correct format...
Here is a solution: I replace each type and each date with a specific index and then I use accumarray in order to create a 2D pivot table. You can also directly use the function pivot table from excel.
% We load the xls file.
[~,txt] = xlsread('test.xls');
% We delete the header:
txt(1,:) = [];
% Value and index for the date:
[val_d,~,ind_d] = unique(txt(:,1));
% Value and index for the type:
[val_c,~,ind_c] = unique(txt(:,2));
% We use accumarray to create a pivot table that count each occurence.
acc = accumarray([ind_d,ind_c],1)
% Then we simply plot the result:
dateFormat = 'dd/mm/yy';
for i = 1:length(val_c);
subplot(1,length(val_c),i)
bar(datenum(val_d,dateFormat),acc(:,i),1) % easier to deal with datenum
datetick('x',dateFormat)
xlabel('Date')
ylabel([val_c{i},' count'])
ylim([0,3])
end
RESULT:

Importing Excel Data with Dates and Values and Plotting Time Series in Matlab

I would like to plot a time series in Matlab of a data set I have in Excel.
The Excel file looks as follows:
Data: | Value:
2005-04-01 | 5.20
2006-12-02 | 3.12
...
How could I load this into Matlab and plot the time series of it?
There's 2 easy way of plotting dates, but I'll give you the script to read from the xls file first.
% Read from Excel
[N,T] = xlsread( filepath );
You then need to extract/convert the dates as follows. Dates are the 1st column of the text.
d = datetime( T(:,1) );
Then you can plot the variables as follows
figure;
plot( d, N(:,1) );
A sample plot is here
Alternatively, you can use datenum instead of datetime if you want the date as an integer instead of a datetime object using the following line.
d = datenum( T(:,1) );
use xlsread to load in data as string, now converting the date and values can be done in a number of ways, the most strait forward way for your dates is perhaps using the str2num which allows you to read in the N th character as a number, for example:
string = "2005-04-01|5.20"
year = str2num(string(1:4))
month = str2num(string(6:7)) //%where the number is the N th character in string, and has to be numerical or the str2num will return error
//%Note that this method does not read non-numerical strings, in your case "-" "|" will not be read.
I believe this is one of the faster methods, since it mainly involve a type conversion on a standard format of data. Any other suggestions?
PS: in your time series plot, I would suggest converting your dates into a long number, i.e. 20050401, 20061202, etc; which would be most efficient. (you can do this by years*1000+months*100+days.

From UTC to date vector

I have a set of date expressed in form of 2010-07-31T23:01:57Z. I need to transform it into vector. I could do this as datavec(mydate) it will transform automatically the string into vector, but this function doesn't accept UTC string date. So I have rudely resolved in this way:
a = `2010-07-31T23:01:57Z`; %UTC date format
a(20) = ''; %remove Z
a(11) = ' '; %replace T with a space
a = datavec(a); % [2010, 7, 31, 23, 1, 57]
In this way a is a datevector and I can use etime(T1, T0) to compute time difference between T1 and T0. Is this the unique way or I can do something stylish?
As Marc suggests, all you have to do is 'help' MATLAB a bit by specifying the data format.
datevec('2010-07-31T23:01:57Z','yyyy-mm-ddTHH:MM:SS')
should do the trick.
use the fieldSpecIn part of the datevec() call. Read all about it here:
http://www.mathworks.com/help/techdoc/matlab_prog/bspgcx2-1.html#bspgc4m-1
Except for the TZ spec at the end of your string and the -'s and :'s, yours is identical to the standard ISO 8601 format. You can either modify yours, or create your own spec string.
Please note that Matlab time has no concept of time zone. You must keep track of that yourself.
As stated by others, you could specify the format of the expected date strings to functions like DATEVEC and DATENUM. Example:
%# set of dates and an initial date
T0 = '2010-01-01T00:00:00Z';
T = repmat({'2010-07-31T23:01:57Z'}, [10 1]); %# cell array
%# format of datetime
frmt = 'yyyy-mm-ddTHH:MM:SS';
%# convert to serial date numbers, and compute difference between all T and T0
n = datenum(T,frmt);
n0 = datenum(T0,frmt);
tdiff = bsxfun(#minus, n, n0);
Alternatively, if you have an unusual date format, you can always split and parse it yourself with functions like TEXTSCAN:
vec = zeros(numel(T),6);
for i=1:numel(T)
C = textscan(T{i}, '%f', 'Delimiter',['-' ':' 'T' 'Z']);
vec(i,:) = C{1};
end
n = datenum(vec);
Note that in both cases, you can convert back serial times to date strings with the DATESTR function.