空字符串串联的Datenum行为

时间:2019-06-18 15:35:58

标签: matlab date

我注意到使用MATLAB R2017a及更高版本的函数datenum中的行为异常:

如果您尝试运行:

date = datenum([""],'yyyymmdd');

我们收到警告:

  

警告:不支持将DATENUM与空的日期字符向量或空的字符串一起使用。       结果可能会在将来的版本中更改。

date = 
      0x1 empty double column vector

但是现在,如果我们运行:

date = datenum(["","20181012"],'yyyymmdd')

我们获得:

date = 2x1:
          737426 % which corresponds to 20190101
          737345

因此,两次我们都为datenum提供一个空字符串,但是如果数组包含多个字符串,结果将有所不同。为什么在存在其他字符串(甚至是另一个空字符串)时却不能解析空字符串?

2 个答案:

答案 0 :(得分:5)

这可能是一个错误。

datenum函数的开头包含

arg1 = stringToLegacyText(arg1);

其中arg1datenum的第一个输入。 stringToLegacyText函数根据其代码执行以下操作:

S = STRINGTOLEGACYTEXT(S) converts the string array S to a char row vector,
if S is a scalar, or to a cellstr, if S is not a scalar.

也就是说,

>> stringToLegacyText([""])
ans =
  0×0 empty char array

>> stringToLegacyText(["" ""])
ans =
  1×2 cell array
    {0×0 char}    {0×0 char}

>> stringToLegacyText(["" "20181012"])
ans =
  1×2 cell array
    {0×0 char}    {'20181012'}

稍后有此测试:

if isdatestr && isempty(arg1)
   n = zeros(0,1);
   warning(message('MATLAB:datenum:EmptyDate'));
   return;
end

,如果arg1为空,则会产生您提到的警告。对于上面的第一种情况([""]),测试结果为true;对于第二种情况(["" ""])或第三种情况(["" "20181012"]),测试结果为true。因此,对于第二种或第三种情况,该功能将继续

n = dtstr2dtnummx(arg1,matlab.internal.datetime.cnv2icudf(arg2))

dtstr2dtnummx函数未记录:

>> which dtstr2dtnummx
built-in (undocumented)

但是它希望将char向量的单元格数组作为第一个参数,并以某种方式为空字符向量给出737426

>> dtstr2dtnummx({''}, matlab.internal.datetime.cnv2icudf(arg2))
ans =
      737426

>> dtstr2dtnummx({'' ''}, matlab.internal.datetime.cnv2icudf(arg2))
ans =
      737426
      737426

>> dtstr2dtnummx({'' '20181012'}, matlab.internal.datetime.cnv2icudf(arg2))
ans =
      737426
      737345

答案 1 :(得分:4)

我能够通过键入edit datenum来了解datenum在R2018a中如何解析其输入参数。它要做的第一件事是将第一个参数传递给函数stringToLegacyText,该函数将其从string type转换为character array或{{3}这是关键) }}:

>> import matlab.internal.datatypes.stringToLegacyText  % Get helper function
>> stringToLegacyText([""])  % Single empty string

ans =

  0×0 empty char array

>> stringToLegacyText(["", "20181012"])  % Array of strings

ans =

  1×2 cell array

    {0×0 char}    {'20181012'}

稍后在代码中,它将执行此检查:

if isdatestr && isempty(arg1)
    n = zeros(0,1);
    warning(message('MATLAB:datenum:EmptyDate'));
    return;
end

这就是出现差异的地方。 cell array of character arrays函数为空字符数组返回true(发出警告),但对于非空单元格数组返回false,即使该单元格数组包含所有空对象也是如此。无论出于何种原因,空条目默认为2019年1月1日 st

>> datestr(737426)

ans =

    '01-Jan-2019'

我认为这里的正确解决方法是更新条件以检查是否有任何空条目的单元格数组:

if isdatestr && (isempty(arg1) || (iscell(arg1) && any(cellfun('isempty', arg1))))
    n = zeros(0,1);
    warning(message('MATLAB:datenum:EmptyDate'));
    return;
end