【问题标题】:Datetime() returns wrong valuesDatetime() 返回错误值
【发布时间】:2018-12-14 16:45:11
【问题描述】:

我正在尝试使用 datetime 数组中的 x 轴值在 matlab 中进行绘图。
一个值的示例:'2016-06-03T13:37:20.315Z'
首先,这些值被保存到一个结构数组中,我尝试将它们复制到一个单独的数组中。我使用以下代码:

 timestamp=[];
 for j=1:length(data)
   timestamp = getfield(data,{j},'timestamp');
   timestamp{j}=(datetime);
end  

但是当我查看数组时,似乎所有值都是一个日期,甚至不在“数据”结构数组中。
示例:

timestamp{1} = '14-Dec-2018 00:31:05';  
timestamp{10} = '14-Dec-2018 00:31:05';   
timestamp{19} = '14-Dec-2018 00:31:05'; 

我的第一个想法是可能是输入格式的问题所以我尝试了

timestamp{j}=(datetime(timestamp,'InputFormat','uuuu-MM-dd''T''HH:mmXXX','TimeZone','UTC'));  

但我收到一条消息:“使用日期时间时出错(第 635 行) 无法使用格式 'uuuu-MM-dd'T'HH:mmXXX' 将 '2016-06-03T13:37:20.315Z' 转换为日期时间。"

有什么想法吗?

【问题讨论】:

  • 在您的 for 循环中,您正在沿 i 迭代,但您正在访问数据中的 jth 对象。这可能解释了为什么它们都是相同的日期,但不能解释错误的日期。

标签: matlab datetime


【解决方案1】:

您的代码中有许多错误。它们总结如下。

  1. 您正在循环获取存储在给定结构中的字段中的数据。而您只需使用 getfield() 函数即可直接获取存储在结构中特定字段中的所有数据。
  2. 在循环中,您只是使用 datetime 函数来填充时间戳变量。因此,每次调用 datetime 时,它​​都会返回当前时间,因此会在每个位置使用相同的值填充数组。
  3. 您不能直接将具有 TimeZone 偏移量的日期字符数组直接转换为日期时间格式。您需要先使用 strrep() 命令删除偏移量。

问题的解决方案

  1. 您应该使用 getfield 函数从 数据结构完全在一行中,不使用循环。

-

  1. 您应该首先从日期字符数组中删除偏移字段(T 和 Z),然后

-

  1. 最后,您应该将已编辑的日期时间字符串转换回日期时间类型,使用所需的格式在绘图中使用。

说明该过程的代码如下。

% 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])

输出

【讨论】:

    【解决方案2】:

    您的索引和类型转换有点混乱,请参阅我的 cmets...

    % 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 
    

    您可以按如下方式更正此问题:

    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
    

    输出:

    timestamp = 
     1×2 datetime array
     03-Jun-2016 13:37:20   03-Jun-2016 13:37:21
    

    (使用您的示例字符串创建,并添加了一秒钟的相同字符串)。


    这就是纠正代码的方法,我会这样做:

    timestamp = regexprep( {data.timestamp}, '[TZ]', '' );
    timestamp = datetime( timestamp, 'InputFormat', 'yyyy-MM-ddHH:mm:ss.SSS' );   
    

    【讨论】:

      猜你喜欢
      • 2018-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多