Reputation: 3
I am trying to plot in matlab using values for the x-axis from a datetime array.
Example of one value: '2016-06-03T13:37:20.315Z'
At first the values are saved into a struct array from where I try to copy them into a separate array. I do it with the following code:
timestamp=[];
for j=1:length(data)
timestamp = getfield(data,{j},'timestamp');
timestamp{j}=(datetime);
end
But when I take a look at the array it seems like all the values are one date, which is not even in the "data" struct array.
Example:
timestamp{1} = '14-Dec-2018 00:31:05';
timestamp{10} = '14-Dec-2018 00:31:05';
timestamp{19} = '14-Dec-2018 00:31:05';
My first thoughts were that it is probably because of the input format so I tried
timestamp{j}=(datetime(timestamp,'InputFormat','uuuu-MM-dd''T''HH:mmXXX','TimeZone','UTC'));
But I got a message: "Error using datetime (line 635) Unable to convert '2016-06-03T13:37:20.315Z' to datetime using the format 'uuuu-MM-dd'T'HH:mmXXX'."
Any ideas?
Upvotes: 0
Views: 475
Reputation: 30046
Your indexing and type conversion are just a bit confusing, see my comments...
% Your code:
timestamp=[];
for i=1:length(data) % Your loop variable is "i"
% You override the entire "timestamp" array here, with element "j" not "i" of "data"
% You also don't need to use getfield here
timestamp = getfield(data,{j},'timestamp');
% You override element "j" (again, not "i") with the CURRENT datetime.
% This line doesn't do any type conversion, "datetime" with no arguments is now!
% Also you're using curly braces for indexing, which isn't right for a datetime array
timestamp{j}=(datetime);
end
You can correct this as follows:
timestamp = NaT(1,length(data)); % pre-allocate the output to "not a time" array
for ii = 1:length(data)
t = getfield( data, {ii}, 'timestamp' );
t( t == 'T' | t == 'Z' ) = []; % remove T and Z, they will break datetime
timestamp( ii ) = datetime( t, 'InputFormat', 'yyyy-MM-ddHH:mm:ss.SSS' );
end
Output:
timestamp =
1×2 datetime array
03-Jun-2016 13:37:20 03-Jun-2016 13:37:21
(Created using your example string, and the same string with one second added).
That's how to correct your code, here's how I would do it:
timestamp = regexprep( {data.timestamp}, '[TZ]', '' );
timestamp = datetime( timestamp, 'InputFormat', 'yyyy-MM-ddHH:mm:ss.SSS' );
Upvotes: 0
Reputation: 364
There are numerous errors in your code. They are summarized below.
Solutions to the problem
- You should use getfield function to access the timestamp char array from the data struct altogether in a single line without using loops.
-
- You should remove the offset fields(T and Z) first from the date char array and
-
- Finally, you should convert the edited datetime strings back to the datetime type using required format to be used in plot.
The code illustrating the procedure is given below.
% suppose we have a struct named data
% with a field known as timestamp holding the
% different datetime char arrays of particular
% TimeZone offsets
data.timestamp = {'2016-06-03T13:37:20.315Z', '2016-07-10T17:45:20.200Z', ...
'2016-07-09T13:37:21.305Z', '2016-11-10T01:30:20.320Z'};
% now getting the timestamp field elements in a variable using getfield()
% command
timestamp = getfield(data, 'timestamp')
% now removing each offsets chars(T and Z) from each datetime strings
edited_timestamp = strrep(timestamp, 'T', ' '); % removing T
edited_timestamp = strrep(edited_timestamp, 'Z', '') % removing Z
% finally, convert the edited_timestamp back to datetime type using the
% required format to use in plot
timestamp_datetime = datetime(edited_timestamp, 'Format', 'yyyy-MM-dd HH:mm:ss.SSS')
% ------------------------------------------------------
% now you can do the plotting here using timestamp_datetime
% ------------------------------------------------------
% e.g., plot(timestamp_datetime, [1:4])
Upvotes: 1