How to import dates into MATLAB - matlab

I am using MATLAB R2015b. I am trying to import a excel file full of dates using xlsread('filename.xls'). The dates looks like the followings:
02/01/1996
03/01/1996
04/01/1996
05/01/1996
08/01/1996
then I want use datevec to separate the day month and year. for date = '02/01/1996'(January 2nd 1996), datevec gives Y= 1996, M = 2, D= 1,H=0 MN=0 S=0. For date '29/12/2000' (Dec 29 2000), datevec gives Y = 35, M=5 D =23 H=0 MN=0 S=0.
I tried to change the date format in excel, but it still does not work. Can anyone let me know how can I fix this please?

DateVector = datevec(DateString,formatIn)
As per the documentation. Set your formatIn correct:
DateString = {'16/09/2007';'14/05/1996';'29/11/2010'};
formatIn = 'dd/mm/yyyy';
datevec(DateString,formatIn)
Since MATLAB is an American program all their defaults are American (hence you're not able to call your colourbar as you want to). You just have to select a different date format.

Related

How do i convert monthly data into quarterly data in matlab as part of a table

How do I convert monthly data into quarterly data?
For example:
my 1 table looks like this:
TB3m
0.08
0.07
0.06
0.12
0.13
0.14
my second table is table of dates:
dates
1975/01/31
1975/02/28
1975/03/31
1975/04/30
1975/05/31
1975/06/30
I want to convert table 1 such that it takes the average of 3 months to give me quarterly data.
It should ideally look like:
TB3M_quarterly
0.07
0.13
so that it can match my other quarterly dates table which looks like:
dates_quarterly
1975/03/31
1975/06/30
Over all my data is from 1975 January to 2021 june which would give me around 186 quarterly data. Please suggest what I can use. It is thefirst time I am using matlab
In case you can't understand a command, search for it in MATLAB documentation. One quick way to do so in Windows is to click on the function you don't understand and then press F1. For example, if you can't understand what calmonths is doing, then click on calminths and press F1.
TBm = [0.08; 0.07; 0.06; 0.12; 0.13; 0.14]; %values
% months
t1 = datetime(1975, 01, 31); %1st month
% datetime is a datatype to represent time
t2 = datetime(1975, 06, 30); %change this as your last month
dates = t1:calmonths(1):t2;
dates = dates'; %row vector to column vector
TBm_reshaped = reshape(TBm, 3, []);
TB3m_quarterly = mean(TBm_reshaped);
dates_quarterly = dates(3:3:end);
TB3m_quarterly = TB3m_quarterly';
T = table(dates_quarterly, TB3m_quarterly)
I suggest you organize your data in a timetable, and then use the function retime()
% Replicating your data
dates = datetime(1975,1,31) : calmonths(1) : datetime(1975,6,30);
T = timetable([8 7 6 12 13 14]'./100, 'RowTimes', dates);
% Using retime to get quarterly values:
T_quarterly = retime(T, 'quarterly', 'mean')
Here you aggregate by taking the mean of the monthly data. For other aggregation methods, look at the documentation for retime()

How do I format X Axis tick labels when using Epoch seconds as X axis values?

I have the following data set:
octave:42> yy
yy =
1420174800.00000 21.70000 21.93000 21.64000 21.81000 1949882.00000
1420434000.00000 21.92000 22.23000 21.90900 22.17000 3189214.00000
1420520400.00000 22.15000 22.51000 22.08000 22.41000 4810496.00000
1420606800.00000 22.21000 22.27500 22.07000 22.11000 2397372.00000
1420693200.00000 21.93000 21.93600 21.70000 21.73000 2797149.00000
1420779600.00000 21.68000 21.98000 21.68000 21.90000 2377333.00000
1421038800.00000 21.88000 22.15000 21.87000 22.07000 2347871.00000
1421125200.00000 21.94000 22.30000 21.76500 22.15000 5255049.00000
1421211600.00000 22.40000 22.51900 22.24000 22.25000 5843980.00000
1421298000.00000 22.18000 22.48000 22.14000 22.47990 3498303.00000
If I plot it I get the following chart:
octave:44> plot(yy(:,1), yy(:,5))
Following the Octave documentation (https://octave.sourceforge.io/octave/function/datetick.html) I have tried the following to get the Years displayed instead of the UNIX Epoch seconds values.
octave:48> plot(yy(:,1), yy(:,5))
octave:49> datetick('x','YYYY')
But this is the result:
I would like to learn how to display the YEAR (YYYY) and the year and month (YY-MM). I am not sure if a Matlab solution could also fit in Octave.
Short version
plot( arrayfun( #(x) datenum([1970, 1, 1, 0, 0, x]), yy(:,1) ), yy(:,5) )
datetick( 'x', 'yyyy' )
Explanation
The numbers you have are unix epochs (i.e. seconds since 1970-1-1 00:00:00 UTC).
The reason you're getting weird numbers out of datetick is because it does not expect unix epochs as input, but "date numbers" (fractional number of days since 0000-1-0 00:00:00 UTC, whatever that means).
What you can do, is use your values to convert to datenums, via a datevec. E.g. your first value, i.e. 1420174800, can be converted to a datenum like so
datenum([1970,1,1,0,0,1420174800]) % i.e. the 1420174800th second of 1970-01-01
% ans = 7.3597e+05
datestr( datenum([1970,1,1,0,0,1420174800]), 0 )
% ans = 02-Jan-2015 05:00:00
Therefore, you could convert all your unix epochs to datenums, e.g. like so
DateNums = arrayfun( #(x) datenum([1970, 1, 1, 0, 0, x]), yy(:,1) )
And then plot using the DateNums instead, and use datetick as expected.
The above solution would work identically in octave and matlab.

How to get datetime day, month and year without financial toolbox in Matlab?

I found that functions like day, month and year require Financial Toolbox.
>> [~, packages] = matlab.codetools.requiredFilesAndProducts('month'); packages(2)
ans =
struct with fields:
Name: 'Financial Toolbox'
Version: '5.8'
ProductNumber: 30
Certain: 1
How to know datetime parts without this toolbox?
I don't think that my comments on the question or the accepted solution are getting across in the way I intended, so I'll give a proper answer to better elaborate on what you're seeing.
There are multiple things called "month" in MATLAB. There is a function called month, that is in the Financial Toolbox (https://www.mathworks.com/help/finance/month.html). There is also a method of the datetime class called "month" (https://www.mathworks.com/help/matlab/ref/month.html). These are two separate functions, and act differently. The regular "month" function (of the Financial Toolbox) will accept any date number or string. However, in MATLAB, if you call "month" and pass it an instance of a datetime (as in the accepted solution's answer, you could use datetime('now')), you will not be calling the Financial Toolbox's function "month", but rather the "month" method of the datetime class, because that is how MATLAB dispatching rules work.
matlab.codetools.requiredFilesAndProducts does not and cannot know that you're calling "month" with a datetime input, so it can't assume you're calling the datetime method called "month" and instead reports to you the requirements for the Financial Toolbox function.
If you know you are working with datetimes, you can be more precise in your query to requiredFilesAndProducts:
>> [~,packages] = matlab.codetools.requiredFilesAndProducts(which('month(datetime(''now''))'))
packages =
Name: 'MATLAB'
Version: '8.6'
ProductNumber: 1
Certain: 1
By using which('month(datetime(''now''))'), you are more precise by telling the which function exactly what your function call is going to look like (i.e., what its input type will be), which allows it to properly figure out which overloaded "month" will get called and then requiredFilesAndProducts can correctly show you that if your input is a datetime, you only need MATLAB -- not the Financial Toolbox.
If you truly need to call "month" on a non-datetime, you can effectively get the same behavior by writing your own function that just puts the serial date and format into a datetime and then calls "month" on the datetime object (see the 'ConvertFrom' syntax on https://www.mathworks.com/help/matlab/ref/datetime.html). This will not have any requirements on the Financial Toolbox, because it will only leverage the datetime method (which is included in base MATLAB).
You can use the datestr function (no toolbox required).
For an example, I'll use 'now' to create the datetime object for now, then process:
dt = datetime( 'now' ); % datetime object: 27-Jun-2018 12:17:27
% Year
y = datestr( dt, 'yyyy' ); % >> y = '2018'
% Month
m = datestr( dt, 'mm' ); % >> m = '06'
m = datestr( dt, 'mmm' ); % >> m = 'Jun'
% Day
d = datestr( dt, 'dd' ); % >> d = '27'
d = datestr( dt, 'ddd' ); % >> d = 'Wed'
If you need to convert the numeric year/month/day outputs to numbers from the char arrays, use str2double.
Looking under the hood of, for example, month you can see that (after the robustness checks) it simply indexes an array of month names with the output of datevec, so that would be another way to go.
Edit
I've just seen you can directly access year/month/day/... properties of a datetime object. This makes things pretty easy, especially if you want the numeric output:
dt = datetime( 'now' ); % datetime object: 04-Mar-2019 11:20:00
y = dt.Year; % >> y = 2019
m = dt.Month; % >> m = 3
This still avoids using the year/month/... functions.

How to format dates on a plot and remove gap from time

I have the following plot created from this very simple script.
clear;
format long g
Ts = ncread('EURUSD_1 hour_30_D_2015-11-03_02-52-36-PM.nc', 'TimeStamp');
Obs = ncread('EURUSD_1 hour_30_D_2015-11-03_02-52-36-PM.nc', 'Close');
plot(datenum(Ts), Obs);
datetick('x', 20);
However, I get this error:
>> netcdfExample
Error using datevecmx
Date number out of range.
Error in datevec (line 303)
[y,mo,d] = datevecmx(t);
Error in dateTickPicker (line 85)
[y,m,d] = datevec(x);
Error in datetick>bestscale (line 292)
[labels,format] = dateTickPicker(axh,[xmin,xmax],dateform,dateChoice,axVal);
Error in datetick (line 251)
ticks = bestscale(axh,ax,vmin,vmax,dateform,dateChoice);
Error in netcdfExample (line 9)
datetick('x', 20);
>>
When I just try something simple like this
>> formatOut = 'mmmm-dd-yyyy';
>> str = datestr(6.35821236e+17,formatOut,'local')
I get this error. I wonder if these encoded date numbers are wrong?
Error using dateformverify (line 28)
DATESTR failed converting date number to date vector.
Error in datestr (line 194)
S = dateformverify(dtnumber, dateformstr, islocal);
Caused by:
Error using datevecmx
Date number out of range.
The datetimes/close look like this (in the .csv vesion)
9/22/2015 16:15 1.11255
9/22/2015 17:00 1.11305
9/22/2015 18:00 1.112
9/22/2015 19:00 1.1107
9/22/2015 20:00 1.1123
The date is from hourly intra-day data (netcdf format) that I read from a file into Matlab :
As you can see, the x-axis are numbers in 10^17 format instead of System.DateTime from C#. Also, please note that since the markets close and reopen, there is a line joining the plot between when the market closes, and reopens.
How do I:
Get rid of the date gap. I want the data to be next to its neighbor.
Make the x-axis tick marks be something resembling a date/time?
The y axis data has five decimal places of precision. How do I ask the plot to show more precision on the y-axis tick marks?
I sort of figured out a workaround. In the C# program, instead of using a Datetime, I convert the Datetime to a double. Then this program works fine
Ts = ncread('EURUSD_1 hour_30_D_2015-11-03_06-41-44-PM.nc', 'TimeStamp');
Obs = ncread('EURUSD_1 hour_30_D_2015-11-03_06-41-44-PM.nc', 'Close');
plot(Ts, Obs);
datetick('x', 'mm-dd-yy HHPM');
I still don't know how to add precision to the y axis, and how to remove the gaps in time on the x-axis. It is interesting because if I just say
plot(Obs)
The plot looks correct on the y-axis but the x-axis is numbers. If I add
plot(Ts, Obs)
datetick('x', 'mm-dd-yy HHPM');
Then the x-axis is correctly "indexed" by date/time, but I suspect that Matlab is honoring the gaps in time so the plot looks "jumpy" and disconnected.

Matlab addtodate function

I am trying to use "addtodate" function of matlab. Am I correct in observing that it can't be applied to vector of dates ?
If that is the case how do I add an hour to each of the dates in the following vector of dates:
stDt = datenum('2/28/2014');
endDt = datenum('4/29/2014');
interval = (datenum(1987,0,0,1,0,0)-datenum(1987,0,0,0,0,0));
z1 = datenum(stDt):interval:datenum(endDt);
z = datestr(addtodate(z1,1,'hour'));
The last line fails with following error:
??? Error using ==> addtodate at 42
Date number must be a numeric scalar.
datenum in matlab returns a serial date number in units of days. To add an hour to each date in a vector just add 1/24:
z = datestr(z1 + 1/24);