Datenum behaviour with empty string concatenation
This is probably a bug.
The beginning of the datenum
function contains
arg1 = stringToLegacyText(arg1);
where arg1
is the first input of datenum
. The stringToLegacyText
function does the following, according to its code:
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.
That is,
>> 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'}
Later on there is this test:
if isdatestr && isempty(arg1) n = zeros(0,1); warning(message('MATLAB:datenum:EmptyDate')); return; end
which produces the warning you mention if arg1
is empty. The test yields true for the first case above ([""]
), but not for the second (["" ""]
) or third (["" "20181012"]
). So for the second or third cases the function continues to
n = dtstr2dtnummx(arg1,matlab.internal.datetime.cnv2icudf(arg2))
The dtstr2dtnummx
function is undocumented:
>> which dtstr2dtnummx built-in (undocumented)
But it expects a cell array of char vectors as first argument, and somehow gives 737426
for empty char vectors:
>> 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
I was able to look at how datenum
parses its input arguments in R2018a by typing edit datenum
. One of the first things it does is pass the first argument to a function stringToLegacyText
, which converts it from a string type to either a character array or (and this is key) a cell array of character arrays:
>> 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'}
A short while later in the code, it performs this check:
if isdatestr && isempty(arg1)
n = zeros(0,1);
warning(message('MATLAB:datenum:EmptyDate'));
return;
end
And this is where the discrepancy arises. The isempty
function returns true
for an empty character array (issuing the warning) but returns false for a non-empty cell array, even if that cell array contains all empty objects. For whatever reason, the empty entries default to January 1st, 2019:
>> datestr(737426)
ans =
'01-Jan-2019'
I think the correct fix here would be to update the condition to check for a cell array with any empty entries:
if isdatestr && (isempty(arg1) || (iscell(arg1) && any(cellfun('isempty', arg1))))
n = zeros(0,1);
warning(message('MATLAB:datenum:EmptyDate'));
return;
end