【问题标题】:How to identify and homogenize date format of instances in a string?如何识别和同质化字符串中实例的日期格式?
【发布时间】:2017-10-20 00:43:54
【问题描述】:

我无法找到一种方法来识别 MATLAB 中字符串的日期格式并将所有这些格式设置为相同的格式。我有以下单元格数组:

list = {'01-Sep-1882'; ...
        '01-Aug-1895'; ...
        '04/01/1912'; ...
        'Tue, 05/28/46'; ...
        'Tue, 03/10/53'; ... 
        '06/20/58'; ...
        'Thu, 09/20/73'; ...
        'Fri, 08/15/75'; ...
        'Sun, 12/01/1996'};

如果我选择datenum(list),则会出现错误消息,因为所有行的日期格式都不相同。你能想出一种方法来规避这个问题吗?

【问题讨论】:

  • list 是元胞数组吗?
  • 嗨@rayryeng,是的。格式为:list = '12/15/68' 'Sun, 01/15/89'...
  • 执行此操作的一种方法是循环遍历单元格的每个元素并单独使用datenum。但是,如果您在元胞数组中以字母形式以月份的日期开头的任何元素上使用 datenumTue, Thu, Fri 等,然后是数字形式的日期,MATLAB 目前没有内置格式说明符寻找这种日期,所以它会在这里给你一个错误。丢弃这些并仅依赖日期的数字形式是否安全?
  • 与@rayryeng 一起使用,最简单(可能也是最不优雅)的解决方案可能是简单地循环单元格数组并将各个日期数字存储到新的数字列表中。这应该让 numList 成为一个很好的同构数值数组,以便您随意处理。
  • 非常感谢您的建议!

标签: string matlab date format


【解决方案1】:

您可以通过连续应用datetime 来转换每种格式并使用isnat 来识别那些没有正确转换的日期来做到这一点。此外,您可以在 date format string 中指定一周中的哪几天,以及仅使用最后两个数字在年份中使用的 pivot year。从您问题中的示例数据和预期日期格式开始,以下是执行此操作的代码:

% Input:
list = {'01-Sep-1882'; ...
        '01-Aug-1895'; ...
        '04/01/1912'; ...
        'Tue, 05/28/46'; ...
        'Tue, 03/10/53'; ...
        '06/20/58'; ...
        'Thu, 09/20/73'; ...
        'Fri, 08/15/75'; ...
        'Sun, 12/01/1996'};

% Conversion code:
dt = datetime(list, 'Format', 'dd-MMM-yyyy');
index = isnat(dt);
dt(index) = datetime(list(index), 'Format', 'MM/dd/yy', 'PivotYear', 1900);
index = isnat(dt);
dt(index) = datetime(list(index), 'Format', 'eee, MM/dd/yy', 'PivotYear', 1900)

% Output:
dt = 

  9×1 datetime array

   01-Sep-1882
   01-Aug-1895
   01-Apr-1912
   28-May-1946
   10-Mar-1953
   20-Jun-1958
   20-Sep-1973
   15-Aug-1975
   01-Dec-1996

现在您可以使用datenum 将这些转换为数值:

dnum = datenum(dt);

【讨论】:

    【解决方案2】:

    这里的部分问题是 MATLAB 的 datenum 无法理解这种格式:Tue, 05/28/46。所以让我们清理一下原始列表,以便它可以理解。

    % original list
    list = {'01-Sep-1882','01-Aug-1895','04/01/1912','Tue, 05/28/46','Tue, 03/10/53','06/20/58','Thu, 09/20/73','Fri, 08/15/75','Sun, 12/01/1996'}
    
    % split each cell in the list
    list_split = cellfun(@(x) strsplit(x,' '), list, 'UniformOutput', false);
    
    % now detect where there is unusual format, this will give logical array
    abnormal_idx = cellfun(@(x) length(x) == 2, list_split,'UniformOutput', true)
    
    % make copy
    clean_list = list;
    
    % now at abnormal indices retain only the part that MATLAB understands
    clean_list(abnormal_idx) = cellfun(@(x) x{2}, list_split(abnormal_idx), 'UniformOutput', false);
    
    % now run datenum on clean list
    date_num = cellfun(@datenum, clean_list, 'UniformOutput', true);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 2017-06-14
      • 1970-01-01
      相关资源
      最近更新 更多