diff --git a/matlab/@dates/dates.m b/matlab/@dates/dates.m index 99093bfe7..5cb9a7318 100644 --- a/matlab/@dates/dates.m +++ b/matlab/@dates/dates.m @@ -45,7 +45,7 @@ function dd = dates(varargin) % --*-- Unitary tests --*-- %! @end deftypefn %@eod: -% Copyright (C) 2011-2013 Dynare Team +% Copyright (C) 2011-2014 Dynare Team % % This file is part of Dynare. % @@ -62,6 +62,7 @@ function dd = dates(varargin) % --*-- Unitary tests --*-- % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +% Initialization. if nargin>0 && ischar(varargin{1}) && isequal(varargin{1},'initialize') dd = struct('ndat', 0, 'freq', NaN(0), 'time', NaN(0,2)); dd = class(dd,'dates'); @@ -71,61 +72,98 @@ end dd = evalin('base','emptydatesobject'); -switch nargin - case 0 - % Returns an empty object +if isequal(nargin, 0) + % Return an empty dates obect return - case 1 - if isa(varargin{1},'dates') - % Returns a copy of the input argument - dd = varargin{1}; - elseif isdate(varargin{1}) - date = string2date(varargin{1}); - dd.ndat = 1; - dd.freq = date.freq; - dd.time = date.time; - elseif isfreq(varargin{1}) - % Instantiate an empty dates object (only set frequency) - if ischar(varargin{1}) - dd.freq = string2freq(varargin{1}); - else - dd.freq = varargin{1}; - end +end + +if all(cellfun(@isdates, varargin)) + % Concatenates dates in a dates object. + dd = horzcat(varargin{:}); + return +end + +if all(cellfun(@isstringdate,varargin)) + % Concatenates dates in a dates object. + tmp = cellfun(@string2date,varargin); + if all([tmp.freq]-tmp(1).freq==0) + dd.freq = tmp(1).freq; else - error('dates:: Wrong calling sequence of the constructor!') + error('dates::dates: Wrong calling sequence of the constructor! All dates must have common frequency.') end - otherwise - if isdate(varargin{1}) - dd.ndat = nargin; - dd.time = NaN(dd.ndat,2); - date = string2date(varargin{1}); - dd.freq = date.freq; - dd.time(1,:) = date.time; - elseif isdates(varargin{1}) - dd = horzcat(varargin{:}); - return - elseif isfreq(varargin{1}) - S.type = '()'; - S.subs = varargin; - dd = subsref(dd,S); - return + dd.ndat = length(tmp); + dd.time = transpose(reshape([tmp.time],2,dd.ndat)); + return +end + +if isequal(nargin,1) && isfreq(varargin{1}) + % Instantiate an empty dates object (only set frequency) + if ischar(varargin{1}) + dd.freq = string2freq(varargin{1}); else - error('dates::dates: Wrong calling sequence!') + dd.freq = varargin{1}; end - for i=2:dd.ndat - if isdate(varargin{i}) - date = string2date(varargin{i}); - if isequal(date.freq,dd.freq) - dd.time(i,:) = date.time; + return +end + +if isequal(nargin,3) && isfreq(varargin{1}) + if ischar(varargin{1}) + dd.freq = string2freq(varargin{1}); + else + dd.freq = varargin{1}; + end + if (isnumeric(varargin{2}) && isvector(varargin{2}) && isint(varargin{2})) + if isnumeric(varargin{3}) && isvector(varargin{3}) && isint(varargin{3}) + if all(varargin{3}>=1) && all(varargin{3}<=dd.freq) + dd.time = [varargin{2}(:), varargin{3}(:)]; + dd.ndat = size(dd.time,1); else - error(sprintf('dates::dates: Check that all the inputs have the same frequency (see input number %i)!',i)) + error(sprintf('dates::dates: Wrong calling sequence of the constructor! Third input must contain integers between 1 and %i.',dd.freq)) end else - error(sprintf('dates::dates: Input %i has to be a string date!',i)) + error('dates::dates: Wrong calling sequence of the constructor! Third input must be a vector of integers.') + end + else + error('dates::dates: Wrong calling sequence of the constructor! Second input must be a vector of integers.') + end + return +end + +if isequal(nargin,2) && isfreq(varargin{1}) + if ischar(varargin{1}) + dd.freq = string2freq(varargin{1}); + else + dd.freq = varargin{1}; + end + if isequal(dd.freq, 1) + if (isnumeric(varargin{2}) && isvector(varargin{2}) && isint(varargin{2})) + dd.time = [varargin{2}, ones(length(varargin{2},1))]; + dd.ndat = size(dd.time,1); + return + else + error('dates::dates: Wrong calling sequence of the constructor! Second input must be a vector of integers.') + end + else + if isequal(size(varargin{2},2), 2) + if all(isint(varargin{2}(:,1))) && all(isint(varargin{2}(:,1))) + if all(varargin{2}(:,2)>=1) && all(varargin{2}(:,2)<=dd.freq) + dd.time = [varargin{2}(:,1), varargin{2}(:,2)]; + dd.ndat = size(dd.time,1); + else + error(sprintf('dates::dates: Wrong calling sequence of the constructor! Second column of the last input must contain integers between 1 and %i.',dd.freq)) + end + else + error('dates::dates: Wrong calling sequence! Second input argument must be an array of integers.') + end + else + error('dates::dates: Wrong calling sequence!') end end + return end +error('dates::dates: Wrong calling sequence!') + %@test:1 %$ % Define some dates %$ B1 = '1945Q3'; diff --git a/matlab/utilities/dates/isdate.m b/matlab/utilities/dates/isdate.m index 67bfcdb2d..726e5e479 100644 --- a/matlab/utilities/dates/isdate.m +++ b/matlab/utilities/dates/isdate.m @@ -30,11 +30,11 @@ if isnumeric(str) && isscalar(str) return end -b = isquaterly(str) || isyearly(str) || ismonthly(str) || isweekly(str); +b = isstringdate(str); %@test:1 %$ -%$ date_1 = '1950M2'; +%$ date_1 = 1950; %$ date_2 = '1950m2'; %$ date_3 = '-1950m2'; %$ date_4 = '1950m52'; diff --git a/matlab/utilities/dates/isstringdate.m b/matlab/utilities/dates/isstringdate.m new file mode 100644 index 000000000..fbac8b007 --- /dev/null +++ b/matlab/utilities/dates/isstringdate.m @@ -0,0 +1,54 @@ +function b = isstringdate(str) % --*-- Unitary tests --*-- + +% Tests if the input string can be interpreted as a date. +% +% INPUTS +% o str string. +% +% OUTPUTS +% o b integer scalar, equal to 1 if str can be interpreted as a date or 0 otherwise. + +% Copyright (C) 2013 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +if ischar(str) + b = isquaterly(str) || isyearly(str) || ismonthly(str) || isweekly(str); +else + b = 0; +end + +%@test:1 +%$ +%$ date_1 = '1950M2'; +%$ date_2 = '1950m2'; +%$ date_3 = '-1950m2'; +%$ date_4 = '1950m52'; +%$ date_5 = ' 1950'; +%$ date_6 = '1950Y'; +%$ date_7 = '-1950a'; +%$ date_8 = '1950m '; +%$ +%$ t(1) = dyn_assert(isstringdate(date_1),1); +%$ t(2) = dyn_assert(isstringdate(date_2),1); +%$ t(3) = dyn_assert(isstringdate(date_3),1); +%$ t(4) = dyn_assert(isstringdate(date_4),0); +%$ t(5) = dyn_assert(isstringdate(date_5),0); +%$ t(6) = dyn_assert(isstringdate(date_6),1); +%$ t(7) = dyn_assert(isstringdate(date_7),1); +%$ t(8) = dyn_assert(isstringdate(date_8),0); +%$ T = all(t); +%@eof:1 \ No newline at end of file