I work with csv and must subtract 2 cells with the following date format dd.MM.yyyy HH:mm:ss. I need to extract only the seconds.
Timestamp is a column and I attempted:
data1 = Timestamp(1) ;
data2 = Timstamp(2) ; % returns error
class(data1); % returns cell
data1 - data2 % returns error
How can I convert the cells into a number which I can subtract?
You can index into your cell to extract the date string. Then you can use datenum to convert it to "decimal days since 1st January 0000". Then it's a simple matter of subtracting your starting date (convert that using datenum as well) and changing from decimal days to seconds:
tmp = your_cell{1}; % e.g. 26.11.2020 00:00:00, is a string
tmp_date = datenum(tmp); % MATLAB datenum, decimal days.
tmp_date2 = datenum(your_cell{2});
no_start = tmp_date2-tmp_date; % remove starting date
time_sec = no_start*(24*60*60); % change decimal days to seconds
Or as a oneliner:
(datenum(your_cell{2})-datenum(your_cell{1}))*(24*60*60)
Related
Suppose DT is a vector of type datetime. How can I get their days of the year?
This is an approximation, but I can't find the right function:
month(DT) * 30 + day(DT)
You can use the Matlab's day function with a vector of datetime elements (see the doc)
t = [datetime('yesterday');datetime('today');datetime('tomorrow')]; % vector of datetime
day( t, 'dayofyear')
that will give the Day-of-year number, from 1 to 365 or 366, depending on the year.
ans =
334
335
336
You can use datetime and between as follows:
d = datetime; %Read current time (just for the example).
jan_1st = datetime(d.Year, 1, 1); %Create datetime object of January fist in year of d.
day_in_year = between(jan_1st, d, 'Days'); %Get day in year.
The result is a calendarDuration object: 334d.
For converting to scalar, use split:
day_in_year = split(day_in_year, 'Days') + 1; % Add one in case the first day of the year is day 1 and not 0
Applying the solution on a vector of datetime may require a for loop due to the usage of datetime(d.Year, 1, 1).
I have a CSV file contains data of Hurricane location coordinates.
I'm new to Matlab so I'm not sure how to treat correctly date and hour cells, especially when they are displayed unconventionally.
I need to apply linear interpolation so I can get the date for every 30 minutes.
Let's assume you read the data in as numerical values
Now you have some matrix like so:
data = [20130928 0 21.1 50.0
20130928 600 22.2 50.3
20130928 1200 23.3 50.6
20130928 1800 24.2 50.6];
To convert the first two columns to datetime values, we could do this:
% Concatenate first two columns, including making all times 4 digits by 0 padding
fulltime = [num2str(data(:,1)), num2str(data(:,2), '%.4u')]
% Use datetime to convert (cell) times to dates with given format
dates = datetime(cellstr(fulltime),'inputformat', 'yyyyMMddHHmm');
>> dates = 28-Sep-2013 00:00:00
28-Sep-2013 06:00:00
28-Sep-2013 12:00:00
28-Sep-2013 18:00:00
Now we can easily interpolate. First create an array of times we want to use:
% Data value every 30 mins
interpdates = dates(1):hours(0.5):dates(end)
Then use interp1
interpolateddata = interp1(dates, data(:,3:4), interpdates);
>> interpolateddata = 21.1000 50.0000
21.1917 50.0250
21.2833 50.0500
21.3750 50.0750
...
24.1250 50.6000
24.2000 50.6000
Let
x=7.369030000162731e+05
x is a matlab date and it is equal to
27.07.2017 00:00:01.406
I want to remove the milliseconds from it (ie. .406)
To do this I convert it to datestr with 'dd.mm.yyyy HH:MM:SS' format
and then again to datenum
datenum(datestr(x,'dd.mm.yyyy HH:MM:SS'))
Is there a simpler way to do this.
If you want the manual approach:
y = floor(x*86400)/86400;
because serial date numbers are measured in days, and 86400 is the number of seconds in a day.
Here's a somewhat simpler way that converts x to a date vector, floors all the elements (which only affects the seconds value in index 6), then converts it back to a serial date number:
x = datenum(floor(datevec(x)));
I have a time series xlsx data which has columns like the following one. I would like to get the row data that are in between 8:00:00 AM to 10:00:00 AM for my analysis. Can any one help me out?
Add Velocity Time
0.128835374 10.34912454 8:44:23 AM
0.20423977 8.078739988 8:47:01 AM
0.110629502 13.4081172 9:19:46 AM
0.088979639 5.057336749 9:24:02 AM
0.128835374 10.60785265 10:21:29 AM
0.20423977 9.46599837 10:23:06 AM
[num, txt] = xlsread('Consective_result.xlsx');
T = num(:,3);
TimeVector = datevec(T)
You almost have it right. Use the third column of your txt cell array, and skip over the first row so you don't get the time header. I'm going to assume that your times are entered in as text. Once you do this, just use datenum and determine those times that are later than 8:00 AM and less than 10:00 AM. datenum can conveniently take in a cell array of strings, and it will output a numeric vector where each time string in your cell array is converted into its corresponding numerical representation.
Once you find those rows, you can filter out the rows in each of num and txt using what we just talked about before you continue. Therefore:
[num, txt] = xlsread('Consective_result.xlsx');
times = txt(2:end,3); %// Get the 3rd column, skip 1st row
time_nums = datenum(times); %// Get the numerical representation of the times
%// Figure out those rows that are between 8:00 AM and 10:00 AM
times_to_choose = time_nums >= datenum('08:00:00AM') & time_nums <= datenum('10:00:00AM');
%// Remove those rows then continue
num(1 + times_to_choose) = [];
txt(1 + times_to_choose) = [];
Take special care that I added a 1 to the indices because we omitted the time header in your spreadsheet. Now, num and txt should only contain those times that are between 8:00 AM and 10:00 AM.
I want to do something like
scatter(timesRefined, upProb)
where timesRefined is a cell array in which each entry is a string corresponding to a time moment, such as 8:32:21.122 and upProb is simply a vector of numbers with same length as cell array. What is the most convenient way to do this?
You can convert your timesRefined cell to a numeric representation of date with datenum
>> timesRefined = {'8:32:21.122','9:30:54.123'};
>> datenum(timesRefined)
ans =
734869.355800023
734869.396459757
The resulting number expresses a date as days from the epoch. Since you are not concerned with days, just time, and provided your observations are contained within one day, you can simply take the fractional part of the datenum output:
>> datestr(mod(datenum(timesRefined),1))
ans =
8:32 AM
9:30 AM
and do scater(mod(datenum(timesRefined),1),upProb)
EDIT:
As pointed out by Pursuit, you can use the result of datenum directly as your x values and use datetick('x','HH:MM:SS.FFF')
strsplit from the Matlab file exchange should help. If all values are numeric, you'll get a matrix back.
timestr = '8:32:21.122';
timenum = strsplit(timestr,':');
convmat = [60*60; 60; 1];
time_in_seconds = sum(timenum .* convmat);