I have a date
time1 = '03-Apr-2004 00:15:00'
aTime = datenum(time1)
time2 = datestr(addtodate(aTime, -53.1*60, 'minute'))
31-Mar-2004 19:09:00
But I want time2 to be in the nearest multiple of 5 minutes always. How can I do this (either by adding or multiplying some factor)?
Expected answer: 31-Mar-2004 19:10:00
Basically, in my entire dataset, I want these values to be always 5,10,15,20,...,55 etc. in the minute section.
What you have, in fact, is a datenum, not datetime. You could, for example, first convert it to datevec, then round the minutes, then convert back to datenum:
>> dv = datevec(time2);
>> dv(5) = round(dv(5) / 5) * 5;
>> datestr(datenum(dv))
ans =
31-Mar-2004 19:10:00
If it is possible that seconds are non-zero, you can also set them to zero:
dv(6) = 0;
Related
I am running into the following problem in Matlab 2019a.
>> datestr(datetime('20190927','InputFormat','yyyyMMdd')-datetime('20190923','InputFormat','yyyyMMdd'),'yyyymmdd')
ans =
'00000104'
Why is the answer 1 month 4 days? Shouldn't it be zero month 4 days?
EDIT:
I realize that arithmetic on datetime arrays create duration arrays. But I don't know how to set format of duration arrays after doing arithmetic on datetime arrays or how to retrieve the duration data in a format free way.
Datetime arithmetic is what I need. So I am asking the question so I can do datetime arithmetic without issue.
d = datetime('20190927','InputFormat','yyyyMMdd')-datetime('20190923','InputFormat','yyyyMMdd')
returns:
d =
duration
96:00:00
That is, 96 hours. Converting this to a date string results in January 4th. If you start counting hours from midnight on the year 0, 96 hours later you end up on January 4th. There's no 0th month.
What you can do is this:
d = duration(d,'Format','dd:hh:mm:ss')
which returns:
d =
duration
04:00:00:00
You can also do:
d = days(d)
which returns:
d =
4
Consider the following example
xDATA = data_timestamp;
[~,~,Days,Hour,Min,~] = datevec(xDATA(2:end) - xDATA(1:end - 1));
BadSamplingTime = find((Days)> 0 | (Hour)> 0 |(Min)> 5 );
In which xData contains a vector of time stamps and I am trying to find the samples with sampling time greater than 5 mins in between , the algorithm works fine but it creates 3 extra vectors for the data as big as my timestamp vector(the size to time stamp vector is pretty huge) whereas if I do this
DurationTime = xDATA(2:end) - xDATA(1:end - 1);
Instead of the second line it will just create one vector of same length of 'duration' data type which will be much easier to handle because but the problem I cant seem to access each index of the duration data type
for example
DurationTime(5,1)
ans =
26:00:01
I need to access this 26 hours part , does anyone have any idea how to do that ? or a better suggestion
You can create a duration-object and then use it to compare it with the duration vector DurationTime. The result of a>b is a logical vector that can be directly used to index the elements of DurationTime and thus giving you all the values where the duration is greater than 5 minutes.
Sidenote: You can calculate the difference/duration directly with diff.
Code:
% create example data
xDATA = (([0:4,4+26*60,4+26*60+1:4+26*60+5])/24/60+datetime('now')).';
% calculate the durations
DurationTime = xDATA(2:end) - xDATA(1:end-1); % as in the question
%DurationTime = diff(xDATA); % alternative
% get index and values of all durations greater than 5 minutes
ind = find(DurationTime>duration(0,5,0))
DurationTime(ind)
% get values of all durations greater than 5 minutes (direct solution, if no index needed)
DurationTime(DurationTime>duration(0,5,0));
Result:
ind =
5
ans =
26:00:00
My data (cell) in Matlab looks like this:
00.00.00.515
00.00.00.671
00.00.00.828
00.00.00.984
00.00.01.140
etc.
This is the time stamp: HH:MM:SS:TTT, the T stands for thousandth (=milliseconds). The milliseconds are important because the step size is small. How to convert this data (cell) to data Matlab can handle (double)?
So the data will be as follow:
0.515
0.671
0.828
0.984
1.140
etc.
The minutes and hours should be converted to seconds so it is easy to calculate the total time of the data or the average stepsize. So:
01.30.00.000
will be:
5400.000
seconds
Thanks!
Assuming your cell array contains strings:
ts = {'00.00.00.515'
'00.00.00.671'
'00.00.00.828'
'00.00.00.984'
'00.00.01.140'};
it can be done as follows:
>> cell2mat(cellfun(#(c) sscanf(c,'%d.%d.%f').', ts, 'uniformout', 0)) * [3600 60 1].'
ans =
0.5150
0.6710
0.8280
0.9840
1.1400
This uses cellfun to convert each cell into a row vector of numbers with sscanf,; then concatenates all those vectos into a matrix with cell2mat; and fianlly applies matrix multiplication to compute time.
The code also works if the number of digits is not fixed. For example:
>> ts = {'0.1.00.51'};
>> cell2mat(cellfun(#(c) sscanf(c,'%d.%d.%f').', ts, 'uniformout', 0)) * [3600 60 1].'
ans =
60.5100
I have strings of the format '15:10:21' for time, and I also know the date, which is in the format 2011-08-05.
What's the best way to obtain matlab time (in days since 1900) out of this data?
Use datenum:
>> num = datenum('2011-08-05 15:10:21')
num =
7.3472e+05
>> datestr(num)
ans =
05-Aug-2011 15:10:21
The "matlab time" is actually days since the 0th of January, in the year 0:
>> datestr(0)
ans =
00-Jan-0000
I need to subtract 21 months from a given date.
My solution as given below only takes me to the first month of the given year :(
[a,b,c]= datevec(date);
b= b-21;
datestr(datenum(a,b,c)) %--> 11-Jan-2011 (WRONG).
I want the answer to be 11-June-2009.
Go via date numbers rather than date vectors and use addtodate:
>> d = datenum(date);
>> e = addtodate(d, -21, 'month');
>> datestr(e)
ans =
11-Jun-2009