diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7775a14c1352adefcd8fe2b75a6d89569f5e32ea..7cf0fb4806025577ea710d39a1189d1d43b91aea 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,6 @@ variables:
   TERM: linux
 
 before_script:
-  - git clone https://git.dynare.org/Dynare/dates
   - git clone https://git.dynare.org/Dynare/m-unit-tests
 
 testsuite_matlab:
diff --git a/LICENSE.md b/LICENSE.md
index be44670163c68945a8a2a8b4e75ba2f34e005f03..ea80a3567d9969b1b0b8a3d911588a43f6aecc53 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
-> Copyright (C) 2014 Dynare Team
+> Copyright (C) 2014-2018 Dynare Team
 >
-> The dseries Matlab/Octave class is licensed under GNU GPL as published by
+> The dseries and dates Matlab/Octave classes are licensed under GNU GPL as published by
 > the Free Software Foundation, either version 3 of the License, or (at
 > your option) any later version.
 >
diff --git a/Makefile b/Makefile
index 80cd0c547753864e77157aa03a3ebb413cc23574..024e6ca4df9d8a899cc928b99480ebfa81cfbf30 100644
--- a/Makefile
+++ b/Makefile
@@ -3,12 +3,25 @@ MATLAB=`which matlab`
 
 all: check-octave check-matlab
 
-check-octave:
-	@cd tests ;\
-	$(OCTAVE) --no-init-file --silent --no-history --eval "addpath ../m-unit-tests/src; addpath ../dates/src; runalltests" && [ ! -f ./failed ] && [ -f ./pass ]
+check-octave: check-octave-dseries check-octave-dates
 
-check-matlab:
-	@$(MATLAB) -nosplash -nodisplay -r "addpath m-unit-tests/src; addpath dates/src; cd tests; runalltests; quit" && [ ! -f ./tests/failed ] && [ -f ./tests/pass ]
+check-matlab: check-matlab-dseries check-matlab-dates
+
+
+check-octave-dseries:
+	@cd tests/dseries ;\
+	$(OCTAVE) --no-init-file --silent --no-history --eval "addpath([pwd() '/../../m-unit-tests/src']); runalltests" && [ ! -f ./failed ] && [ -f ./pass ]
+
+check-octave-dates:
+	@cd tests/dates ;\
+	$(OCTAVE) --no-init-file --silent --no-history --eval "addpath([pwd() '/../../m-unit-tests/src']); runalltests" && [ ! -f ./failed ] && [ -f ./pass ]
+
+check-matlab-dseries:
+	@$(MATLAB)  -nosplash -nodisplay -r "addpath m-unit-tests/src; cd tests/dseries; runalltests; quit" && [ ! -f ./tests/failed ] && [ -f ./tests/pass ]
+
+check-matlab-dates:
+	@$(MATLAB)  -nosplash -nodisplay -r "addpath m-unit-tests/src; cd tests/dates; runalltests; quit" && [ ! -f ./tests/failed ] && [ -f ./tests/pass ]
 
 check-clean:
-	rm -f tests/*_test_*.m tests/*.csv tests/*.xls tests/*.xlsx tests/*.mat tests/failed tests/datafile_for_test
+	rm -f tests/dseries/*_test_*.m tests/dseries/*.csv tests/dseries/*.xls tests/dseries/*.xlsx tests/dseries/*.mat tests/dseries/failed tests/dseries/datafile_for_test
+	rm -f tests/dates/*_test_*.m tests/dates/*.csv tests/dates/*.xls tests/dates/*.xlsx tests/dates/*.mat tests/dates/failed tests/dates/datafile_for_test
diff --git a/data/test_dates4display.m b/data/test_dates4display.m
new file mode 100644
index 0000000000000000000000000000000000000000..b84264f55ab1f24992b7cef7edc4978321200b49
--- /dev/null
+++ b/data/test_dates4display.m
@@ -0,0 +1,4 @@
+expected_str_1 = sprintf('toto is an empty dates object.\n');
+expected_str_2 = sprintf('toto = <dates: 1950Q1, 1950Q2>\n');
+expected_str_3 = sprintf('toto = <dates: 1950Q1, 1950Q2, ..., 1950Q4, 1951Q1>\n');
+expected_str_4 = sprintf('toto = <dates: 1950Q1, 1950Q2, 1950Q3, 1950Q4, 1951Q1>\n');
diff --git a/src/@dates/append.m b/src/@dates/append.m
new file mode 100644
index 0000000000000000000000000000000000000000..231da9731b428446311601cce85927df0c3df09d
--- /dev/null
+++ b/src/@dates/append.m
@@ -0,0 +1,136 @@
+function o = append(o, d) % --*-- Unitary tests --*--
+
+% append method for dates class.
+%
+% INPUTS
+% - o [dates]
+% - a [dates or string] dates object with one element or string that can be interpreted as a date.
+%
+% OUTPUTS
+% - o [dates] dates object containing dates defined in o and d.
+
+% Copyright (C) 2012-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if isa(d, 'dates')
+    if ~isequal(length(d), 1)
+        error('dates:append:ArgCheck','Input argument %s has to be a dates object with one element.', inputname(2))
+    end
+    if isempty(d)
+        return
+    end
+elseif isdate(d)
+    d = dates(d);
+end
+
+if ~isequal(o.freq, d.freq)
+    error('dates:append:ArgCheck','dates must have common frequency!')
+end
+
+o = copy(o);
+o.append_(d);
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2,B1);
+%$ try
+%$     d.append(dates(B5));
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ f.time = [1945 3; 1950 1; 1950 2; 1953 4];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2,B1);
+%$ try
+%$     c = d.append(B5);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,f.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(c.freq,e.freq);
+%$     t(5) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ f.time = [1945 3; 1950 1; 1950 2; 1953 4];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2,B1);
+%$ try
+%$     c = append(d, B5);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,f.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(c.freq,e.freq);
+%$     t(5) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:3
diff --git a/src/@dates/append_.m b/src/@dates/append_.m
new file mode 100644
index 0000000000000000000000000000000000000000..2c4a3a8de26826ebafb175c6518c71f998382481
--- /dev/null
+++ b/src/@dates/append_.m
@@ -0,0 +1,189 @@
+function o = append_(o, d) % --*-- Unitary tests --*--
+
+% append method for dates class (in place modification).
+%
+% INPUTS
+% - o [dates]
+% - a [dates or string] dates object with one element or string that can be interpreted as a date.
+%
+% OUTPUTS
+% - o [dates] dates object containing dates defined in o and d.
+
+% Copyright (C) 2012-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if isa(d, 'dates')
+    if ~isequal(length(d), 1)
+        error('dates:append_:ArgCheck','Input argument %s has to be a dates object with one element.', inputname(2))
+    end
+    if isempty(d)
+        return
+    end
+elseif isdate(d)
+    d = dates(d);
+end
+
+if ~isequal(o.freq, d.freq)
+    error('dates:append_:ArgCheck','dates must have common frequency!')
+end
+
+o.time = [o.time; d.time];
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2,B1);
+%$ try
+%$     d.append_(dates(B5));
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2,B1);
+%$ try
+%$     d.append_(B5);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2,B1);
+%$ try
+%$     c = d.append_(B5);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(d.freq,e.freq);
+%$     t(5) = dassert(c.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:3
+
+
+%@test:4
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3);
+%$ e = dates(B1,B2,B5);
+%$ try
+%$     d.append_(e);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define some dates
+%$ B = '1950Q2';
+%$
+%$ % Call the tested routine.
+%$ d = dates(B);
+%$ try
+%$     d.append_('1950Q3');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.time, [1950 2; 1950 3]);
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
+
+%@test:6
+%$ % Define some dates
+%$ B = '1950Q2';
+%$
+%$ % Call the tested routine.
+%$ d = dates(B);
+%$ try
+%$     d.append_('1950Z3');
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:6
diff --git a/src/@dates/char.m b/src/@dates/char.m
new file mode 100644
index 0000000000000000000000000000000000000000..fe41d6cb836a8ffe5f41151fb0404e26d8a2aac2
--- /dev/null
+++ b/src/@dates/char.m
@@ -0,0 +1,120 @@
+function s = char(o) % --*-- Unitary tests --*--
+
+% Given a one element dates object, returns a string with the formatted date.
+%
+% INPUTS
+% - o  [dates]
+%
+% OUTPUTS
+% - s  [string]
+
+% Copyright (C) 2014-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if length(o)>1
+    error('dates:char:ArgCheck', 'The input argument must be a dates object with one element!')
+end
+
+s = date2string(o.time, o.freq);
+
+%@test:1
+%$ % Define a dates object
+%$ o = dates('1950Q1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     str = char(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str,'1950Q1');
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define a dates object
+%$ o = dates('1950M1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     str = char(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str,'1950M1');
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define a dates object
+%$ o = dates('1950W50');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     str = char(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str,'1950W50');
+%$ end
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define a dates object
+%$ o = dates('1950Y');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     str = char(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str,'1950Y');
+%$ end
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define a dates object
+%$ o = dates('1950A');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     str = char(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str,'1950Y');
+%$ end
+%$ T = all(t);
+%@eof:5
diff --git a/src/@dates/colon.m b/src/@dates/colon.m
new file mode 100644
index 0000000000000000000000000000000000000000..2c43bae02c6e64455a271b5a140734f9201bc8a0
--- /dev/null
+++ b/src/@dates/colon.m
@@ -0,0 +1,192 @@
+function q = colon(varargin) % --*-- Unitary tests --*--
+
+% Overloads the colon operator (:). This method can be used to create ranges of dates.
+%
+% INPUTS
+%  o o [dates] Initial date.
+%  o d [integer] Number of periods between each date (default value, if nargin==2, is one)
+%  o p [dates] Terminal date.
+%
+% OUTPUTS
+%  o q [dates] Object with length(p-o) elements (if d==1).
+%
+% REMARKS
+% 1. p must be greater than o if d>0.
+% 2. p and q are dates objects with one element.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+% Check the input arguments.
+if isequal(nargin,2)
+    o = varargin{1};
+    p = varargin{2};
+    d = 1;
+    if ~(isa(o,'dates') && isa(p,'dates') && isequal(o.length(),1) && isequal(p.length(),1))
+        error('dates:colon:ArgCheck','In an expression like A:B, A and B must be one element dates objects!')
+    end
+elseif isequal(nargin,3)
+    o = varargin{1};
+    p = varargin{3};
+    d = varargin{2};
+    if ~(isa(o,'dates') && isa(p,'dates') && isequal(o.length(),1) && isequal(o.length(),1) && isscalar(d) && isint(d))
+        error('dates:colon:ArgCheck','In an expression like A:d:B, A and B must be one element dates objects and d a scalar integer!')
+    end
+    if isequal(d,0)
+        error('dates:colon:ArgCheck','In an expression like A:d:B, d (the incremental number of periods) must nonzero!')
+    end
+else
+    error('dates:colon:ArgCheck','See the manual for the colon (:) operator and dates objects.')
+end
+
+if ~isequal(o.freq, p.freq)
+    error('dates:colon:ArgCheck','dates::colon: Input arguments %s and %s must have common frequency!', inputname(1), inputname(2))
+end
+
+if o>p && d>0
+    error('dates:colon:ArgCheck','First date must preceed the second one!')
+end
+
+if p>o && d<0
+    error('dates:colon:ArgCheck','Second date must preceed the first one!')
+end
+
+% Initialize the output argument.
+q = dates();
+
+% Compute the number of elements in the returned dates object.
+n = (p-o)+1; % The number of elements in q dates object if d==1.
+m = n;
+if d>1 % Correction of the number of elements (if d is not equal to one).
+    m = length(1:d:n);
+end
+
+% Set the frequency in q
+q.freq = o.freq;
+
+if isequal(q.freq, 1)
+    % Yearly
+    q.time = NaN(m,2);
+    q.time(:,1) = o.time(1)+transpose(0:d:n-1);
+    q.time(:,2) = 1;
+else
+    % Weekly, Monthly, Quaterly
+    q.time = NaN(n,2);
+    initperiods = min(q.freq-o.time(2)+1,n);
+    q.time(1:initperiods,1) = o.time(1);
+    q.time(1:initperiods,2) = transpose(o.time(2)-1+(1:initperiods));
+    if n>initperiods
+        l = n-initperiods;
+        if l<=q.freq
+            q.time(initperiods+(1:l),1) = o.time(1)+1;
+            q.time(initperiods+(1:l),2) = transpose(1:l);
+        else
+            k = fix(l/o.freq);
+            r = rem(l,o.freq);
+            q.time(initperiods+(1:q.freq*k),2) = repmat(transpose(1:q.freq),k,1);
+            q.time(initperiods+(1:q.freq*k),1) = kron(o.time(1)+transpose(1:k),ones(q.freq,1));
+            if r>0
+                q.time(initperiods+q.freq*k+(1:r),1) = q.time(initperiods+q.freq*k,1)+1;
+                q.time(initperiods+q.freq*k+(1:r),2) = transpose(1:r);
+            end
+        end
+    end
+    if d>1
+        q.time = q.time(1:d:n,:);
+    end
+end
+
+%@test:1
+%$ % Define two dates
+%$ date_1 = '1950Q2';
+%$ date_2 = '1951Q4';
+%$
+%$ % Define expected results.
+%$ e.freq = 4;
+%$ e.time = [1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4];
+%$
+%$ % Call the tested routine.
+%$ d1 = dates(date_1);
+%$ d2 = dates(date_2);
+%$ d3 = d1:d2;
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d3.time,e.time);
+%$ t(2) = dassert(d3.freq,e.freq);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define expected results.
+%$ e.freq = 4;
+%$ e.time = [1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4];
+%$
+%$ % Call the tested routine.
+%$ d = dates('1950Q2'):dates('1951Q4');
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define expected results.
+%$ e.freq = 4;
+%$ e.time = [1950 2; 1950 4; 1951 2; 1951 4];
+%$
+%$ % Call the tested routine.
+%$ d = dates('1950Q2'):2:dates('1951Q4');
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ T = all(t);
+%@eof:3
+
+
+%$ @test:3
+%$ % Create an empty dates object for quaterly data
+%$ qq = dates('Q');
+%$
+%$ % Define expected results.
+%$ e.freq = 4;
+%$ e.time = [1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4];
+%$
+%$ % Call the tested routine.
+%$ d = qq(1950,2):qq(1951,4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ T = all(t);
+%$ @eof:3
+
+%$ @test:4
+%$ % Create an empty dates object for quaterly data
+%$ qq = dates('Q');
+%$
+%$ % Define expected results.
+%$ e.freq = 4;
+%$ e.time = [1950 1; 1950 2; 1950 3];
+%$
+%$ % Call the tested routine.
+%$ d = qq(1950,1):qq(1950,3);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ T = all(t);
+%$ @eof:4
diff --git a/src/@dates/copy.m b/src/@dates/copy.m
new file mode 100644
index 0000000000000000000000000000000000000000..3454125c2a32dd9470f590ead7bfb9d0982444d7
--- /dev/null
+++ b/src/@dates/copy.m
@@ -0,0 +1,49 @@
+function p = copy(o) % --*-- Unitary tests --*--
+
+% Do a copy of a dates object.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - p [dates]
+
+% Copyright (C) 2014-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+p = dates();
+p.freq = o.freq;
+p.time = o.time;
+
+%@test:1
+%$ % Define a dates object
+%$ o = dates('1945Q3','1944Q4');
+%$ q = dates('1945Q3','1944Q4');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     p = copy(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$      o.sort_();
+%$      t(2) = dassert(p, q);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/@dates/dates.m b/src/@dates/dates.m
new file mode 100644
index 0000000000000000000000000000000000000000..95b1612034583c00ae0ec920b2500b447f5697a6
--- /dev/null
+++ b/src/@dates/dates.m
@@ -0,0 +1,272 @@
+classdef dates<handle % --*-- Unitary tests --*--
+
+% Copyright (C) 2014-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+properties
+    freq = []; % Frequency (integer scalar)
+    time = []; % Array (one row for every date. first column is the year, second is the period)
+end
+
+methods
+    function o = dates(varargin)
+        if ~nargin
+            % Returns empty dates object.
+            o.freq = NaN(0);
+            o.time = NaN(0,2);
+            return
+        end
+        if all(cellfun(@isdates, varargin))
+            % Concatenates dates objects in a dates object.
+            o = 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)
+                o.freq = tmp(1).freq;
+            else
+                error('dates:ArgCheck', 'All dates passed as inputs must have the same frequency!')
+            end
+            o.time = transpose(reshape([tmp.time], 2, length(tmp)));
+            return
+        end
+        if isequal(nargin,1) && isfreq(varargin{1})
+            % Instantiate an empty dates object (only set frequency)
+            o.time = NaN(0,2);
+            if ischar(varargin{1})
+                o.freq = string2freq(varargin{1});
+            else
+                o.freq = varargin{1};
+            end
+            return
+        end
+        if isequal(nargin,3) && isfreq(varargin{1})
+            o.time = NaN(0,2);
+            if ischar(varargin{1})
+                o.freq = string2freq(varargin{1});
+            else
+                o.freq = varargin{1};
+            end
+            if (isnumeric(varargin{2}) && isvector(varargin{2}) && all(isint(varargin{2})))
+                if isnumeric(varargin{3}) && isvector(varargin{3}) && all(isint(varargin{3}))
+                    if all(varargin{3}>=1) && all(varargin{3}<=o.freq)
+                        o.time = [varargin{2}(:), varargin{3}(:)];
+                    else
+                        error('dates:ArgCheck','Third input must contain integers between 1 and %i.', o.freq)
+                    end
+                else
+                    error('dates:ArgCheck','Third input must be a vector of integers.')
+                end
+            else
+                error('dates:ArgCheck','Second input must be a vector of integers.')
+            end
+            return
+        end
+        if isequal(nargin,2) && isfreq(varargin{1})
+            o.time = NaN(0,2);
+            if ischar(varargin{1})
+                o.freq = string2freq(varargin{1});
+            else
+                o.freq = varargin{1};
+            end
+            if isequal(o.freq, 1)
+                if (isnumeric(varargin{2}) && isvector(varargin{2}) && all(isint(varargin{2})))
+                    o.time = [varargin{2}, ones(length(varargin{2}),1)];
+                    return
+                else
+                    error('dates:ArgCheck','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}(:,2)))
+                        if all(varargin{2}(:,2)>=1) && all(varargin{2}(:,2)<=o.freq)
+                            o.time = [varargin{2}(:,1), varargin{2}(:,2)];
+                        else
+                            error('dates:ArgCheck','Second column of the last input must contain integers between 1 and %i.',o.freq)
+                        end
+                    else
+                        error('dates:ArgCheck','Second input argument must be an array of integers.')
+                    end
+                else
+                    error('dates:ArgCheck','Wrong calling sequence!')
+                end
+            end
+            return
+        end
+        error('dates:ArgCheck','The input cannot be interpreted as a date. You should first read the manual!')
+    end % dates constructor.
+        % Other methods
+    p = sort(o);
+    o = sort_(o);
+    p = unique(o);
+    o = unique_(o);
+    p = append(o, d);
+    o = append_(o, d);
+    p = pop(o, d);
+    o = pop_(o, d);
+    p = remove(o, d);
+    o = remove_(o, d);
+    s = char(o);
+    a = double(o);
+    n = ndat(o);
+    n = length(o);
+end % methods
+end % classdef
+
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1945Q3';
+%$ B2 = '1950Q2';
+%$ B3 = '1950q1';
+%$ B4 = '1953Q4';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 2; 1950 1; 1953 4];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time, e.time);
+%$ t(2) = dassert(d.freq, e.freq);
+%$ t(3) = dassert(d.ndat(), size(e.time, 1));
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1945M3';
+%$ B2 = '1950M2';
+%$ B3 = '1950M10';
+%$ B4 = '1953M12';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 2; 1950 10; 1953 12];
+%$ e.freq = 12;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ t(3) = dassert(d.ndat(), size(e.time, 1));
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ B1 = '1945y';
+%$ B2 = '1950Y';
+%$ B3 = '1950a';
+%$ B4 = '1953A';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 1; 1950 1; 1950 1; 1953 1];
+%$ e.freq = 1;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time, e.time);
+%$ t(2) = dassert(d.freq, e.freq);
+%$ t(3) = dassert(d.ndat(), size(e.time, 1));
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define a dates object
+%$ B = dates('1950Q1'):dates('1960Q3');
+%$
+%$
+%$ % Call the tested routine.
+%$ d = B(2);
+%$ if isa(d,'dates')
+%$     t(1) = 1;
+%$ else
+%$     t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.freq,B.freq);
+%$     t(3) = dassert(d.time,[1950 2]);
+%$ end
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define a dates object
+%$ B = dates(4,1950,1):dates(4,1960,3);
+%$
+%$ % Call the tested routine.
+%$ d = B(2);
+%$ if isa(d,'dates')
+%$     t(1) = 1;
+%$ else
+%$     t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.freq,B.freq);
+%$     t(3) = dassert(d.time,[1950 2]);
+%$ end
+%$ T = all(t);
+%@eof:5
+
+%@test:6
+%$ % Define a dates object
+%$ B = dates(4,[1950 1]):dates(4,[1960 3]);
+%$
+%$ % Call the tested routine.
+%$ d = B(2);
+%$ if isa(d,'dates')
+%$     t(1) = 1;
+%$ else
+%$     t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.freq,B.freq);
+%$     t(3) = dassert(d.time,[1950 2]);
+%$ end
+%$ T = all(t);
+%@eof:6
+
+%@test:7
+%$ try
+%$   B = dates(4,[1950; 1950], [1; 2]);
+%$   t = 1;
+%$ catch
+%$   t = 0;
+%$ end
+%$
+%$ T = all(t);
+%@eof:7
+
+%@test:8
+%$ try
+%$   B = dates(4,[1950, 1950], [1, 2]);
+%$   t = 1;
+%$ catch
+%$   t = 0;
+%$ end
+%$
+%$ T = all(t);
+%@eof:8
diff --git a/src/@dates/disp.m b/src/@dates/disp.m
new file mode 100644
index 0000000000000000000000000000000000000000..89e82f93a9c123ffc4b81ad64793789d29f185de
--- /dev/null
+++ b/src/@dates/disp.m
@@ -0,0 +1,26 @@
+function disp(o)
+
+% Overloads the disp function for dates object.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPTS
+% None
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+fprintf(['\n' dates4display(o, inputname(1), Inf) '\n\n']);
\ No newline at end of file
diff --git a/src/@dates/display.m b/src/@dates/display.m
new file mode 100644
index 0000000000000000000000000000000000000000..3059ac87b552cf333b37c37706c9d3e5473e922d
--- /dev/null
+++ b/src/@dates/display.m
@@ -0,0 +1,26 @@
+function display(o)
+
+% Overloads display method for dates object.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPTS
+% None
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+fprintf(['\n' dates4display(o, inputname(1), 5) '\n\n']);
\ No newline at end of file
diff --git a/src/@dates/double.m b/src/@dates/double.m
new file mode 100644
index 0000000000000000000000000000000000000000..8ccae249902ff5aab8a91c539da392d6f7af275c
--- /dev/null
+++ b/src/@dates/double.m
@@ -0,0 +1,75 @@
+function [m, f]  = double(o) % --*-- Unitary tests --*--
+
+% Returns a vector of doubles with the fractional part corresponding
+% to the subperiod. Used for plots and to store dates in a matrix.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - m [double] o.ndat*1 vector of doubles.
+% - f [integer] scalar, the frequency (1, 4, 12 or 52).
+%
+% REMARKS
+%  Obviously the frequency is lost during the conversion.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+m = o.time(:,1)+(o.time(:,2)-1)/o.freq;
+if nargout>1
+    f = o.freq;
+end
+
+%@test:1
+%$ % Define a dates object
+%$ B = dates('1950Q1'):dates('1951Q1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     C = double(B);
+%$     t(1) = 1;
+%$ catch
+%$     t(1) = 0;
+%$ end
+%$
+%$ % Define expected results.
+%$ E = [ones(4,1)*1950; 1951];
+%$ E = E + [(transpose(1:4)-1)/4; 0];
+%$ if t(1)
+%$     t(2) = dassert(C,E);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Call the tested routine.
+%$ try
+%$     C = NaN(2,1);
+%$     C(1) = double(dates('1950Q1'));
+%$     C(2) = double(dates('1950Q2'));
+%$     t(1) = 1;
+%$ catch
+%$     t(1) = 0;
+%$ end
+%$
+%$ % Define expected results.
+%$ E = ones(2,1)*1950;
+%$ E = E + [0; .25];
+%$ if t(1)
+%$     t(2) = dassert(C,E);
+%$ end
+%$ T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/@dates/end.m b/src/@dates/end.m
new file mode 100644
index 0000000000000000000000000000000000000000..cd22c28c7c308e5af12e4f7bdae059aad4d0dd1d
--- /dev/null
+++ b/src/@dates/end.m
@@ -0,0 +1,49 @@
+function lastIndex = end(o, k, n) % --*-- Unitary tests --*--
+
+% Overloads end keyword.
+%
+% INPUTS
+%   o [dates]
+%   k [integer]  index where end appears
+%   n [integer]  number of indices
+%
+% OUTPUTS
+%   lastIndex [integer] last dates index
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+assert(k==1 && n==1, 'dates:end:ArgCheck', 'dates only has one dimension');
+lastIndex = o.ndat();
+
+%@test:1
+%$ % Define a dates object
+%$ o = dates('1938Q4'):dates('2015Q4');
+%$ q = dates('2015Q4');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     p = o(end);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$      t(2) = dassert(p, q);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/@dates/eq.m b/src/@dates/eq.m
new file mode 100644
index 0000000000000000000000000000000000000000..58ef96b7a062047fa3ecc9c05c232762d0cb855a
--- /dev/null
+++ b/src/@dates/eq.m
@@ -0,0 +1,90 @@
+function l = eq(varargin) % --*-- Unitary tests --*--
+
+% Overloads == operator for dates objects.
+%
+% INPUTS
+% - o [dates] dates object with n or 1 elements.
+% - p [dates] dates object with n or 1 elements.
+%
+% OUTPUTS
+% - l [logical] column vector of max(n,1) elements (zeros or ones).
+
+% Copyright (C) 2013-2015 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if varargin{1}.ndat>1 && varargin{2}.ndat>1 && ~isequal(varargin{1}.ndat, varargin{2}.ndat)
+    l = false;
+    return
+end
+
+[o, p] = comparison_arg_checks(varargin{:});
+
+if isequal(o.ndat(), p.ndat())
+    l = logical(transpose(all(transpose(eq(o.time,p.time)))));
+else
+    l = logical(transpose(all(transpose(bsxfun(@eq,o.time,p.time)))));
+end
+
+%@test:1
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1','1950Q2','1950Q3','1950Q4') ;
+%$ d2 = dates('1960Q1','1960Q2','1960Q3','1960Q4') ;
+%$ d3 = dates('1950Q1','1960Q2','1950Q3','1960Q4') ;
+%$
+%$ % Call the tested routine.
+%$ t1 = d1==d1;
+%$ t2 = d1==d2;
+%$ t3 = d1==d3;
+%$
+%$ % Check the results.
+%$ t(1) = dassert(t1,true(4,1));
+%$ t(2) = dassert(t2,false(4,1));
+%$ t(2) = dassert(t3,[true; false; true; false]);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1') ;
+%$ d2 = dates('1960Q1') ;
+%$ d3 = dates('1960Q1') ;
+%$
+%$ % Call the tested routine.
+%$ t1 = d1==d1;
+%$ t2 = d1==d2;
+%$ t3 = d1==d3;
+%$
+%$ % Check the results.
+%$ t(1) = dassert(t1,true);
+%$ t(2) = dassert(t2,false);
+%$ t(2) = dassert(t3,false);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1','1950Q2','1950Q3','1950Q4') ;
+%$ d2 = dates('1950Q2') ;
+%$ d3 = dates('1970Q1') ;
+%$
+%$ % Call the tested routine.
+%$ t1 = d1==d2;
+%$ t2 = d1==d3;
+%$
+%$ % Check the results.
+%$ t(1) = dassert(t1,[false; true; false; false]);
+%$ t(2) = dassert(t2,false(4,1));
+%$ T = all(t);
+%@eof:3
diff --git a/src/@dates/ge.m b/src/@dates/ge.m
new file mode 100644
index 0000000000000000000000000000000000000000..1edfba585983179e484105f293861e163818e135
--- /dev/null
+++ b/src/@dates/ge.m
@@ -0,0 +1,95 @@
+function l = ge(varargin)  % --*-- Unitary tests --*--
+
+% Overloads the >= operator for dates objects.
+%
+% INPUTS
+% - o [dates] dates object with n or 1 elements.
+% - p [dates] dates object with n or 1 elements.
+%
+% OUTPUTS
+% - l [logical] column vector of max(n,1) elements (zeros or ones).
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+[o, p] = comparison_arg_checks(varargin{:});
+
+if isequal(o.ndat(), p.ndat())
+    l = (o==p);
+    idx = find(l==false);
+    for i=1:length(idx)
+        l(idx(i)) = greaterorequal(o.time(idx(i),:), p.time(idx(i),:));
+    end
+else
+    if isequal(o.ndat(),1)
+        l = false(p.ndat(),1);
+        for i=1:p.ndat()
+            l(i) = greaterorequal(o.time, p.time(i,:));
+        end
+    else
+        l = false(o.ndat(),1);
+        for i=1:o.ndat()
+            l(i) = greaterorequal(o.time(i,:), p.time);
+        end
+    end
+end
+
+%@test:1
+%$ % Define some dates
+%$ date_2 = '1950Q2';
+%$ date_3 = '1950Q3';
+%$ date_4 = '1950Q1';
+%$ date_5 = '1949Q2';
+%$
+%$ % Call the tested routine.
+%$ d2 = dates(date_2);
+%$ d3 = dates(date_3);
+%$ d4 = dates(date_4);
+%$ d5 = dates(date_5);
+%$ i1 = (d2>=d3);
+%$ i2 = (d3>=d4);
+%$ i3 = (d4>=d2);
+%$ i4 = (d5>=d4);
+%$ i5 = (d5>=d5);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i1,false);
+%$ t(2) = dassert(i2,true);
+%$ t(3) = dassert(i3,false);
+%$ t(4) = dassert(i4,false);
+%$ t(5) = dassert(i5,true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1945Q1';
+%$ B2 = '1945Q2';
+%$ B3 = '1945Q3';
+%$ B4 = '1945Q4';
+%$ B5 = '1950Q1';
+%$
+%$ % Create dates objects.
+%$ dd = dates(B1,B2,B3,B4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(dates(B1)>=dates(B2),false);
+%$ t(2) = dassert(dates(B2)>=dates(B1),true);
+%$ t(3) = dassert(dates(B2)>=dates(B2),true);
+%$ t(4) = dassert(dd>=dates(B5),false(4,1));
+%$ t(5) = dassert(dates(B5)>=dd,true(4,1));
+%$ t(6) = dassert(dates(B1)>=dd,[true; false(3,1)]);
+%$ T = all(t);
+%@eof:2
diff --git a/src/@dates/gt.m b/src/@dates/gt.m
new file mode 100644
index 0000000000000000000000000000000000000000..727aed0739dddcfe0191cb245d2c1e23d106f74b
--- /dev/null
+++ b/src/@dates/gt.m
@@ -0,0 +1,92 @@
+function l = gt(varargin)  % --*-- Unitary tests --*--
+
+% Overloads the > operator for dates objects.
+%
+% INPUTS
+% - o [dates] dates object with n or 1 elements.
+% - p [dates] dates object with n or 1 elements.
+%
+% OUTPUTS
+% - l [logical] column vector of max(n,1) elements (zeros or ones).
+
+% Copyright (C) 2013-2015 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+[o, p] = comparison_arg_checks(varargin{:});
+
+if isequal(o.ndat(), p.ndat())
+    l = false(o.ndat(),1);
+    for i=1:o.ndat()
+        l(i) = greaterthan(o.time(i,:), p.time(i,:));
+    end
+else
+    if isequal(o.ndat(),1)
+        l = false(p.ndat(),1);
+        for i=1:p.ndat()
+            l(i) = greaterthan(o.time, p.time(i,:));
+        end
+    else
+        l = false(o.ndat(),1);
+        for i=1:o.ndat()
+            l(i) = greaterthan(o.time(i,:), p.time);
+        end
+    end
+end
+
+%@test:1
+%$ % Define some dates
+%$ date_2 = '1950Q2';
+%$ date_3 = '1950Q3';
+%$ date_4 = '1950Q1';
+%$ date_5 = '1949Q2';
+%$
+%$ % Call the tested routine.
+%$ d2 = dates(date_2);
+%$ d3 = dates(date_3);
+%$ d4 = dates(date_4);
+%$ d5 = dates(date_5);
+%$ i1 = (d2>d3);
+%$ i2 = (d3>d4);
+%$ i3 = (d4>d2);
+%$ i4 = (d5>d4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i1,false);
+%$ t(2) = dassert(i2,true);
+%$ t(3) = dassert(i3,false);
+%$ t(4) = dassert(i4,false);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1945Q1';
+%$ B2 = '1945Q2';
+%$ B3 = '1945Q3';
+%$ B4 = '1945Q4';
+%$ B5 = '1950Q1';
+%$
+%$ % Create dates objects.
+%$ dd = dates(B1,B2,B3,B4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(dates(B1)>dates(B2),false);
+%$ t(2) = dassert(dates(B2)>dates(B1),true);
+%$ t(3) = dassert(dates(B5)>dates(B1),true);
+%$ t(4) = dassert(dd>dates(B5),false(4,1));
+%$ t(5) = dassert(dates(B5)>dd,true(4,1));
+%$ t(6) = dassert(dates(B1)>dd,false(4,1));
+%$ T = all(t);
+%@eof:2
diff --git a/src/@dates/horzcat.m b/src/@dates/horzcat.m
new file mode 100644
index 0000000000000000000000000000000000000000..b203853cf66f67ca4c945da2fc5e11cf6b6f232c
--- /dev/null
+++ b/src/@dates/horzcat.m
@@ -0,0 +1,132 @@
+function o = horzcat(varargin) % --*-- Unitary tests --*--
+
+% Overloads the horzcat method for dates objects.
+%
+% INPUTS
+% - varargin [dates]
+%
+% OUTPUTS
+% - o [dates] object containing dates defined in varargin{:}
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~all(cellfun(@isdates,varargin))
+    error('dates:horzcat:ArgCheck','All input arguments must be dates objects.')
+end
+
+o = copy(varargin{1});
+for i=2:nargin
+    p = varargin{i};
+    if isequal(o.freq,p.freq)
+        if ~isempty(p)
+            o.time = [o.time; p.time];
+        end
+    else
+        error('dates:horzcat','All input arguments must have the same frequency!')
+    end
+end
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2,B1);
+%$ d = [d, dates(B5)];
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ t(3) = size(e.time,1)==d.ndat();
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2);
+%$ d = [d, dates(B1), dates(B5)];
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ t(3) = size(e.time,1)==d.ndat();
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2);
+%$ d = [d, dates(B1,B5)];
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ t(3) = size(e.time,1)==d.ndat();
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2);
+%$ d = [d, [dates(B1), dates(B5)]];
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d.time,e.time);
+%$ t(2) = dassert(d.freq,e.freq);
+%$ t(3) = size(e.time,1)==d.ndat();
+%$ T = all(t);
+%@eof:4
diff --git a/src/@dates/intersect.m b/src/@dates/intersect.m
new file mode 100644
index 0000000000000000000000000000000000000000..5cbed03fefd3ab3c67a27c5472824e01ca4d64a5
--- /dev/null
+++ b/src/@dates/intersect.m
@@ -0,0 +1,82 @@
+function q = intersect(o, p) % --*-- Unitary tests --*--
+
+% Overloads intersect function for dates objects.
+%
+% INPUTS
+% - o [dates]
+% - p [dates]
+%
+% OUTPUTS
+% - q [dates] All the common elements in o and p.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~isa(o,'dates') || ~isa(p,'dates')
+    error('dates:intersect:ArgCheck','All input arguments must be dates objects!')
+end
+
+if o.length()==p.length() && isequal(o, p)
+    q = copy(o);
+    return
+end
+
+if ~isequal(o.freq,p.freq)
+    q = dates();
+    return
+end
+
+if isoctave || matlab_ver_less_than('8.1.0')
+    time = intersect(o.time,p.time,'rows');
+else
+    time = intersect(o.time,p.time,'rows','legacy');
+end
+
+q = dates();
+if isempty(time)
+    return
+end
+
+q.freq = o.freq;
+q.time = time;
+
+%@test:1
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1'):dates('1969Q4') ;
+%$ d2 = dates('1960Q1'):dates('1969Q4') ;
+%$ d3 = dates('1970Q1'):dates('1979Q4') ;
+%$
+%$ % Call the tested routine.
+%$ c1 = intersect(d1,d2);
+%$ c2 = intersect(d1,d3);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(c1,d2);
+%$ t(2) = dassert(isempty(c2),true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1'):dates('1969Q4') ;
+%$ d2 = dates('1950Q1'):dates('1969Q4') ;
+%$
+%$ % Call the tested routine.
+%$ c1 = intersect(d1,d2);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(c1,d1);
+%$ T = all(t);
+%@eof:2
diff --git a/src/@dates/isempty.m b/src/@dates/isempty.m
new file mode 100644
index 0000000000000000000000000000000000000000..15e91602e424216c2da0e74eaef9d291199a5ecc
--- /dev/null
+++ b/src/@dates/isempty.m
@@ -0,0 +1,42 @@
+function l = isempty(o) % --*-- Unitary tests --*--
+
+% Returns true (1) if and only if o dates object is empty.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - l [logical]
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+l = isequal(o.ndat(),0);
+
+%@test:1
+%$ % Instantiate an empty dates object
+%$ d = dates();
+%$ % Test if this object is empty
+%$ t(1) = isempty(d);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Instantiate an empty dates object
+%$ d = dates('1938Q4');
+%$ % Test if this object is empty
+%$ t(1) = ~isempty(d);
+%$ T = all(t);
+%@eof:2
diff --git a/src/@dates/isequal.m b/src/@dates/isequal.m
new file mode 100644
index 0000000000000000000000000000000000000000..3922f0356851a7ee3407bccd726e0d80b0b00798
--- /dev/null
+++ b/src/@dates/isequal.m
@@ -0,0 +1,71 @@
+function l = isequal(o, p, fake) % --*-- Unitary tests --*--
+
+% Overloads isequal function for dates objects. Returns true (1) iff o and p have the same elements.
+%
+% INPUTS
+% - o [dates]
+% - p [dates]
+%
+% OUTPUTS
+% - l [logical]
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~isa(o,'dates') || ~isa(p,'dates')
+    error('dates:isequal:ArgCheck','Both inputs must be dates objects!')
+end
+
+l = isequal(o.freq, p.freq) && isequal(o.time, p.time);
+
+%@test:1
+%$ d1 = dates('1938Q1');
+%$ d2 = dates('1938Q1');
+%$ % Test if this object is empty
+%$ t(1) = isequal(d1,d2);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ d1 = dates('1938Q1');
+%$ d2 = dates('1938Q2');
+%$ % Test if this object is empty
+%$ t(1) = ~isequal(d1,d2);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ d1 = dates('1938Q4');
+%$ d2 = dates('1938M11');
+%$ % Test if this object is empty
+%$ t(1) = ~isequal(d1,d2);
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ d1 = dates('1938Q4','1938Q3');
+%$ d2 = dates('1938Q3','1938Q1');
+%$ % Test if this object is empty
+%$ t(1) = ~isequal(d1,d2);
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ d1 = dates('1938Q4','1938Q3','1938Q2');
+%$ d2 = dates('1938Q3','1938Q1');
+%$ % Test if this object is empty
+%$ t(1) = ~isequal(d1,d2);
+%$ T = all(t);
+%@eof:5
diff --git a/src/@dates/le.m b/src/@dates/le.m
new file mode 100644
index 0000000000000000000000000000000000000000..5c36a1cba6251ec3dba33e3c25d230759deec6eb
--- /dev/null
+++ b/src/@dates/le.m
@@ -0,0 +1,95 @@
+function l = le(varargin)  % --*-- Unitary tests --*--
+
+% Overloads the <= operator for dates objects.
+%
+% INPUTS
+% - o [dates] dates object with n or 1 elements.
+% - p [dates] dates object with n or 1 elements.
+%
+% OUTPUTS
+% - l [logical] column vector of max(n,1) elements (zeros or ones).
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+[o, p] = comparison_arg_checks(varargin{:});
+
+if isequal(o.ndat(), p.ndat())
+    l = (o==p);
+    idx = find(l==0);
+    for i=1:length(idx)
+        l(idx(i)) = lessorequal(o.time(idx(i),:), p.time(idx(i),:));
+    end
+else
+    if isequal(o.ndat(),1)
+        l = false(p.ndat(),1);
+        for i=1:p.ndat()
+            l(i) = lessorequal(o.time, p.time(i,:));
+        end
+    else
+        l = false(o.ndat(),1);
+        for i=1:o.ndat()
+            l(i) = lessorequal(o.time(i,:), p.time);
+        end
+    end
+end
+
+%@test:1
+%$ % Define some dates
+%$ date_2 = '1950Q2';
+%$ date_3 = '1950Q3';
+%$ date_4 = '1950Q1';
+%$ date_5 = '1949Q2';
+%$
+%$ % Call the tested routine.
+%$ d2 = dates(date_2);
+%$ d3 = dates(date_3);
+%$ d4 = dates(date_4);
+%$ d5 = dates(date_5);
+%$ i1 = (d2<=d3);
+%$ i2 = (d3<=d4);
+%$ i3 = (d4<=d2);
+%$ i4 = (d5<=d4);
+%$ i5 = (d5<=d5);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i1,true);
+%$ t(2) = dassert(i2,false);
+%$ t(3) = dassert(i3,true);
+%$ t(4) = dassert(i4,true);
+%$ t(5) = dassert(i5,true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1945Q1';
+%$ B2 = '1945Q2';
+%$ B3 = '1945Q3';
+%$ B4 = '1945Q4';
+%$ B5 = '1950Q1';
+%$
+%$ % Create dates objects.
+%$ dd = dates(B1,B2,B3,B4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(dates(B1)<=dates(B2),true);
+%$ t(2) = dassert(dates(B2)<=dates(B1),false);
+%$ t(3) = dassert(dates(B2)<=dates(B2),true);
+%$ t(4) = dassert(dd<=dates(B5),true(4,1));
+%$ t(5) = dassert(dates(B5)<=dd,false(4,1));
+%$ t(6) = dassert(dates(B1)<=dd,true(4,1));
+%$ T = all(t);
+%@eof:2
diff --git a/src/@dates/length.m b/src/@dates/length.m
new file mode 100644
index 0000000000000000000000000000000000000000..a58f367cda82e7e44f2b68b615a074f41199630b
--- /dev/null
+++ b/src/@dates/length.m
@@ -0,0 +1,47 @@
+function n = length(o) % --*-- Unitary tests --*--
+
+% Returns the number of elements in a dates object.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - n [integer] Number of elements in o.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+n = o.ndat();
+
+%@test:1
+%$ d = dates('1938Q1');
+%$ % Test if this object is empty
+%$ t(1) = isequal(d.length(),1);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ d = dates();
+%$ % Test if this object is empty
+%$ t(1) = isequal(d.length(),0);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ d = dates('1938Q1')+dates('1938Q2')+dates('1938Q3');
+%$ % Test if this object is empty
+%$ t(1) = isequal(d.length(),3);
+%$ T = all(t);
+%@eof:3
diff --git a/src/@dates/lt.m b/src/@dates/lt.m
new file mode 100644
index 0000000000000000000000000000000000000000..826b3afcb1b9927a63d2cfcf500ffa7b19d1901d
--- /dev/null
+++ b/src/@dates/lt.m
@@ -0,0 +1,92 @@
+function l = lt(varargin)  % --*-- Unitary tests --*--
+
+% Overloads the < operator for dates objects.
+%
+% INPUTS
+% - o [dates] dates object with n or 1 elements.
+% - p [dates] dates object with n or 1 elements.
+%
+% OUTPUTS
+% - l [logical] column vector of max(n,1) elements (zeros or ones).
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+[o, p] = comparison_arg_checks(varargin{:});
+
+if isequal(o.ndat(), p.ndat())
+    l = false(o.ndat(),1);
+    for i=1:o.ndat()
+        l(i) = lessthan(o.time(i,:),p.time(i,:));
+    end
+else
+    if isequal(o.ndat(),1)
+        l = false(p.ndat(),1);
+        for i=1:p.ndat()
+            l(i) = lessthan(o.time,p.time(i,:));
+        end
+    else
+        l = false(o.ndat(),1);
+        for i=1:o.ndat()
+            l(i) =  lessthan(o.time(i,:),p.time);
+        end
+    end
+end
+
+%@test:1
+%$ % Define some dates
+%$ date_2 = '1950Q2';
+%$ date_3 = '1950Q3';
+%$ date_4 = '1950Q1';
+%$ date_5 = '1949Q2';
+%$
+%$ % Call the tested routine.
+%$ d2 = dates(date_2);
+%$ d3 = dates(date_3);
+%$ d4 = dates(date_4);
+%$ d5 = dates(date_5);
+%$ i1 = (d2<d3);
+%$ i2 = (d3<d4);
+%$ i3 = (d4<d2);
+%$ i4 = (d5<d4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i1,true);
+%$ t(2) = dassert(i2,false);
+%$ t(3) = dassert(i3,true);
+%$ t(4) = dassert(i4,true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1945Q1';
+%$ B2 = '1945Q2';
+%$ B3 = '1945Q3';
+%$ B4 = '1945Q4';
+%$ B5 = '1950Q1';
+%$
+%$ % Create dates objects.
+%$ dd = dates(B1,B2,B3,B4);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(dates(B1)<dates(B2),true);
+%$ t(2) = dassert(dates(B2)<dates(B1),false);
+%$ t(3) = dassert(dates(B2)<dates(B1),false);
+%$ t(4) = dassert(dd<dates(B5),true(4,1));
+%$ t(5) = dassert(dates(B5)<dd,false(4,1));
+%$ t(6) = dassert(dates(B1)<dd,[false; true(3,1)]);
+%$ T = all(t);
+%@eof:2
diff --git a/src/@dates/max.m b/src/@dates/max.m
new file mode 100644
index 0000000000000000000000000000000000000000..10bdec6c3a881f8ff5e46c7c6faa0340d80afc4a
--- /dev/null
+++ b/src/@dates/max.m
@@ -0,0 +1,86 @@
+function q = max(varargin)  % --*-- Unitary tests --*--
+
+% Overloads the max function for dates objects.
+%
+% INPUTS
+% - varargin [dates]
+%
+% OUTPUTS
+% - q [dates]
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~all(cellfun(@isdates,varargin))
+    error('dates:max:ArgCheck','All input arguments must be dates objects.')
+end
+
+switch nargin
+  case 1
+    sorted_time_member = sortrows(varargin{1}.time);
+    q = dates();
+    q.freq = varargin{1}.freq;
+    q.time = sorted_time_member(varargin{1}.ndat(),:);
+  otherwise
+    q = max(horzcat(varargin{:}));
+end
+
+%@test:1
+%$ % Define some dates
+%$ d3 = dates('1950q2');
+%$ d4 = dates('1950Q3');
+%$ d5 = dates('1950m1');
+%$ d6 = dates('1948M6');
+%$ m2 = max(d3,d4);
+%$ i2 = (m2==d4);
+%$ m3 = max(d5,d6);
+%$ i3 = (m3==d5);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i2,true);
+%$ t(2) = dassert(i3,true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ d = dates('1950Q2','1951Q3','1949Q1','1950Q4');
+%$ m = max(d);
+%$ i = (m==dates('1951Q3'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i,true);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ m = max(dates('1950Q2','1951Q3'),dates('1949Q1'),dates('1950Q4'));
+%$ i = (m==dates('1951Q3'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i,true);
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates
+%$ m = max(dates('1950Q2'),dates('1951Q3'),dates('1949Q1'),dates('1950Q4'));
+%$ i = (m==dates('1951Q3'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i,true);
+%$ T = all(t);
+%@eof:4
diff --git a/src/@dates/min.m b/src/@dates/min.m
new file mode 100644
index 0000000000000000000000000000000000000000..0535179c6c035ccda497e1639b849e41c2a63427
--- /dev/null
+++ b/src/@dates/min.m
@@ -0,0 +1,86 @@
+function q = min(varargin) % --*-- Unitary tests --*--
+
+% Overloads the min function for dates objects.
+%
+% INPUTS
+% - varargin [dates]
+%
+% OUTPUTS
+% - q [dates]
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~all(cellfun(@isdates,varargin))
+    error('dates:min:ArgCheck','All input arguments must be dates objects.')
+end
+
+switch nargin
+  case 1
+    sorted_time_member = sortrows(varargin{1}.time);
+    q = dates();
+    q.freq = varargin{1}.freq;
+    q.time = sorted_time_member(1,:);
+  otherwise
+    q = min(horzcat(varargin{:}));
+end
+
+%@test:1
+%$ % Define some dates
+%$ d3 = dates('1950q2');
+%$ d4 = dates('1950Q3');
+%$ d5 = dates('1950m1');
+%$ d6 = dates('1948M6');
+%$ m2 = min(d3,d4);
+%$ i2 = (m2==d3);
+%$ m3 = min(d5,d6);
+%$ i3 = (m3==d6);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i2,true);
+%$ t(2) = dassert(i3,true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ d = dates('1950Q2','1951Q3','1949Q1','1950Q4');
+%$ m = min(d);
+%$ i = (m==dates('1949Q1'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i,true);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ m = min(dates('1950Q2','1951Q3'),dates('1949Q1'),dates('1950Q4'));
+%$ i = (m==dates('1949Q1'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i,true);
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates
+%$ m = min(dates('1950Q2'),dates('1951Q3'),dates('1949Q1'),dates('1950Q4'));
+%$ i = (m==dates('1949Q1'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i,true);
+%$ T = all(t);
+%@eof:4
diff --git a/src/@dates/minus.m b/src/@dates/minus.m
new file mode 100644
index 0000000000000000000000000000000000000000..20f21a45a23a8e6a72723b454324aade125a9ab5
--- /dev/null
+++ b/src/@dates/minus.m
@@ -0,0 +1,169 @@
+function q = minus(o,p) % --*-- Unitary tests --*--
+
+% Overloads the minus operator (-). If o and p are dates objects, the method . If
+% one of the inputs is an integer or a vector of integers, the method shifts the dates object by X (the interger input) periods backward.
+
+% Overloads the minus (-) binary operator.
+%
+% INPUTS
+% - o [dates]
+% - p [dates or integer]
+%
+% OUTPUTS
+% - q [dates]
+%
+% REMARKS
+% 1. If o and p are dates objects the method returns the number of periods between o and p (so that q+o=p).
+% 2. If o is a dates object and p is an integer (scalar or vector), the method shifts the dates object by
+%    p periods backward.
+% 3. If o is not a dates object, an error is returned.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if isa(o,'dates') && isa(p,'dates')
+    if ~isequal(o.freq, p.freq)
+        error('dates:minus:ArgCheck','Input arguments must have common frequencies!')
+    end
+    if isempty(o) || isempty(p)
+        error('dates:minus:ArgCheck','Input arguments must not be empty!')
+    end
+    u = copy(o);
+    v = copy(p);
+    if ~isequal(u.length(),v.length())
+        if isequal(u.length(),1)
+            u.time = repmat(u.time,v.ndat(),1);
+        elseif isequal(v.length(),1)
+            v.time = repmat(v.time,u.ndat(),1);
+        else
+            error('dates:minus:ArgCheck','Input arguments lengths are not consistent!')
+        end
+    end
+    q = zeros(u.length(),1);
+    id = find(~(u==v));
+    if ~isempty(id)
+        q(id) = u.time(id,2)-v.time(id,2) + (u.time(id,1)-v.time(id,1))*v.freq;
+    end
+elseif isa(o,'dates') && ~isa(p,'dates')
+    if (isvector(p) && isequal(length(p),o.ndat()) && all(isint(p))) || (isscalar(p) && isint(p)) || (isequal(o.length(),1) && isvector(p) && all(isint(p)))
+        q = dates();
+        q.freq = o.freq;
+        q.time = add_periods_to_array_of_dates(o.time, o.freq, -p(:));
+    else
+        error('dates:minus:ArgCheck','Second argument has to be a vector of integers or scalar integer. You should read the manual.')
+    end
+else
+    error('dates:minus:ArgCheck','You should read the manual.')
+end
+
+%@test:1
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1','1950Q2','1960Q1');
+%$ d2 = dates('1950Q3','1950Q4','1960Q1');
+%$ d3 = dates('2000Q1');
+%$ d4 = dates('2002Q2');
+%$ % Call the tested routine.
+%$ try
+%$   e1 = d2-d1;
+%$   e2 = d4-d3;
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,[2; 2; 0]);
+%$   t(3) = dassert(e2,9);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d1 = dates('1950Y','1951Y','1953Y');
+%$ d2 = dates('1951Y','1952Y','1953Y');
+%$ d3 = dates('2000Y');
+%$ d4 = dates('1999Y');
+%$ % Call the tested routine.
+%$ try
+%$   e1 = d2-d1;
+%$   e2 = d4-d3;
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,[1; 1; 0]);
+%$   t(3) = dassert(e2,-1);
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates objects
+%$ d1 = dates('2000Y');
+%$ d2 = dates('1999Y');
+%$ % Call the tested routine.
+%$ try
+%$   e1 = d1-1;
+%$   e2 = d2-(-1);
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,d2);
+%$   t(3) = dassert(e2,d1);
+%$ end
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates objects
+%$ d1 = dates('2000Q1');
+%$ e1 = dates('1999Q4','1999Q3','1999Q2','1999Q1','1998Q4');
+%$ % Call the tested routine.
+%$ try
+%$   f1 = d1-transpose(1:5);
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,f1);
+%$ end
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define some dates objects
+%$ d1 = dates('1999Q4','1999Q3','1999Q2','1999Q1','1998Q4');
+%$ e1 = dates('2000Q1')*5;
+%$ % Call the tested routine.
+%$ try
+%$   f1 = d1-(-transpose(1:5));
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,f1);
+%$ end
+%$ T = all(t);
+%@eof:5
diff --git a/src/@dates/mtimes.m b/src/@dates/mtimes.m
new file mode 100644
index 0000000000000000000000000000000000000000..c824fef179923006d0bad6fe19348b70d2ccf1f5
--- /dev/null
+++ b/src/@dates/mtimes.m
@@ -0,0 +1,47 @@
+function p = mtimes(o,n) % --*-- Unitary tests --*--
+
+% Overloads the times operator (*). Returns dates object o replicated n times.
+%
+% INPUTS
+% - o [dates] object with m elements.
+%
+% OUTPUTS
+% - p [dates] object with m*n elements.
+%
+% EXAMPLES
+% 1. If A = dates('2000Q1'), then B=A*3 is a dates object equal to dates('2000Q1','2000Q1','2000Q1')
+% 2. If A = dates('2003Q1','2009Q2'), then B=A*2 is a dates object equal to dates('2003Q1','2009Q2','2003Q1','2009Q2')
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~(isscalar(n) && isint(n))
+    error('dates:mtimes:ArgCheck','First and second input arguments have to be a dates object and a scalar integer!')
+end
+
+p = copy(o);
+p.time = repmat(p.time, n, 1);
+
+%@test:1
+%$ % Define some dates
+%$ d = dates('1950q2','1950q3');
+%$ e = dates('1950q2','1950q3')+dates('1950q2','1950q3');
+%$ f = d*2;
+%$ i = isequal(e, f);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i,true);
+%$ T = all(t);
+%@eof:1
diff --git a/src/@dates/ndat.m b/src/@dates/ndat.m
new file mode 100644
index 0000000000000000000000000000000000000000..e29310fb1e449b8b9becfbed4d8015fac129d56c
--- /dev/null
+++ b/src/@dates/ndat.m
@@ -0,0 +1,98 @@
+function s = ndat(o) % --*-- Unitary tests --*--
+
+% Given a one element dates object, returns a string with the formatted date.
+%
+% INPUTS
+% - o  [dates]
+%
+% OUTPUTS
+% - s  [integer]
+
+% Copyright (C) 2015-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+s = size(o.time, 1);
+
+%@test:1
+%$ % Define a dates object
+%$ o = dates('1950Q1'):dates('1952Q1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     card = ndat(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(card,9);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define a dates object
+%$ o = dates('1950M1'):dates('1951M6');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     card = ndat(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(card,18);
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define a dates object
+%$ o = dates('1950W1'):dates('1950W16');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     card = ndat(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(card,16);
+%$ end
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define a dates object
+%$ o = dates('1950Y'):dates('1959Y');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     card = ndat(o);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(card,10);
+%$ end
+%$ T = all(t);
+%@eof:4
diff --git a/src/@dates/ne.m b/src/@dates/ne.m
new file mode 100644
index 0000000000000000000000000000000000000000..351166ec473cc77e676cd67842a69802fc409b3e
--- /dev/null
+++ b/src/@dates/ne.m
@@ -0,0 +1,85 @@
+function l = ne(varargin) % --*-- Unitary tests --*--
+
+% Overloads ~= operator for dates objects.
+%
+% INPUTS
+% - o [dates] dates object with n or 1 elements.
+% - p [dates] dates object with n or 1 elements.
+%
+% OUTPUTS
+% - l [logical] column vector of max(n,1) elements (zeros or ones).
+
+% Copyright (C) 2013-2015 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+[o, p] = comparison_arg_checks(varargin{:});
+
+if isequal(o.ndat(), p.ndat())
+    l = logical(transpose(any(transpose(ne(o.time,p.time)))));
+else
+    l = logical(transpose(any(transpose(bsxfun(@ne,o.time,p.time)))));
+end
+
+%@test:1
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1','1950Q2','1950Q3','1950Q4') ;
+%$ d2 = dates('1960Q1','1960Q2','1960Q3','1960Q4') ;
+%$ d3 = dates('1950Q1','1960Q2','1950Q3','1960Q4') ;
+%$
+%$ % Call the tested routine.
+%$ t1 = d1~=d1;
+%$ t2 = d1~=d2;
+%$ t3 = d1~=d3;
+%$
+%$ % Check the results.
+%$ t(1) = dassert(t1,false(4,1));
+%$ t(2) = dassert(t2,true(4,1));
+%$ t(3) = dassert(t3,[false; true; false; true]);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1') ;
+%$ d2 = dates('1960Q1') ;
+%$ d3 = dates('1960Q1') ;
+%$
+%$ % Call the tested routine.
+%$ t1 = d1~=d1;
+%$ t2 = d1~=d2;
+%$ t3 = d1~=d3;
+%$
+%$ % Check the results.
+%$ t(1) = dassert(t1,false);
+%$ t(2) = dassert(t2,true);
+%$ t(3) = dassert(t3,true);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1','1950Q2','1950Q3','1950Q4') ;
+%$ d2 = dates('1950Q2') ;
+%$ d3 = dates('1970Q1') ;
+%$
+%$ % Call the tested routine.
+%$ t1 = d1~=d2;
+%$ t2 = d1~=d3;
+%$
+%$ % Check the results.
+%$ t(1) = dassert(t1,[true; false; true; true]);
+%$ t(2) = dassert(t2,true(4,1));
+%$ T = all(t);
+%@eof:3
diff --git a/src/@dates/plus.m b/src/@dates/plus.m
new file mode 100644
index 0000000000000000000000000000000000000000..281045af30a679102ad8fa39043007befe2997e0
--- /dev/null
+++ b/src/@dates/plus.m
@@ -0,0 +1,150 @@
+function q = plus(o,p) % --*-- Unitary tests --*--
+
+% Overloads the plus (+) binary operator.
+%
+% INPUTS
+% - o [dates or integer]
+% - p [dates or integer]
+%
+% OUTPUTS
+% - q [dates]
+%
+% REMARKS
+% 1. If o and p are dates objects the method combines o and p without removing repetitions.
+% 2. If  one of the inputs is an integer or a vector of integers, the method shifts the dates
+%    object by X (the interger input) periods forward.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if isa(o,'dates') && isa(p,'dates')
+    % Concatenate dates objects without removing repetitions if o and p are not disjoint sets of dates.
+    if ~isequal(o.freq,p.freq)
+        error('dates:plus:ArgCheck','Input arguments must have common frequency!')
+    end
+    if isempty(p)
+        q = copy(o);
+        return
+    end
+    if isempty(o)
+        q = copy(p);
+        return
+    end
+    q = dates();
+    q.freq = o.freq;
+    q.time = [o.time; p.time];
+elseif isa(o,'dates') || isa(p,'dates')
+    if isa(o,'dates') && ((isvector(p) && isequal(length(p),o.ndat()) && all(isint(p))) || ...
+                          (isequal(o.length(),1) && isvector(p) && all(isint(p))) || ...
+                          (isscalar(p) && isint(p)))
+        q = dates();
+        q.freq = o.freq;
+        q.time = add_periods_to_array_of_dates(o.time, q.freq, p(:));
+    elseif isa(p,'dates') && ((isvector(o) && isequal(length(o),p.ndat()) && all(isint(o))) || ...
+                              (isequal(p.length(),1) && isvector(o) && all(isint(o))) || ...
+                              (isscalar(o) && isint(o)) )
+        q = dates();
+        q.freq = p.freq;
+        q.time = add_periods_to_array_of_dates(p.time, q.freq, o(:));
+    else
+        error('dates:plus:ArgCheck','Please read the manual.')
+    end
+else
+    error('dates:plus:ArgCheck','Please read the manual.')
+end
+
+%@test:1
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1','1950Q2') ;
+%$ d2 = dates('1950Q3','1950Q4') ;
+%$ d3 = dates('1950Q1','1950Q2','1950Q3','1950Q4') ;
+%$
+%$ % Call the tested routine.
+%$ try
+%$   e1 = d1+d2;
+%$   e2 = d1+d2+d3;
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,d3);
+%$   t(3) = dassert(e2,dates('1950Q1','1950Q2','1950Q3','1950Q4','1950Q1','1950Q2','1950Q3','1950Q4'));
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1');
+%$ e1 = dates('1950Q2');
+%$ e2 = dates('1950Q3');
+%$ e3 = dates('1950Q4');
+%$ e4 = dates('1951Q1');
+%$ e5 = dates('1950Q2','1950Q3','1950Q4','1951Q1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$   f1 = d1+1;
+%$   f2 = d1+2;
+%$   f3 = d1+3;
+%$   f4 = d1+4;
+%$   f5 = d1+transpose(1:4);
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,f1);
+%$   t(3) = dassert(e2,f2);
+%$   t(4) = dassert(e3,f3);
+%$   t(5) = dassert(e4,f4);
+%$   t(6) = dassert(e5,f5);
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1');
+%$ e1 = dates('1949Q4');
+%$ e2 = dates('1949Q3');
+%$ e3 = dates('1949Q2');
+%$ e4 = dates('1949Q1');
+%$ e5 = dates('1948Q4');
+%$
+%$ % Call the tested routine.
+%$ try
+%$   f1 = d1+(-1);
+%$   f2 = d1+(-2);
+%$   f3 = d1+(-3);
+%$   f4 = d1+(-4);
+%$   f5 = d1+(-5);
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(e1,f1);
+%$   t(3) = dassert(e2,f2);
+%$   t(4) = dassert(e3,f3);
+%$   t(5) = dassert(e4,f4);
+%$   t(6) = dassert(e5,f5);
+%$ end
+%$ T = all(t);
+%@eof:3
diff --git a/src/@dates/pop.m b/src/@dates/pop.m
new file mode 100644
index 0000000000000000000000000000000000000000..47ce424297e3266d8b9d9a13fe2b3df7ef51035c
--- /dev/null
+++ b/src/@dates/pop.m
@@ -0,0 +1,163 @@
+function o = pop(o, p) % --*-- Unitary tests --*--
+
+% pop method for dates class (removes a date).
+%
+% INPUTS
+% - o [dates]
+% - p [dates] object with one element, string which can be interpreted as a date or integer scalar.
+%
+% OUTPUTS
+% - o [dates]
+%
+% REMARKS
+% 1. If a is a date appearing more than once in o, then only the last occurence is removed. If one wants to
+%    remove all the occurences of p in o, the remove method should be used instead.
+%
+% See also remove, setdiff.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+o = copy(o);
+
+if nargin>1
+    o.pop_(p);
+else
+    o.pop_();
+end
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$ d = dates(B4,B3,B2,B1,B5);
+%$
+%$ % Define expected results
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine
+%$ try
+%$     c = d.pop();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(c.time,e.time(1:end-1,:));
+%$     t(3) = dassert(c.freq,e.freq);
+%$     t(4) = dassert(d.time,e.time);
+%$     t(5) = dassert(d.freq,e.freq);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$ d = dates(B4,B3,B2,B1,B5);
+%$
+%$ % Define expected results
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine
+%$ try
+%$     c = d.pop(B5);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(c.time,e.time(1:end-1,:));
+%$     t(3) = dassert(c.freq,e.freq);
+%$     t(4) = dassert(d.time,e.time);
+%$     t(5) = dassert(d.freq,e.freq);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$ d = dates(B4,B3,B2,B1,B5);
+%$
+%$ % Define expected results
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine
+%$ try
+%$     c = d.pop(dates(B5));
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(c.time,e.time(1:end-1,:));
+%$     t(3) = dassert(c.freq,e.freq);
+%$     t(4) = dassert(d.time,e.time);
+%$     t(5) = dassert(d.freq,e.freq);
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$ d = dates(B4,B3,B2,B1,B5);
+%$
+%$ % Define expected results
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine
+%$ try
+%$     c = d.pop(3);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(c.time,e.time([1 2 4 5],:));
+%$     t(3) = dassert(c.freq,e.freq);
+%$     t(4) = dassert(d.time,e.time);
+%$     t(5) = dassert(d.freq,e.freq);
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
\ No newline at end of file
diff --git a/src/@dates/pop_.m b/src/@dates/pop_.m
new file mode 100644
index 0000000000000000000000000000000000000000..67c4b838a17328c6375953e21b834697d888749c
--- /dev/null
+++ b/src/@dates/pop_.m
@@ -0,0 +1,240 @@
+function o = pop_(o, p) % --*-- Unitary tests --*--
+
+% pop method for dates class (in place modification).
+%
+% INPUTS
+% - o [dates]
+% - p [dates] object with one element, string which can be interpreted as a date or integer scalar.
+%
+% OUTPUTS
+% - o [dates]
+%
+% REMARKS
+% 1. If a is a date appearing more than once in o, then only the last occurence is removed. If one wants to
+%    remove all the occurences of p in o, the remove method should be used instead.
+%
+% See also remove, setdiff.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if o.isempty()
+    return
+end
+
+if nargin<2
+    % Remove last date
+    o.time = o.time(1:end-1,:);
+    return
+end
+
+if ~( isdates(p) || isdate(p) || (isscalar(p) && isint(p)) )
+    error('dates:pop','Input argument %s has to be a dates object with a single element, a string (which can be interpreted as a date) or an integer!',inputname(2))
+end
+
+if ischar(p)
+    p = dates(p);
+end
+
+if isnumeric(p)
+    idx = find(transpose(1:o.ndat())~=p);
+    o.time = o.time(idx,:);
+else
+    if ~isequal(o.freq,p.freq)
+        error('dates:pop','Inputs must have common frequency!')
+    end
+    if p.length()>1
+        error('dates:pop','dates to be removed must have one element!')
+    end
+    if isempty(p)
+        return
+    end
+    idx = find(o==p);
+    jdx = find(transpose(1:o.ndat())~=idx(end));
+    o.time = o.time(jdx,:);
+end
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine
+%$ d = dates(B4,B3,B2,B1);
+%$ d.append_(dates(B5));
+%$ try
+%$     d.pop_();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time(1:end-1,:));
+%$     t(3) = dassert(d.freq,e.freq);
+%$     t(4) = dassert(size(e.time,1)-1,d.ndat());
+%$     f = copy(d);
+%$     try
+%$         d.pop_(B1);
+%$         t(5) = true;
+%$     catch
+%$         t(5) = false;
+%$     end
+%$     if t(5)
+%$         t(6) = dassert(d.time,[1945 3; 1950 1; 1950 2]);
+%$         t(7) = dassert(d.freq,e.freq);
+%$         t(8) = dassert(size(e.time,1)-2, d.ndat());
+%$         try
+%$             f.pop_(dates(B1));
+%$             t(9) = true;
+%$         catch
+%$             t(9) = false;
+%$         end
+%$        if t(9)
+%$            t(10) = dassert(f.time,[1945 3; 1950 1; 1950 2]);
+%$            t(11) = dassert(f.freq,e.freq);
+%$            t(12) = dassert(size(e.time,1)-2, f.ndat());
+%$        end
+%$     end
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1950Q1';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Call the tested routine
+%$ d = dates(B1,B2,B3,B4);
+%$ d.append_(dates(B5));
+%$ try
+%$     d.pop_();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d,dates(B1,B2,B3,B4));
+%$     try
+%$         d.pop_(B1);
+%$         t(3) = true;
+%$     catch
+%$         t(3) = false;
+%$     end
+%$     if t(3)
+%$         t(4) = dassert(d,dates(B1,B2,B4));
+%$         try
+%$             d.pop_(1);
+%$             t(5) = true;
+%$         catch
+%$             t(5) = false;
+%$         end
+%$         if t(5)
+%$             t(6) =  dassert(d,dates(B2,B4));
+%$         end
+%$     end
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ B1 = '1950Q1';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q3';
+%$ d = dates(B1,B2,B3);
+%$
+%$ % Call the tested routine
+%$ try
+%$     d.pop_();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d,dates(B1,B2));
+%$     try
+%$         d.pop_(B1);
+%$         t(3) = true;
+%$     catch
+%$         t(3) = false;
+%$     end
+%$     if t(3)
+%$         t(4) = dassert(d,dates(B2));
+%$         try
+%$             d.pop_(1);
+%$             t(5) = true;
+%$         catch
+%$             t(5) = false;
+%$         end
+%$         if t(5)
+%$             t(6) = isempty(d);
+%$         end
+%$     end
+%$ end
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates
+%$ B = '1950Q1';
+%$ d = dates();
+%$
+%$ % Call the tested routine
+%$ try
+%$     d.pop_(B);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = isempty(d);
+%$ end
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define some dates
+%$ d = dates();
+%$
+%$ % Call the tested routine
+%$ try
+%$     d.pop_();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = isempty(d);
+%$ end
+%$ T = all(t);
+%@eof:5
diff --git a/src/@dates/private/comparison_arg_checks.m b/src/@dates/private/comparison_arg_checks.m
new file mode 100644
index 0000000000000000000000000000000000000000..a439bd1d0a45b5959f837039f0b1ce8f51452a54
--- /dev/null
+++ b/src/@dates/private/comparison_arg_checks.m
@@ -0,0 +1,167 @@
+function [o, p] = comparison_arg_checks(varargin) % --*-- Unitary tests --*--
+
+% Returns two dates objects or an error if objects to be compared are not compatible.
+%
+% INPUTS
+% - varargin
+%
+% OUTPUTS
+% - o [dates] dates object with n or 1 elements.
+% - p [dates] dates object with n or 1 elements.
+
+% Copyright (C) 2014-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~isequal(nargin,2)
+    s = dbstack;
+    error(sprintf('dates:%s:ArgCheck',s(2).name),'I need exactly two input arguments!')
+end
+
+if ~isa(varargin{1},'dates') || ~isa(varargin{2},'dates')
+    s = dbstack;
+    error(sprintf('dates:%s:ArgCheck',s(2).name),'Input arguments have to be dates objects!')
+end
+
+if ~isequal(varargin{1}.freq,varargin{2}.freq)
+    s = dbstack;
+    error(sprintf('dates:%s:ArgCheck',s(2).name),'Input arguments must have common frequency!')
+end
+
+if ~isequal(varargin{1}.ndat, varargin{2}.ndat) && ~(isequal(varargin{1}.ndat,1) || isequal(varargin{2}.ndat,1))
+    s = dbstack;
+    if ~isequal(s(2).name, 'eq')
+        error(sprintf('dates:%s:ArgCheck',s(2).name),'Dimensions are not consistent!')
+    end
+end
+
+o = varargin{1};
+p = varargin{2};
+
+%@test:1
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ try
+%$     [o, p] = comparison_arg_checks(1);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:1
+
+%@test:2
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ try
+%$     [o, p] = comparison_arg_checks('make', 'my', 'day');
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:2
+
+%@test:3
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ try
+%$     [o, p] = comparison_arg_checks('punk', dates('1950Q1'));
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:3
+
+%@test:4
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ try
+%$     [o, p] = comparison_arg_checks(dates('1950Q1'), 1);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:4
+
+%@test:5
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ try
+%$     [o, p] = comparison_arg_checks(dates('1950Q1'), dates('1950M1'));
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:5
+
+%@test:6
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ try
+%$     [o, p] = comparison_arg_checks(dates('1950Q1'):dates('1950Q2'), dates('1950Q1'):dates('1950Q3'));
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:6
+
+%@test:7
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ try
+%$     [o, p] = comparison_arg_checks(dates('1950Q2'), dates('1950Q1'));
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(o, dates('1950Q2'));
+%$     t(3) = dassert(p, dates('1950Q1'));
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:7
\ No newline at end of file
diff --git a/src/@dates/private/dates4display.m b/src/@dates/private/dates4display.m
new file mode 100644
index 0000000000000000000000000000000000000000..9630904aaa64926612624375e91c7d16b252eb60
--- /dev/null
+++ b/src/@dates/private/dates4display.m
@@ -0,0 +1,160 @@
+function str = dates4display(o, name, max_number_of_elements) % --*-- Unitary tests --*--
+
+% Converts a list object to a string.
+%
+% INPUTS
+% - o                      [list]     A dates object to be displayed.
+% - name                   [string]   Name of the dates object o.
+% - max_number_of_elements [integer]  Maximum number of elements displayed.
+%
+% OUTPUTS
+% - str  [string] Representation of the dates object as a string.
+
+% Copyright (C) 2014-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if isempty(o)
+    str = sprintf('%s is an empty dates object.\n', name);
+    return
+end
+
+str = sprintf('%s = <dates: ', name);
+
+if o.length()<=max_number_of_elements
+    % All the elements are displayed
+    for i=1:length(o)-1
+        str = sprintf('%s%s, ', str, date2string(o.time(i,:),o.freq));
+    end
+else
+    % Only display four elements (two first and two last)
+    for i=1:2
+        str = sprintf('%s%s, ', str, date2string(o.time(i,:),o.freq));
+    end
+    str = sprintf('%s%s, ', str, '...');
+    str = sprintf('%s%s, ', str, date2string(o.time(o.length()-1,:),o.freq));
+end
+str = sprintf('%s%s>\n', str, date2string(o.time(o.length(),:),o.freq));
+
+%@test:1
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$ addpath('../../../data/')
+%$
+%$ try
+%$     toto = dates();
+%$     str = dates4display(toto, 'toto', 5);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     test_dates4display;
+%$     try
+%$         t(2) = dassert(str, expected_str_1);
+%$     catch
+%$         t(2) = false;
+%$     end
+%$ end
+%$
+%$ T = all(t);
+%$ rmpath('../../../data/')
+%$ cd(OPATH);
+%@eof:1
+
+%@test:2
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$ addpath('../../../data/')
+%$
+%$ try
+%$     toto = dates('1950Q1'):dates('1950Q2');
+%$     str = dates4display(toto, 'toto', 5);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     test_dates4display;
+%$     try
+%$         t(2) = dassert(str, expected_str_2);
+%$     catch
+%$         t(2) = false;
+%$     end
+%$ end
+%$
+%$ T = all(t);
+%$ rmpath('../../../data/')
+%$ cd(OPATH);
+%@eof:2
+
+%@test:3
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$ addpath('../../../data/')
+%$
+%$ try
+%$     toto = dates('1950Q1'):dates('1951Q1');
+%$     str = dates4display(toto, 'toto', 4);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     test_dates4display;
+%$     try
+%$         t(2) = dassert(str, expected_str_3);
+%$     catch
+%$         t(2) = false;
+%$     end
+%$ end
+%$
+%$ T = all(t);
+%$ rmpath('../../../data/')
+%$ cd(OPATH);
+%@eof:3
+
+%@test:4
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$ addpath('../../../data/')
+%$
+%$ try
+%$     toto = dates('1950Q1'):dates('1951Q1');
+%$     str = dates4display(toto, 'toto', 6);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     test_dates4display;
+%$     try
+%$         t(2) = dassert(str, expected_str_4);
+%$     catch
+%$         t(2) = false;
+%$     end
+%$ end
+%$
+%$ T = all(t);
+%$ rmpath('../../../data/')
+%$ cd(OPATH);
+%@eof:4
diff --git a/src/@dates/private/greaterorequal.m b/src/@dates/private/greaterorequal.m
new file mode 100644
index 0000000000000000000000000000000000000000..504414cfbdbb3018d18d955e8b12c8d22a560280
--- /dev/null
+++ b/src/@dates/private/greaterorequal.m
@@ -0,0 +1,145 @@
+function c = greaterorequal(a,b) % --*-- Unitary tests --*--
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if a(1)>b(1)
+    c = true;
+else
+    if a(1)<b(1)
+        c = false;
+    else
+        if a(2)>=b(2)
+            c = true;
+        else
+            c = false;
+        end
+    end
+end
+
+%@test:1
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [2, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = greaterorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:1
+
+%@test:2
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [2, 2];
+%$
+%$ try
+%$     boolean = greaterorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:2
+
+%@test:3
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = greaterorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:3
+
+%@test:4
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 4];
+%$
+%$ try
+%$     boolean = greaterorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:4
+
+%@test:5
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = greaterorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:5
diff --git a/src/@dates/private/greaterthan.m b/src/@dates/private/greaterthan.m
new file mode 100644
index 0000000000000000000000000000000000000000..38b4a3214db98e3ffa981391c151db5150d8f6b6
--- /dev/null
+++ b/src/@dates/private/greaterthan.m
@@ -0,0 +1,145 @@
+function c = greaterthan(a,b) % --*-- Unitary tests --*--
+
+% Copyright (C) 2013-2015 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if a(1)>b(1)
+    c = true;
+else
+    if a(1)<b(1)
+        c = false;
+    else
+        if a(2)>b(2)
+            c = true;
+        else
+            c = false;
+        end
+    end
+end
+
+%@test:1
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [2, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = greaterthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:1
+
+%@test:2
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [2, 2];
+%$
+%$ try
+%$     boolean = greaterthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:2
+
+%@test:3
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = greaterthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:3
+
+%@test:4
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 4];
+%$
+%$ try
+%$     boolean = greaterthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:4
+
+%@test:5
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = greaterthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:5
diff --git a/src/@dates/private/lessorequal.m b/src/@dates/private/lessorequal.m
new file mode 100644
index 0000000000000000000000000000000000000000..ee7149229f7087de08377fb19270bb162db93a8c
--- /dev/null
+++ b/src/@dates/private/lessorequal.m
@@ -0,0 +1,145 @@
+function c = lessorequal(a, b) % --*-- Unitary tests --*--
+
+% Copyright (C) 2013-2015 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if a(1)<b(1)
+    c = true;
+else
+    if a(1)>b(1)
+        c = false;
+    else
+        if a(2)<=b(2)
+            c = true;
+        else
+            c = false;
+        end
+    end
+end
+
+%@test:1
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [2, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = lessorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:1
+
+%@test:2
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [2, 2];
+%$
+%$ try
+%$     boolean = lessorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:2
+
+%@test:3
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = lessorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:3
+
+%@test:4
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 4];
+%$
+%$ try
+%$     boolean = lessorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:4
+
+%@test:5
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = lessorequal(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:5
diff --git a/src/@dates/private/lessthan.m b/src/@dates/private/lessthan.m
new file mode 100644
index 0000000000000000000000000000000000000000..570f1ac6e9aa392ed3b371d29c669278a6e65310
--- /dev/null
+++ b/src/@dates/private/lessthan.m
@@ -0,0 +1,145 @@
+function c = lessthan(a,b) % --*-- Unitary tests --*--
+
+% Copyright (C) 2013-2015 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if a(1)<b(1)
+    c = true;
+else
+    if a(1)>b(1)
+        c = false;
+    else
+        if a(2)<b(2)
+            c = true;
+        else
+            c = false;
+        end
+    end
+end
+
+%@test:1
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [2, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = lessthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:1
+
+%@test:2
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [2, 2];
+%$
+%$ try
+%$     boolean = lessthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:2
+
+%@test:3
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 4];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = lessthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:3
+
+%@test:4
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 4];
+%$
+%$ try
+%$     boolean = lessthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:4
+
+%@test:5
+%$ OPATH = pwd();
+%$ [DATES_PATH, ~, ~] = fileparts(which('initialize_dates_toolbox'));
+%$ cd([DATES_PATH '/@dates/private']);
+%$
+%$ a = [1, 2];
+%$ b = [1, 2];
+%$
+%$ try
+%$     boolean = lessthan(a, b);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%$ cd(OPATH);
+%@eof:5
diff --git a/src/@dates/remove.m b/src/@dates/remove.m
new file mode 100644
index 0000000000000000000000000000000000000000..9d1bb6e0e8a75897b1ae0a5e6795146e8731809d
--- /dev/null
+++ b/src/@dates/remove.m
@@ -0,0 +1,140 @@
+function o = remove(o, p) % --*-- Unitary tests --*--
+
+% remove method for dates class (removes dates).
+%
+% INPUTS
+% - o [dates]
+% - p [dates]
+%
+% OUTPUTS
+% - o [dates]
+%
+% REMARKS
+% 1. If a is a date appearing more than once in o, then all occurences are removed.
+% 2. The removal of p is done by inplace modification of o (in place version of setdiff).
+%
+% See also pop, setdiff
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if nargin<2
+    error('dates:remove','Input argument is missing! You should read the manual')
+end
+
+if ~isdates(p)
+    error('dates:remove','Input argument %s has to be a dates object')
+end
+
+if ~isequal(o.freq,p.freq)
+    error('dates:remove','Inputs must have common frequency!')
+end
+
+o = copy(o);
+o.remove_(p);
+
+%@test:1
+%$ % Define some dates objects
+%$ d = dates('1950Q1'):dates('1952Q4');
+%$ e = dates('1951Q1'):dates('1952Q4');
+%$ f = dates('1950Q1'):dates('1950Q4');
+%$ g = copy(d);
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c = d.remove(e);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(c,f);
+%$     t(3) = dassert(d,g);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = dates('1950Q1');
+%$ f = dates('1950Q2');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c = d.remove(e);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(c,f);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = dates('1950Q1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c = d.remove();
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = '1950Q1';
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c = d.remove(e);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = dates('1950M1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c = d.remove();
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
diff --git a/src/@dates/remove_.m b/src/@dates/remove_.m
new file mode 100644
index 0000000000000000000000000000000000000000..5416231147003604240cf611fb6eb90d530fe078
--- /dev/null
+++ b/src/@dates/remove_.m
@@ -0,0 +1,143 @@
+function o = remove_(o, p) % --*-- Unitary tests --*--
+
+% remove method for dates class (removes dates).
+%
+% INPUTS
+% - o [dates]
+% - p [dates]
+%
+% OUTPUTS
+% - o [dates]
+%
+% REMARKS
+% 1. If a is a date appearing more than once in o, then all occurences are removed.
+% 2. The removal of p is done by inplace modification of o (in place version of setdiff).
+%
+% See also pop, setdiff
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if nargin<2
+    error('dates:remove','Input argument is missing! You should read the manual')
+end
+
+if ~isdates(p)
+    error('dates:remove','Input argument %s has to be a dates object')
+end
+
+if ~isequal(o.freq,p.freq)
+    error('dates:remove','Inputs must have common frequency!')
+end
+
+if isoctave || matlab_ver_less_than('8.1.0')
+    time = setdiff(o.time,p.time,'rows');
+else
+    time = setdiff(o.time,p.time,'rows','legacy');
+end
+
+o.time = time;
+
+%@test:1
+%$ % Define some dates objects
+%$ d = dates('1950Q1'):dates('1952Q4');
+%$ e = dates('1951Q1'):dates('1952Q4');
+%$ f = dates('1950Q1'):dates('1950Q4');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     d.remove_(e);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d,f);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = dates('1950Q1');
+%$ f = dates('1950Q2');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     d.remove_(e);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d,f);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = dates('1950Q1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     d.remove();
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = '1950Q1';
+%$
+%$ % Call the tested routine.
+%$ try
+%$     d.remove(e);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define some dates objects
+%$ d = dates('1950Q1','1950Q2','1950Q1');
+%$ e = dates('1950M1');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     d.remove();
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
\ No newline at end of file
diff --git a/src/@dates/setdiff.m b/src/@dates/setdiff.m
new file mode 100644
index 0000000000000000000000000000000000000000..783cbf9eb9fc8192658112aed8e65e8123819922
--- /dev/null
+++ b/src/@dates/setdiff.m
@@ -0,0 +1,163 @@
+function [q, io] = setdiff(o,p) % --*-- Unitary tests --*--
+
+% Overloads setdiff function for dates objects.
+%
+% INPUTS
+% - o  [dates]
+% - p  [dates]
+%
+% OUTPUTS
+% - q  [dates]   with n elements
+% - io [integer] n*1 vector of integers such that q = o(io)
+%
+% See also pop, remove.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~isa(o,'dates') || ~isa(o,'dates')
+    error('dates;setdiff','All input arguments must be dates objects!')
+end
+
+if ~isequal(o.freq,p.freq)
+    error('dates;setdiff','All input arguments must have common frequency!')
+end
+
+if isempty(p)
+    q = copy(o);
+    if nargout>1, io = 1:length(q); end
+    return
+end
+
+if isequal(o.length(),p.length()) && isequal(o, p)
+    % Return an empty dates object.
+    q = dates(o.freq);
+    if nargout>1, io = []; end
+    return
+end
+
+if isoctave || matlab_ver_less_than('8.1.0')
+    if nargout<2
+        time = setdiff(o.time,p.time,'rows');
+    else
+        [time, io] = setdiff(o.time,p.time,'rows');
+    end
+else
+    if nargout<2
+        time = setdiff(o.time,p.time,'rows','legacy');
+    else
+        [time, io] = setdiff(o.time,p.time,'rows','legacy');
+    end
+end
+
+q = dates(o.freq);
+q.time = time;
+
+%@test:1
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1'):dates('1950Q4') ;
+%$ d2 = dates('1950Q3'):dates('1950Q4') ;
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c1 = setdiff(d1,d2);
+%$     [c2, i] = setdiff(d1,d2);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(c1,c2);
+%$     t(3) = dassert(d1(i),c2);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1'):dates('1950Q4') ;
+%$ d2 = dates('1950M3'):dates('1950M4') ;
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c1 = setdiff(d1,d2);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates objects
+%$ d = dates('1950Q1'):dates('1950Q4') ;
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c1 = setdiff(d,1);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1'):dates('1950Q4') ;
+%$ d2 = dates('1951Q3'):dates('1951Q4') ;
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c1 = setdiff(d1,d2);
+%$     [c2, i] = setdiff(d1,d2);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(isequal(c1,d1),true);
+%$     t(3) = dassert(isequal(c1,d1(i)),true);
+%$ end
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1'):dates('1950Q4') ;
+%$
+%$ % Call the tested routine.
+%$ try
+%$     c1 = setdiff(d1,d1);
+%$     [c2, i] = setdiff(d1,d1);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(isempty(c1),true);
+%$     t(3) = dassert(isempty(c2),true);
+%$     t(4) = dassert(isempty(i),true);
+%$ end
+%$ T = all(t);
+%@eof:5
diff --git a/src/@dates/sort.m b/src/@dates/sort.m
new file mode 100644
index 0000000000000000000000000000000000000000..61b3ae00610896a5ae4f6d0c16d09589d9d6ca0a
--- /dev/null
+++ b/src/@dates/sort.m
@@ -0,0 +1,89 @@
+function o = sort(o) % --*-- Unitary tests --*--
+
+% Sort method for dates class (with copy).
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - o [dates] with dates sorted by increasing order.
+
+% Copyright (C) 2011-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+o = copy(o);
+o.sort_();
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4];
+%$ e.freq = 4;
+%$ f.time = [1953 4; 1950 2; 1950 1; 1945 3];
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4);
+%$ try
+%$     c = d.sort();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,f.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(d.freq,e.freq);
+%$     t(5) = dassert(c.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4];
+%$ e.freq = 4;
+%$ f.time = [1953 4; 1950 2; 1950 1; 1945 3];
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4);
+%$ try
+%$     c = sort(d);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,f.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(d.freq,e.freq);
+%$     t(5) = dassert(c.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/@dates/sort_.m b/src/@dates/sort_.m
new file mode 100644
index 0000000000000000000000000000000000000000..e4ef50ac7dfbf68e5b45c2c66ba871063e51053d
--- /dev/null
+++ b/src/@dates/sort_.m
@@ -0,0 +1,86 @@
+function o = sort_(o) % --*-- Unitary tests --*--
+
+% Sort method for dates class (in place modification).
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - o [dates] with dates sorted by increasing order.
+
+% Copyright (C) 2015-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if isequal(o.ndat(),1)
+    return
+end
+
+o.time = sortrows(o.time,[1,2]);
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4);
+%$ try
+%$     d.sort_();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4);
+%$ try
+%$     c = sort_(d);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/@dates/strings.m b/src/@dates/strings.m
new file mode 100644
index 0000000000000000000000000000000000000000..5557c1429993f908c6c0e9d01aa488f409d9ccee
--- /dev/null
+++ b/src/@dates/strings.m
@@ -0,0 +1,54 @@
+function m = strings(o) % --*-- Unitary tests --*--
+
+% Returns a cell array of strings containing the dates
+%
+% INPUTS
+% - o [dates] object with n elements.
+%
+% OUTPUTS
+% - m [cell of char] object with n elements.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+m = cell(1,o.ndat());
+
+for i = 1:o.length()
+    m(i) = { date2string(o.time(i,:), o.freq) };
+end
+
+%@test:1
+%$ % Define a dates objects
+%$ d = dates('1950Q1'):dates('1950Q3');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     m = strings(d);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = iscell(m);
+%$     t(3) = dassert(m{1}, '1950Q1');
+%$     t(4) = dassert(m{2}, '1950Q2');
+%$     t(5) = dassert(m{3}, '1950Q3');
+%$     t(6) = dassert(length(m), 3);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
diff --git a/src/@dates/subperiod.m b/src/@dates/subperiod.m
new file mode 100644
index 0000000000000000000000000000000000000000..1f391782684a3b38d133adf05ef8b40318b28435
--- /dev/null
+++ b/src/@dates/subperiod.m
@@ -0,0 +1,20 @@
+function s = subperiod(d)
+
+% Returns the subperiod (quarter, month or week depending on the frequency).
+
+% Copyright (C) 2016-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+s = d.time(2);
\ No newline at end of file
diff --git a/src/@dates/subsasgn.m b/src/@dates/subsasgn.m
new file mode 100644
index 0000000000000000000000000000000000000000..bd236093bb64dff92189ef40857ac8871bce3c45
--- /dev/null
+++ b/src/@dates/subsasgn.m
@@ -0,0 +1,33 @@
+function val = subsasgn(val, idx, rhs) % --*-- Unitary tests --*--
+
+% Copyright (C) 2013-2015 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+error('dates::subsasgn: Members of dates class are private')
+
+%@test:1
+%$ % Define a dates objects
+%$ d = dates('1950Q1'):dates('1950Q3');
+%$
+%$ % Call the tested routine.
+%$ try
+%$     d(1) = dates('1950Q4');
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/@dates/subsref.m b/src/@dates/subsref.m
new file mode 100644
index 0000000000000000000000000000000000000000..cbeea253d3618a5928be50fc4b9ddb1e663b08cd
--- /dev/null
+++ b/src/@dates/subsref.m
@@ -0,0 +1,347 @@
+function B = subsref(A,S) % --*-- Unitary tests --*--
+
+% Overloads the subsref method for dates objects.
+%
+% INPUTS
+% - A [dates]
+% - S [structure]
+%
+% OUTPUTS
+% - B [*]
+%
+% REMARKS
+% 1. The type of the returned argument depends on the content of S.
+% 2. See the matlab's documentation about the subsref method.
+
+% Copyright (C) 2011-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+switch S(1).type
+  case '.'
+    switch S(1).subs
+      case {'time','freq'}% Access public members.
+        if length(S)>1 && isequal(S(2).type,'()') && isempty(S(2).subs)
+            error(['dates::subsref: ' S(1).subs ' is not a method but a member!'])
+        end
+        B = builtin('subsref', A, S(1));
+      case {'sort','sort_','unique','unique_','double','isempty','length','char','ndat','year','subperiod'}% Public methods (without input arguments)
+        B = feval(S(1).subs,A);
+        if length(S)>1 && isequal(S(2).type,'()') && isempty(S(2).subs)
+            S = shiftS(S,1);
+        end
+      case {'append','append_','pop','pop_','remove','remove_'}% Public methods (with arguments).
+        if isequal(S(2).type,'()')
+            B = feval(S(1).subs,A,S(2).subs{:});
+            S = shiftS(S,1);
+        else
+            error('dates::subsref: Something is wrong in your syntax!')
+        end
+      case {'disp'}
+        feval(S(1).subs,A);
+        return
+      otherwise
+        error('dates::subsref: Unknown public member or method!')
+    end
+  case '()'
+    if isempty(A)
+        if isempty(A.freq)
+            % Populate an empty dates object with time member (freq is not specified). Needs two or three inputs. First input is an integer
+            % scalar specifying the frequency. Second input is either the time member (a n*2 array of integers) or a column vector with n
+            % elements (the first column of the time member --> years). If the the second input is a row vector and if A.freq~=1 a third input
+            % is necessary. The third input is n*1 vector of integers between 1 and A.freq (second column of the time member --> subperiods).
+            B = dates();
+            % First input is the frequency.
+            if isfreq(S(1).subs{1})
+                if ischar(S(1).subs{1})
+                    B.freq = string2freq(S(1).subs{1});
+                else
+                    B.freq = S(1).subs{1};
+                end
+            else
+                error('dates::subsref: First input must be a frequency!')
+            end
+            if isequal(length(S(1).subs),2)
+                % If two inputs are provided, the second input must be a n*2 array except if frequency is annual.
+                [n, m] = size(S(1).subs{2});
+                if m>2
+                    error('dates::subsref: Second input argument array cannot have more than two columns!')
+                end
+                if ~isequal(m,2) && ~isequal(B.freq,1)
+                    error('dates::subsref: Second argument has to be a n*2 array for non annual frequency!')
+                end
+                if ~all(all(S(1).subs{2}))
+                    error('dates::subsref: Second argument has be an array of intergers!')
+                end
+                if m>1 && ~issubperiod(S(1).subs{2}(:,2),B.freq)
+                    error(['dates::subsref: Elements in the second column of the first input argument are not legal subperiods (should be integers betwwen 1 and ' num2str(B.freq) ')!'])
+                end
+                if isequal(m,2)
+                    B.time = S(1).subs{2};
+                elseif isequal(m,1)
+                    B.time = [S(1).subs{2}, ones(n,1)];
+                else
+                    error('dates::subsref: This is a bug!')
+                end
+            elseif isequal(length(S(1).subs),3)
+                % If three inputs are provided, the second and third inputs are column verctors of integers (years and subperiods).
+                if ~iscolumn(S(1).subs{2}) && ~all(isint(S(1).subs{2}))
+                    error('dates::subsref: Second input argument must be a column vector of integers!')
+                end
+                n1 = size(S(1).subs{2},1);
+                if ~iscolumn(S(1).subs{3}) && ~issubperiod(S(1).subs{3}, B.freq)
+                    error(['dates::subsref: Third input argument must be a column vector of subperiods (integers between 1 and ' num2str(B.freq) ')!'])
+                end
+                n2 = size(S(1).subs{3},1);
+                if ~isequal(n1,n2)
+                    error('dates::subsref: Second and third input arguments must have the same number of elements!')
+                end
+                B.time = [S(1).subs{2}, S(1).subs{3}];
+            else
+                error('dates::subsref: Wrong calling sequence!')
+            end
+        else
+            % Populate an empty dates object with time member (freq is already specified).
+            % Needs one (time) or two (first and second columns of time for years and subperiods) inputs.
+            B = copy(A);
+            if isequal(length(S(1).subs),2)
+                if ~iscolumn(S(1).subs{1}) && ~all(isint(S(1).subs{1}))
+                    error('dates::subsref: First argument has to be a column vector of integers!')
+                end
+                n1 = size(S(1).subs{1},1);
+                if ~iscolumn(S(1).subs{2}) && ~issubperiod(S(1).subs{2}, B.freq)
+                    error(['dates::subsref: Second argument has to be a column vector of subperiods (integers between 1 and ' num2str(B.freq) ')!'])
+                end
+                n2 = size(S(1).subs{2},1);
+                if ~isequal(n2,n1)
+                    error('dates::subsref: First and second argument must have the same number of rows!')
+                end
+                B.time = [S(1).subs{1}, S(1).subs{2}];
+            elseif isequal(length(S(1).subs),1)
+                [n, m] = size(S(1).subs{1});
+                if ~isequal(m,2) && ~isequal(B.freq,1)
+                    error('dates::subsref: First argument has to be a n*2 array!')
+                end
+                if ~all(isint(S(1).subs{1}(:,1)))
+                    error('dates::subsref: First column of the first argument has to be a column vector of integers!')
+                end
+                if m>1 && issubperiod(S(1).subs{1}(:,1), B.freq)
+                    error(['dates::subsref: The second column of the first input argument has to be a column  vector of subperiods (integers between 1 and ' num2str(B.freq) ')!'])
+                end
+                if isequal(m,2)
+                    B.time = S(1).subs{1};
+                elseif isequal(m,1) && isequal(B.freq,1)
+                    B.time = [S(1).subs{1}, ones(n,1)];
+                else
+                    error('dates::subsref: This is a bug!')
+                end
+            else
+                error('dates::subsref: Wrong number of inputs!')
+            end
+        end
+    else
+        % dates object A is not empty. We extract some dates
+        if ismatrix(S(1).subs{1}) && isempty(S(1).subs{1})
+            B = dates(A.freq);
+        elseif isvector(S(1).subs{1}) && all(isint(S(1).subs{1})) && all(S(1).subs{1}>0) && all(S(1).subs{1}<=A.ndat())
+            B = dates();
+            B.freq = A.freq;
+            B.time = A.time(S(1).subs{1},:);
+        else
+            error(['dates::subsref: indices has to be a vector of positive integers less than or equal to ' int2str(A.ndat()) '!'])
+        end
+    end
+  otherwise
+    error('dates::subsref: Something is wrong in your syntax!')
+end
+
+S = shiftS(S,1);
+if ~isempty(S)
+    B = subsref(B, S);
+end
+
+%@test:1
+%$ % Define a dates object
+%$ B = dates('1950Q1','1950Q2','1950Q3','1950Q4','1951Q1');
+%$
+%$ % Try to extract a sub-dates object.
+%$ d = B(2:3);
+%$
+%$ if isa(d,'dates')
+%$     t(1) = 1;
+%$ else
+%$     t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.freq,B.freq);
+%$     t(3) = dassert(d.time,[1950 2; 1950 3]);
+%$     t(4) = dassert(d.ndat(),2);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define a dates object
+%$ B = dates('1950Q1'):dates('1960Q3');
+%$
+%$ % Try to extract a sub-dates object and apply a method
+%$
+%$ d = B(2:3).sort ;
+%$
+%$ if isa(d,'dates')
+%$     t(1) = 1;
+%$ else
+%$     t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.freq,B.freq);
+%$     t(3) = dassert(d.time,[1950 2; 1950 3]);
+%$     t(4) = dassert(d.ndat(),2);
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define a dates object
+%$ B = dates('1950Q1'):dates('1960Q3');
+%$
+%$ % Try to extract a sub-dates object and apply a method
+%$
+%$ d = B(2:3).sort() ;
+%$
+%$ if isa(d,'dates')
+%$     t(1) = 1;
+%$ else
+%$     t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.freq,B.freq);
+%$     t(3) = dassert(d.time,[1950 2; 1950 3]);
+%$     t(4) = dassert(d.ndat(),2);
+%$ end
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ % Define a dates object
+%$ B = dates('1950Q1','1950Q2','1950Q3','1950Q4','1951Q1');
+%$
+%$ % Try to extract a sub-dates object.
+%$ d = B(2);
+%$
+%$ if isa(d,'dates')
+%$     t(1) = 1;
+%$ else
+%$     t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(d.freq,B.freq);
+%$     t(3) = dassert(d.time,[1950 2]);
+%$     t(4) = dassert(d.ndat(),1);
+%$ end
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ % Define an empty dates object with quaterly frequency.
+%$ qq = dates('Q');
+%$
+%$ % Define a ranges of dates using qq.
+%$ try
+%$     r1 = qq(1950,1):qq(1950,3);%qq([1950, 3]);
+%$     t(1) = 1;
+%$ catch
+%$     t(1) = 0;
+%$ end
+%$ if t(1)
+%$     try
+%$         r2 = qq([1950, 1; 1950, 2; 1950, 3]);
+%$         t(2) = 1;
+%$     catch
+%$         t(2) = 0;
+%$     end
+%$ end
+%$ if t(1) && t(2)
+%$     try
+%$         r3 = qq(1950*ones(3,1), transpose(1:3));
+%$         t(3) = 1;
+%$     catch
+%$         t(3) = 0;
+%$     end
+%$ end
+%$
+%$ if t(1) && t(2) && t(3)
+%$     t(4) = dassert(r1,r2);
+%$     t(5) = dassert(r1,r3);
+%$ end
+%$ T = all(t);
+%@eof:5
+
+%@test:6
+%$ % Define an empty dates object with quaterly frequency.
+%$ date = dates();
+%$
+%$ % Define a ranges of dates using qq.
+%$ try
+%$     r1 = date(4,1950,1):date(4,[1950, 3]);
+%$     t(1) = 1;
+%$ catch
+%$     t(1) = 0;
+%$ end
+%$ if t(1)
+%$     try
+%$         r2 = date(4,[1950, 1; 1950, 2; 1950, 3]);
+%$         t(2) = 1;
+%$     catch
+%$         t(2) = 0;
+%$     end
+%$ end
+%$ if t(1) && t(2)
+%$     try
+%$         r3 = date(4,1950*ones(3,1), transpose(1:3));
+%$         t(3) = 1;
+%$     catch
+%$         t(3) = 0;
+%$     end
+%$ end
+%$
+%$ if t(1) && t(2) && t(3)
+%$     t(4) = dassert(r1,r2);
+%$     t(5) = dassert(r1,r3);
+%$ end
+%$ T = all(t);
+%@eof:6
+
+%@test:7
+%$ % Define a dates object
+%$ B = dates('1950Q1','1950Q2','1950Q3','1950Q4','1951Q1');
+%$
+%$ % Try to extract a sub-dates object.
+%$ try
+%$     d = B([]);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(isa(d,'dates'), true);
+%$     t(3) = dassert(isempty(d), true);
+%$ end
+%$ T = all(t);
+%@eof:7
diff --git a/src/@dates/uminus.m b/src/@dates/uminus.m
new file mode 100644
index 0000000000000000000000000000000000000000..840592182f6524fe154a18d225b233e549e35452
--- /dev/null
+++ b/src/@dates/uminus.m
@@ -0,0 +1,75 @@
+function o = uminus(o)  % --*-- Unitary tests --*--
+
+% Overloads the unary minus operator for dates objects. Shifts all the elements by one period.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - o [dates]
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+o.time(:,2) = o.time(:,2)-1;
+idx = find(o.time(:,2)==0);
+o.time(idx,1) = o.time(idx,1)-1;
+o.time(idx,2) = o.freq;
+
+%@test:1
+%$ % Define some dates
+%$ date_1 = '1950Y';
+%$ date_2 = '1950Q2';
+%$ date_3 = '1950Q1';
+%$ date_4 = '1950M2';
+%$ date_5 = '1950M1';
+%$
+%$ % Call the tested routine.
+%$ d1 = dates(date_1); -d1;
+%$ d2 = dates(date_2); -d2;
+%$ d3 = dates(date_3); -d3;
+%$ d4 = dates(date_4); -d4;
+%$ d5 = dates(date_5); -d5;
+%$ i1 = (d1==dates('1949Y'));
+%$ i2 = (d2==dates('1950Q1'));
+%$ i3 = (d3==dates('1949Q4'));
+%$ i4 = (d4==dates('1950M1'));
+%$ i5 = (d5==dates('1949M12'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i1,true);
+%$ t(2) = dassert(i2,true);
+%$ t(3) = dassert(i3,true);
+%$ t(4) = dassert(i4,true);
+%$ t(5) = dassert(i5,true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ d1 = dates('1950Q1','1950Q2','1950Q3','1950Q4','1951Q1');
+%$ d2 = dates('1949Q4','1950Q1','1950Q2','1950Q3','1950Q4');
+%$ try
+%$   -d1;
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(all(d2==d1),true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/@dates/union.m b/src/@dates/union.m
new file mode 100644
index 0000000000000000000000000000000000000000..3d56a20fb15f3be28296b628e69f776b7c171754
--- /dev/null
+++ b/src/@dates/union.m
@@ -0,0 +1,60 @@
+function o = union(varargin) % --*-- Unitary tests --*--
+
+% Overloads union function for dates objects (removes repetitions if any).
+%
+% INPUTS
+% - varargin [dates]
+%
+% OUPUTS
+% - o [dates]
+%
+% REMARKS
+% 1. Elements in o are sorted by increasing order.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~all(cellfun(@isdates,varargin))
+    error('dates:union:ArgCheck','All input arguments must be dates objects.')
+end
+
+if isequal(nargin,1)
+    o = sort(unique(varargin{1}));
+    return;
+end
+
+o = sort(unique(horzcat(varargin{:})));
+
+%@test:1
+%$ % Define some dates objects
+%$ d1 = dates('1950Q1'):dates('1959Q4') ;
+%$ d2 = dates('1960Q1'):dates('1969Q4') ;
+%$ d3 = dates('1970Q1'):dates('1979Q4') ;
+%$
+%$ % Call the tested routine.
+%$ e1 = union(d1);
+%$ e2 = union(d1,d2);
+%$ e3 = union(d1,d2,d3);
+%$ e4 = union(d1,d2,d3,d2+d3);
+%$ e5 = union(d1,d2,d3,d2);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(e1,d1);
+%$ t(2) = dassert(e2,d1+d2);
+%$ t(3) = dassert(e3,d1+d2+d3);
+%$ t(4) = dassert(e4,d1+d2+d3);
+%$ t(5) = dassert(e5,d1+d2+d3);
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/@dates/unique.m b/src/@dates/unique.m
new file mode 100644
index 0000000000000000000000000000000000000000..86c6963db4ced270e51a344c3efd82175d18ad16
--- /dev/null
+++ b/src/@dates/unique.m
@@ -0,0 +1,123 @@
+function o = unique(o) % --*-- Unitary tests --*--
+
+% Overloads the unique function for dates objects.
+%
+% INPUTS
+% - o [dates]
+%
+% OUPUTS
+% - o [dates]
+%
+% REMARKS
+% 1. Only the last occurence of a date is kept.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if o.ndat()<=1
+    return
+end
+
+o = copy(o);
+o.unique_();
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950q1';
+%$ B4 = '1945Q3';
+%$ B5 = '1950Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1953 4; 1950 1; 1945 3; 1950 2];
+%$ e.freq = 4;
+%$ f.time = [1953 4; 1950 2; 1950 1; 1945 3; 1950 2];
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4,B5);
+%$ try
+%$     c = d.unique();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,f.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950q1';
+%$ B4 = '1945Q3';
+%$ B5 = '1950Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1953 4; 1950 1; 1945 3; 1950 2];
+%$ e.freq = 4;
+%$ f.time = [1953 4; 1950 2; 1950 1; 1945 3; 1950 2];
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4,B5);
+%$ try
+%$     c = unique(d);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,f.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$
+%$ % Define expected results.
+%$ e.time = [1953 4];
+%$ e.freq = 4;
+%$ f.time = e.time;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1);
+%$ try
+%$     c = d.unique();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,f.time);
+%$     t(3) = dassert(c.time,e.time);
+%$     t(4) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:3
diff --git a/src/@dates/unique_.m b/src/@dates/unique_.m
new file mode 100644
index 0000000000000000000000000000000000000000..dd14b4e4fcc9701102187e053062ffb8b2600a25
--- /dev/null
+++ b/src/@dates/unique_.m
@@ -0,0 +1,97 @@
+function o = unique_(o) % --*-- Unitary tests --*--
+
+% Overloads the unique function for dates objects (in place modification).
+%
+% INPUTS
+% - o [dates]
+%
+% OUPUTS
+% - o [dates]
+%
+% REMARKS
+% 1. Only the last occurence of a date is kept.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if o.ndat()<=1
+    return
+end
+
+if isoctave || matlab_ver_less_than('8.1.0')
+    [tmp, id, jd] = unique(o.time,'rows');
+else
+    [tmp, id, jd] = unique(o.time,'rows','legacy');
+end
+
+o.time = o.time(sort(id),:);
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950q1';
+%$ B4 = '1945Q3';
+%$ B5 = '1950Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1953 4; 1950 1; 1945 3; 1950 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4,B5);
+%$ try
+%$     d.unique_();
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:1
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950q1';
+%$ B4 = '1945Q3';
+%$ B5 = '1950Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1953 4; 1950 1; 1945 3; 1950 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B1,B2,B3,B4,B5);
+%$ try
+%$     unique_(d);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$ end
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/@dates/uplus.m b/src/@dates/uplus.m
new file mode 100644
index 0000000000000000000000000000000000000000..23bd48da0a7642fd2ebf0948460263c9038a4281
--- /dev/null
+++ b/src/@dates/uplus.m
@@ -0,0 +1,75 @@
+function o = uplus(o)  % --*-- Unitary tests --*--
+
+% Overloads the unary plus operator for dates objects. Shifts all the elements by one period.
+%
+% INPUTS
+% - o [dates]
+%
+% OUTPUTS
+% - o [dates]
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+o.time(:,2) = o.time(:,2)+1;
+idx = find(o.time(:,2)>o.freq); % Happy new year!
+o.time(idx,1) = o.time(idx,1)+1;
+o.time(idx,2) = 1;
+
+%@test:1
+%$ % Define some dates
+%$ date_1 = '1950Y';
+%$ date_2 = '1950Q2';
+%$ date_3 = '1950Q4';
+%$ date_4 = '1950M2';
+%$ date_5 = '1950M12';
+%$
+%$ % Call the tested routine.
+%$ d1 = dates(date_1); +d1;
+%$ d2 = dates(date_2); +d2;
+%$ d3 = dates(date_3); +d3;
+%$ d4 = dates(date_4); +d4;
+%$ d5 = dates(date_5); +d5;
+%$ i1 = (d1==dates('1951Y'));
+%$ i2 = (d2==dates('1950Q3'));
+%$ i3 = (d3==dates('1951Q1'));
+%$ i4 = (d4==dates('1950M3'));
+%$ i5 = (d5==dates('1951M1'));
+%$
+%$ % Check the results.
+%$ t(1) = dassert(i1,true);
+%$ t(2) = dassert(i2,true);
+%$ t(3) = dassert(i3,true);
+%$ t(4) = dassert(i4,true);
+%$ t(5) = dassert(i5,true);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ d1 = dates('1950Q1','1950Q2','1950Q3','1950Q4','1951Q1');
+%$ d2 = dates('1950Q2','1950Q3','1950Q4','1951Q1','1951Q2');
+%$ try
+%$   +d1;
+%$   t(1) = 1;
+%$ catch
+%$   t(1) = 0;
+%$ end
+%$
+%$ if t(1)
+%$   t(2) = dassert(all(d2==d1),true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/@dates/vertcat.m b/src/@dates/vertcat.m
new file mode 100644
index 0000000000000000000000000000000000000000..77388792b37690953543088c6a05392f09e23448
--- /dev/null
+++ b/src/@dates/vertcat.m
@@ -0,0 +1,86 @@
+function o = vertcat(varargin) % --*-- Unitary tests --*--
+
+% Overloads the vertcat method for dates objects.
+%
+% INPUTS
+% - varargin [dates]
+%
+% OUTPUTS
+% - o [dates] object containing dates defined in varargin{:}
+%
+% EXAMPLE 1
+%  If A, B and C are dates object the following syntax:
+%
+%    D = [A; B; C] ;
+%
+%  Defines a dates object D containing the dates appearing in A, B and C.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~all(cellfun(@isdates,varargin))
+    error('dates:vertcat:ArgCheck','All input arguments must be dates objects.')
+end
+
+o = horzcat(varargin{:});
+
+%@test:1
+%$ % Define some dates
+%$ B1 = '1953Q4';
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$ B5 = '2009Q2';
+%$
+%$ % Define expected results.
+%$ e.time = [1945 3; 1950 1; 1950 2; 1953 4; 2009 2];
+%$ e.freq = 4;
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2);
+%$ try
+%$     d = [d; dates(B1); dates(B5)];
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ % Check the results.
+%$ if t(1)
+%$     t(2) = dassert(d.time,e.time);
+%$     t(3) = dassert(d.freq,e.freq);
+%$     t(4) = size(e.time,1)==d.ndat();
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ % Define some dates
+%$ B2 = '1950Q2';
+%$ B3 = '1950Q1';
+%$ B4 = '1945Q3';
+%$
+%$ % Call the tested routine.
+%$ d = dates(B4,B3,B2);
+%$ try
+%$     d = [d; 1];
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
diff --git a/src/@dates/year.m b/src/@dates/year.m
new file mode 100644
index 0000000000000000000000000000000000000000..9148435a052ffdab89349ba5d437ebed88056eac
--- /dev/null
+++ b/src/@dates/year.m
@@ -0,0 +1,20 @@
+function y = year(d)
+
+% Returns the year.
+
+% Copyright (C) 2016-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+y = d.time(1);
\ No newline at end of file
diff --git a/src/initialize_dates_toolbox.m b/src/initialize_dates_toolbox.m
new file mode 100644
index 0000000000000000000000000000000000000000..39f06576bacf42c9a00bd582a688152996910b69
--- /dev/null
+++ b/src/initialize_dates_toolbox.m
@@ -0,0 +1,48 @@
+% Copyright (C) 2014-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+
+% Get the path to the dates/src folder.
+dates_src_root = strrep(which('initialize_dates_toolbox'),'initialize_dates_toolbox.m','');
+
+% Set the subfolders to be added in the path.
+p = {'/utilities/is'; ...
+     '/utilities/op'; ...
+     '/utilities/convert'};
+
+% Add missing routines if dynare is not in the path
+if ~exist('isint','file')
+    p{end+1} = '/utilities/missing/isint';
+end
+
+if ~exist('isoctave','file')
+    p{end+1} = '/utilities/missing/isoctave';
+end
+
+if ~exist('shiftS','file')
+    p{end+1} = '/utilities/missing/shiftS';
+end
+
+if ~exist('matlab_ver_less_than','file')
+    p{end+1} = '/utilities/missing/matlab_ver_less_than';
+end
+
+% Set path
+P = cellfun(@(c)[dates_src_root(1:end-1) c], p, 'uni', false);
+addpath(P{:});
+
+if ~isoctave && (~exist('rows','file') || ~exist('columns','file'))
+    addpath([dates_src_root(1:end-1) '/utilities/missing/dims']);
+end
\ No newline at end of file
diff --git a/src/utilities/convert/date2string.m b/src/utilities/convert/date2string.m
new file mode 100644
index 0000000000000000000000000000000000000000..c8d03441a1109533b695ee972aa94866755b5824
--- /dev/null
+++ b/src/utilities/convert/date2string.m
@@ -0,0 +1,121 @@
+function s = date2string(varargin) % --*-- Unitary tests --*--
+
+% Returns date as a string.
+%
+% INPUTS
+%  o varargin{1}     + dates object with one element, if nargin==1.
+%                    + 1*2 vector of integers (first element is the year, second element is the subperiod), if nargin==2.
+%  o varargin{2}     integer scalar equal to 1, 4, 12 or 52 (frequency).
+%
+% OUTPUTS
+%  o s               string.
+
+% Copyright (C) 2013-2017 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 <http://www.gnu.org/licenses/>.
+
+if isequal(nargin,1)
+    if ~(isa(varargin{1},'dates') && isequal(length(varargin{1}),1))
+        error(['dates::format: Input argument ' inputname(1) ' has to be a dates object with one element!'])
+    else
+        time = varargin{1}.time;
+        freq = varargin{1}.freq;
+    end
+end
+
+if isequal(nargin,2)
+    if ~(isvector(varargin{1}) && isequal(length(varargin{1}),2) && all(isint(varargin{1})) && isscalar(varargin{2} && ismember(varargin{2},[1 4 12 52])))
+        error(['dates::format: First input must be a 1*2 vector of integers and second input must be a scalar integer (1, 4, 12 or 52)!'])
+    else
+        if varargin{1}(2)>varargin{2} || varargin{1}(2)<1
+            error('dates::format: Second element of the first input be between 1 and %s!',num2str(varargin{2}))
+        end
+        time = varargin{1};
+        freq = varargin{2};
+    end
+end
+
+s = [num2str(time(1)) freq2string(freq)];
+if freq>1
+    s = strcat(s, num2str(time(2)));
+end
+
+%@test:1
+%$ try
+%$     str = date2string(dates('1938Q4'));
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str, '1938Q4');
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ try
+%$     str = date2string(dates('1938Q4','1945Q3'));
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ try
+%$     str = date2string([1938, 11], 12);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str, '1938M11');
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ try
+%$     str = date2string([1938; 11], 12);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(str, '1938M11');
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ try
+%$     str = date2string([1938; 11], 4);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
diff --git a/src/utilities/convert/freq2string.m b/src/utilities/convert/freq2string.m
new file mode 100644
index 0000000000000000000000000000000000000000..b1b85dd704c85280525345fa2bf5da6b2e585bae
--- /dev/null
+++ b/src/utilities/convert/freq2string.m
@@ -0,0 +1,69 @@
+function s = freq2string(freq) % --*-- Unitary tests --*--
+
+% INPUTS
+%  o freq     scalar integer,  equal to 1, 4, 12 or 52 (resp. annual, quaterly, monthly or weekly)
+%
+% OUTPUTS
+%  o s        character, equal to Y, Q, M or W (resp. annual, quaterly, monthly or weekly)
+
+% Copyright (C) 2013-2017 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 <http://www.gnu.org/licenses/>.
+
+switch freq
+  case 1
+    s = 'Y';
+  case 4
+    s = 'Q';
+  case 12
+    s = 'M';
+  case 52
+    s = 'W';
+  otherwise
+    error('dates::freq2string: Unknown frequency!')
+end
+
+%@test:1
+%$ try
+%$     strY = freq2string(1);
+%$     strQ = freq2string(4);
+%$     strM = freq2string(12);
+%$     strW = freq2string(52);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(strY, 'Y');
+%$     t(3) = dassert(strQ, 'Q');
+%$     t(4) = dassert(strM, 'M');
+%$     t(5) = dassert(strW, 'W');
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ try
+%$     str = freq2string(13);
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
diff --git a/src/utilities/convert/string2date.m b/src/utilities/convert/string2date.m
new file mode 100644
index 0000000000000000000000000000000000000000..96835ea6df0f708409f2b3029429b82db2a36ac0
--- /dev/null
+++ b/src/utilities/convert/string2date.m
@@ -0,0 +1,109 @@
+function date = string2date(a) % --*-- Unitary tests --*--
+
+% Copyright (C) 2013-2017 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 <http://www.gnu.org/licenses/>.
+
+date = struct('freq', NaN, 'time', NaN(1,2));
+
+if ~ischar(a) || ~isdate(a)
+    error('dates::string2date: Input must be a string that can be interpreted as a date!');
+end
+
+if isyearly(a)
+    year = 1:(regexp(a,'[AaYy]')-1);
+    date.freq = 1;
+    date.time = write_time_field_y(a, year);
+    return
+end
+
+if isquarterly(a)
+    year = 1:(regexp(a,'[Qq]')-1);
+    date.freq = 4;
+    date.time = write_time_field(a, year);
+    return
+end
+
+if ismonthly(a)
+    year = 1:(regexp(a,'[Mm]')-1);
+    date.freq = 12;
+    date.time = write_time_field(a, year);
+    return
+end
+
+if isweekly(a)
+    year = 1:(regexp(a,'[Ww]')-1);
+    date.freq = 52;
+    date.time = write_time_field(a, year);
+    return
+end
+
+
+function b = write_time_field(c, d)
+b(1) = str2double(c(d));
+b(2) = str2double(c(d(end)+2:end));
+
+function b = write_time_field_y(c, d)
+b(1) = str2double(c(d));
+b(2) = 1;
+
+%@test:1
+%$
+%$ % Define some dates
+%$ date_1 = '1950Q2';
+%$ date_2 = '1950m10';
+%$ date_3 = '1950w50';
+%$ date_4 = '1950a';
+%$ date_5 = '1967y';
+%$ date_6 = '2009A';
+%$
+%$ % Define expected results.
+%$ e_date_1 = [1950 2];
+%$ e_freq_1 = 4;
+%$ e_date_2 = [1950 10];
+%$ e_freq_2 = 12;
+%$ e_date_3 = [1950 50];
+%$ e_freq_3 = 52;
+%$ e_date_4 = [1950 1];
+%$ e_freq_4 = 1;
+%$ e_date_5 = [1967 1];
+%$ e_freq_5 = 1;
+%$ e_date_6 = [2009 1];
+%$ e_freq_6 = 1;
+%$
+%$ % Call the tested routine.
+%$ d1 = string2date(date_1);
+%$ d2 = string2date(date_2);
+%$ d3 = string2date(date_3);
+%$ d4 = string2date(date_4);
+%$ d5 = string2date(date_5);
+%$ d6 = string2date(date_6);
+%$
+%$ % Check the results.
+%$ t(1) = dassert(d1.time,e_date_1);
+%$ t(2) = dassert(d2.time,e_date_2);
+%$ t(3) = dassert(d3.time,e_date_3);
+%$ t(4) = dassert(d4.time,e_date_4);
+%$ t(5) = dassert(d5.time,e_date_5);
+%$ t(6) = dassert(d6.time,e_date_6);
+%$ t(7) = dassert(d1.freq,e_freq_1);
+%$ t(8) = dassert(d2.freq,e_freq_2);
+%$ t(9) = dassert(d3.freq,e_freq_3);
+%$ t(10) = dassert(d4.freq,e_freq_4);
+%$ t(11)= dassert(d5.freq,e_freq_5);
+%$ t(12)= dassert(d6.freq,e_freq_6);
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/convert/string2freq.m b/src/utilities/convert/string2freq.m
new file mode 100644
index 0000000000000000000000000000000000000000..8a88b927934e2338e8aae661b24c83ce0fa4ff0f
--- /dev/null
+++ b/src/utilities/convert/string2freq.m
@@ -0,0 +1,69 @@
+function freq = string2freq(s) % --*-- Unitary tests --*--
+
+% INPUTS
+%  o s        character, equal to Y, Q, M or W (resp. annual, quaterly, monthly or weekly)
+%
+% OUTPUTS
+%  o freq     scalar integer,  equal to 1, 4, 12 or 52 (resp. annual, quaterly, monthly or weekly)
+
+% Copyright (C) 2013-2017 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 <http://www.gnu.org/licenses/>.
+
+switch upper(s)
+  case {'Y','A'}
+    freq = 1;
+  case 'Q'
+    freq = 4;
+  case 'M'
+    freq = 12;
+  case 'W'
+    freq = 52;
+  otherwise
+    error('dates::freq2string: Unknown frequency!')
+end
+
+%@test:1
+%$ try
+%$     nY = string2freq('Y');
+%$     nQ = string2freq('Q');
+%$     nM = string2freq('M');
+%$     nW = string2freq('W');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(nY, 1);
+%$     t(3) = dassert(nQ, 4);
+%$     t(4) = dassert(nM, 12);
+%$     t(5) = dassert(nW, 52);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ try
+%$     n = string2freq('Z');
+%$     t(1) = false;
+%$ catch
+%$     t(1) = true;
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
diff --git a/src/utilities/is/isdate.m b/src/utilities/is/isdate.m
new file mode 100644
index 0000000000000000000000000000000000000000..78ef73ccacc91ec30abc1b1317cb6339b37db38c
--- /dev/null
+++ b/src/utilities/is/isdate.m
@@ -0,0 +1,55 @@
+function b = isdate(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-2017 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 <http://www.gnu.org/licenses/>.
+
+if isnumeric(str) && isscalar(str)
+    b = true;
+    return
+end
+
+b = isstringdate(str);
+
+%@test:1
+%$
+%$ date_1 = 1950;
+%$ date_2 = '1950m2';
+%$ date_3 = '-1950m2';
+%$ date_4 = '1950m52';
+%$ date_5 = ' 1950';
+%$ date_6 = '1950Y';
+%$ date_7 = '-1950a';
+%$ date_8 = '1950m ';
+%$
+%$ t(1) = dassert(isdate(date_1),true);
+%$ t(2) = dassert(isdate(date_2),true);
+%$ t(3) = dassert(isdate(date_3),true);
+%$ t(4) = dassert(isdate(date_4),false);
+%$ t(5) = dassert(isdate(date_5),false);
+%$ t(6) = dassert(isdate(date_6),true);
+%$ t(7) = dassert(isdate(date_7),true);
+%$ t(8) = dassert(isdate(date_8),false);
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/is/isdates.m b/src/utilities/is/isdates.m
new file mode 100644
index 0000000000000000000000000000000000000000..542569c0a3969b9ac1a4f9e6703fbe60a14644a1
--- /dev/null
+++ b/src/utilities/is/isdates.m
@@ -0,0 +1,97 @@
+function B = isdates(A) % --*-- Unitary tests --*--
+
+% Tests if the input A is a dates object.
+
+% Copyright (C) 2013-2015 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 <http://www.gnu.org/licenses/>.
+
+B = isa(A,'dates');
+
+%@test:1
+%$ try
+%$     boolean = isdates(dates('1950Q2'));
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ try
+%$     boolean = isdates(dates());
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ try
+%$     boolean = isdates(dates('1950Q2'):dates('1950Q4'));
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ try
+%$     boolean = isdates(1);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ try
+%$     boolean = isdates('1938M11');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
\ No newline at end of file
diff --git a/src/utilities/is/isfreq.m b/src/utilities/is/isfreq.m
new file mode 100644
index 0000000000000000000000000000000000000000..d966d6c132f9e95f8921fc333e7be0d35bcf6491
--- /dev/null
+++ b/src/utilities/is/isfreq.m
@@ -0,0 +1,114 @@
+function B = isfreq(A) % --*-- Unitary tests --*--
+
+% Tests if A can be interpreted as a frequency.
+%
+% INPUTS
+%  o A     scalar integer or character.
+%
+% OUTPUTS
+%  o B     scalar integer equal to one if A can be interpreted as a frequency, zero otherwise.
+
+% Copyright (C) 2013-2017 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 <http://www.gnu.org/licenses/>.
+
+B = false;
+
+if ischar(A)
+    if isequal(length(A),1) && ismember(upper(A),{'Y','A','Q','M','W'})
+        B = true;
+        return
+    end
+end
+
+if isnumeric(A) && isequal(length(A),1) && ismember(A,[1 4 12 52])
+    B = true;
+end
+
+%@test:1
+%$ try
+%$     boolean = isfreq('w');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ try
+%$     boolean = isfreq('W');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ try
+%$     boolean = isfreq('M');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ try
+%$     boolean = isfreq('Q');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ try
+%$     boolean = isfreq('Y');
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
diff --git a/src/utilities/is/ismonthly.m b/src/utilities/is/ismonthly.m
new file mode 100644
index 0000000000000000000000000000000000000000..dcf9c4e7312d3df35e67bc658fa8ae452d074710
--- /dev/null
+++ b/src/utilities/is/ismonthly.m
@@ -0,0 +1,58 @@
+function b = ismonthly(str)  % --*-- Unitary tests --*--
+
+% Tests if the input can be interpreted as a monthly date.
+%
+% INPUTS
+%  o str     string.
+%
+% OUTPUTS
+%  o b       integer scalar, equal to 1 if str can be interpreted as a monthly date or 0 otherwise.
+
+% Copyright (C) 2012-2017 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 <http://www.gnu.org/licenses/>.
+
+if ischar(str)
+    if isempty(regexp(str,'^-?[0-9]+[Mm]([1-9]|1[0-2])$','once'))
+        b = false;
+    else
+        b = true;
+    end
+else
+    b = false;
+end
+
+%@test:1
+%$
+%$ date_1 = '1950M2';
+%$ date_2 = '1950m2';
+%$ date_3 = '-1950m2';
+%$ date_4 = '1950m12';
+%$ date_5 = '1950 azd ';
+%$ date_6 = '1950Y';
+%$ date_7 = '1950Q3';
+%$ date_8 = '1950m24';
+%$
+%$ t(1) = dassert(ismonthly(date_1),true);
+%$ t(2) = dassert(ismonthly(date_2),true);
+%$ t(3) = dassert(ismonthly(date_3),true);
+%$ t(4) = dassert(ismonthly(date_4),true);
+%$ t(5) = dassert(ismonthly(date_5),false);
+%$ t(6) = dassert(ismonthly(date_6),false);
+%$ t(7) = dassert(ismonthly(date_7),false);
+%$ t(8) = dassert(ismonthly(date_8),false);
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/is/isquarterly.m b/src/utilities/is/isquarterly.m
new file mode 100644
index 0000000000000000000000000000000000000000..82811c93e8c98b4b037d9fb4dce31af771182cf7
--- /dev/null
+++ b/src/utilities/is/isquarterly.m
@@ -0,0 +1,56 @@
+function b = isquarterly(str)  % --*-- Unitary tests --*--
+
+% Tests if the input can be interpreted as a quarterly date.
+%
+% INPUTS
+%  o str     string.
+%
+% OUTPUTS
+%  o b       integer scalar, equal to 1 if str can be interpreted as a quarterly date or 0 otherwise.
+
+% Copyright (C) 2012-2017 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 <http://www.gnu.org/licenses/>.
+
+if ischar(str)
+    if isempty(regexp(str,'^-?[0-9]+[Qq][1-4]$','once'))
+        b = false;
+    else
+        b = true;
+    end
+else
+    b = false;
+end
+
+%@test:1
+%$
+%$ date_1 = '1950Q2';
+%$ date_2 = '1950q2';
+%$ date_3 = '-1950q2';
+%$ date_4 = '1950q12';
+%$ date_5 = '1950 azd ';
+%$ date_6 = '1950Y';
+%$ date_7 = '1950m24';
+%$
+%$ t(1) = dassert(isquarterly(date_1),true);
+%$ t(2) = dassert(isquarterly(date_2),true);
+%$ t(3) = dassert(isquarterly(date_3),true);
+%$ t(4) = dassert(isquarterly(date_4),false);
+%$ t(5) = dassert(isquarterly(date_5),false);
+%$ t(6) = dassert(isquarterly(date_6),false);
+%$ t(7) = dassert(isquarterly(date_7),false);
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/is/isstringdate.m b/src/utilities/is/isstringdate.m
new file mode 100644
index 0000000000000000000000000000000000000000..3221c94e9a18419b2094b0ddefe442712b49cc92
--- /dev/null
+++ b/src/utilities/is/isstringdate.m
@@ -0,0 +1,69 @@
+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-2017 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 <http://www.gnu.org/licenses/>.
+
+if ischar(str)
+    b = isquarterly(str) || isyearly(str) || ismonthly(str) || isweekly(str);
+else
+    b = false;
+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 ';
+%$ date_9 = 'A';
+%$ date_10 = '1938Q';
+%$ date_11 = 'Q4';
+%$ date_12 = '1938M';
+%$ date_13 = 'M11';
+%$ date_14 = '1W';
+%$ date_15 = 'W1';
+%$
+%$ t(1) = dassert(isstringdate(date_1),true);
+%$ t(2) = dassert(isstringdate(date_2),true);
+%$ t(3) = dassert(isstringdate(date_3),true);
+%$ t(4) = dassert(isstringdate(date_4),false);
+%$ t(5) = dassert(isstringdate(date_5),false);
+%$ t(6) = dassert(isstringdate(date_6),true);
+%$ t(7) = dassert(isstringdate(date_7),true);
+%$ t(8) = dassert(isstringdate(date_8),false);
+%$ t(9) = dassert(isstringdate(date_9),false);
+%$ t(10) = dassert(isstringdate(date_10),false);
+%$ t(11) = dassert(isstringdate(date_11),false);
+%$ t(12) = dassert(isstringdate(date_12),false);
+%$ t(13) = dassert(isstringdate(date_13),false);
+%$ t(14) = dassert(isstringdate(date_14),false);
+%$ t(15) = dassert(isstringdate(date_15),false);
+%$
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/is/issubperiod.m b/src/utilities/is/issubperiod.m
new file mode 100644
index 0000000000000000000000000000000000000000..60fb951e663c9420394373e70871b1be1b68c74c
--- /dev/null
+++ b/src/utilities/is/issubperiod.m
@@ -0,0 +1,69 @@
+function C = issubperiod(A,B) % --*-- Unitary tests --*--
+
+% Copyright (C) 2013-2015 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 <http://www.gnu.org/licenses/>.
+
+if isfreq(B)
+    C = all(isint(A)) && all(A>=1) && all(A<=B);
+else
+    error('issubperiod:: Second input argument must be equal to 1, 4, 12 or 52 (frequency)!')
+end
+
+%@test:1
+%$ try
+%$    b = issubperiod(1, 1);
+%$    t(1) = true;
+%$ catch
+%$    t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(b, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ try
+%$    b = issubperiod(2, 4);
+%$    t(1) = true;
+%$ catch
+%$    t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(b, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ try
+%$    b = issubperiod(6, 4);
+%$    t(1) = true;
+%$ catch
+%$    t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(b, false);
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
\ No newline at end of file
diff --git a/src/utilities/is/isweekly.m b/src/utilities/is/isweekly.m
new file mode 100644
index 0000000000000000000000000000000000000000..a8fdc02934f8c62a86e0d7cafe8e4b274b894528
--- /dev/null
+++ b/src/utilities/is/isweekly.m
@@ -0,0 +1,58 @@
+function b = isweekly(str)  % --*-- Unitary tests --*--
+
+% Tests if the input can be interpreted as a weekly date.
+%
+% INPUTS
+%  o str     string.
+%
+% OUTPUTS
+%  o b       integer scalar, equal to 1 if str can be interpreted as a weekly date or 0 otherwise.
+
+% Copyright (C) 2012-2017 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 <http://www.gnu.org/licenses/>.
+
+if ischar(str)
+    if isempty(regexp(str,'^-?[0-9]+[Ww]([1-9]|[1-4][0-9]|5[0-2])$','once'))
+        b = false;
+    else
+        b = true;
+    end
+else
+    b = false;
+end
+
+%@test:1
+%$
+%$ date_1 = '1950W2';
+%$ date_2 = '1950w2';
+%$ date_3 = '-1950w2';
+%$ date_4 = '1950w22';
+%$ date_5 = '1950 azd';
+%$ date_6 = '1950Y';
+%$ date_7 = '1950Q3';
+%$ date_8 = '1950m54';
+%$
+%$ t(1) = dassert(isweekly(date_1),true);
+%$ t(2) = dassert(isweekly(date_2),true);
+%$ t(3) = dassert(isweekly(date_3),true);
+%$ t(4) = dassert(isweekly(date_4),true);
+%$ t(5) = dassert(isweekly(date_5),false);
+%$ t(6) = dassert(isweekly(date_6),false);
+%$ t(7) = dassert(isweekly(date_7),false);
+%$ t(8) = dassert(isweekly(date_8),false);
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/is/isyearly.m b/src/utilities/is/isyearly.m
new file mode 100644
index 0000000000000000000000000000000000000000..181b7b4ea8834711945c029f53510cbd90f8fac3
--- /dev/null
+++ b/src/utilities/is/isyearly.m
@@ -0,0 +1,58 @@
+function b = isyearly(str)  % --*-- Unitary tests --*--
+
+% Tests if the input can be interpreted as a yearly date.
+%
+% INPUTS
+%  o str     string.
+%
+% OUTPUTS
+%  o b       integer scalar, equal to 1 if str can be interpreted as a yearly date or 0 otherwise.
+
+% Copyright (C) 2012-2017 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 <http://www.gnu.org/licenses/>.
+
+if ischar(str)
+    if isempty(regexp(str,'^-?[0-9]+[YyAa]$','once'))
+        b = false;
+    else
+        b = true;
+    end
+else
+    b = false;
+end
+
+%@test:1
+%$
+%$ date_1 = '1950M2';
+%$ date_2 = '1950m2';
+%$ date_3 = '-1950m2';
+%$ date_4 = '1950m12';
+%$ date_5 = '1950 azd ';
+%$ date_6 = '1950Y';
+%$ date_7 = '-1950a';
+%$ date_8 = '1950m24';
+%$
+%$ t(1) = dassert(isyearly(date_1),false);
+%$ t(2) = dassert(isyearly(date_2),false);
+%$ t(3) = dassert(isyearly(date_3),false);
+%$ t(4) = dassert(isyearly(date_4),false);
+%$ t(5) = dassert(isyearly(date_5),false);
+%$ t(6) = dassert(isyearly(date_6),true);
+%$ t(7) = dassert(isyearly(date_7),true);
+%$ t(8) = dassert(isyearly(date_8),false);
+%$ T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/missing/dims/columns.m b/src/utilities/missing/dims/columns.m
new file mode 100644
index 0000000000000000000000000000000000000000..aabfb7f2dc4075cd66bb70784fa1c46a977c5b01
--- /dev/null
+++ b/src/utilities/missing/dims/columns.m
@@ -0,0 +1,20 @@
+function c = columns(M)
+
+% Computes the number of columns of a matrix
+
+% Copyright (C) 2005-2014 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+c = size(M,2);
\ No newline at end of file
diff --git a/src/utilities/missing/dims/rows.m b/src/utilities/missing/dims/rows.m
new file mode 100644
index 0000000000000000000000000000000000000000..2abe2deb844856d0cc30705a97236a09d71ee3be
--- /dev/null
+++ b/src/utilities/missing/dims/rows.m
@@ -0,0 +1,20 @@
+function r = rows(x)
+
+% Computes the number of rows of a matrix
+
+% Copyright (C) 2005-2014 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+r = size(x,1);
diff --git a/src/utilities/missing/isint/isint.m b/src/utilities/missing/isint/isint.m
new file mode 100644
index 0000000000000000000000000000000000000000..f01a01667e5b37170b7811df1b1634b91165b745
--- /dev/null
+++ b/src/utilities/missing/isint/isint.m
@@ -0,0 +1,129 @@
+function [l,c,d] = isint(a) % --*-- Unitary tests --*--
+
+%  This function tests if the input argument is an integer.
+%
+%  INPUT
+%  - a    [double]   m*n matrix.
+%
+%  OUTPUT
+%  - l    [logical]  m*n matrix of true and false (1 and 0). l(i,j)=true if a(i,j) is an integer.
+%  - c    [integer]  p*1 vector of indices pointing to the integer elements of a.
+%  - d    [integer]  q*1 vector of indices pointing to the non integer elements of a.
+%
+%  REMARKS
+%  p+q is equal to the product of m by n.
+
+% Copyright (C) 2009-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if ~isnumeric(a)
+    l = false;
+    if nargout>1
+        c = [];
+        d = [];
+    end
+    return
+end
+
+l = abs(fix(a)-a)<1e-15;
+
+if nargout>1
+    c = find(l==true);
+    d = find(l==false);
+end
+
+%@test:1
+%$ a = 1938;
+%$ try
+%$     boolean = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ a = pi;
+%$ try
+%$     boolean = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ a = '1';
+%$ try
+%$     boolean = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ a = [1; 2; 3];
+%$ try
+%$     [boolean, iV, iF]  = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(all(boolean), true);
+%$     t(3) = dassert(isequal(iV, [1; 2; 3]), true);
+%$     t(4) = dassert(isempty(iF), true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ a = [1; pi; 3];
+%$ try
+%$     [boolean, iV, iF]  = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(all(boolean), false);
+%$     t(3) = dassert(isequal(iV, [1; 3]), true);
+%$     t(4) = dassert(isequal(iF, 2), true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
\ No newline at end of file
diff --git a/src/utilities/missing/isoctave/isoctave.m b/src/utilities/missing/isoctave/isoctave.m
new file mode 100644
index 0000000000000000000000000000000000000000..7f1b7db9226d6052812b49377fc353f08bf08b34
--- /dev/null
+++ b/src/utilities/missing/isoctave/isoctave.m
@@ -0,0 +1,20 @@
+function l = isoctave()
+
+% Tests if Octave is used.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+l = exist('OCTAVE_VERSION');
\ No newline at end of file
diff --git a/src/utilities/missing/matlab_ver_less_than/matlab_ver_less_than.m b/src/utilities/missing/matlab_ver_less_than/matlab_ver_less_than.m
new file mode 100644
index 0000000000000000000000000000000000000000..5735a54ad33dfade0afe0583d6293116725ef7fe
--- /dev/null
+++ b/src/utilities/missing/matlab_ver_less_than/matlab_ver_less_than.m
@@ -0,0 +1,29 @@
+function r = matlab_ver_less_than(verstr)
+
+% Returns 1 if current Matlab version is strictly older than the one given in argument.
+%
+% INPUTS
+% - verstr  [string]  Matlab's version as 'x.y' or 'x.y.z'
+%
+% OUTPUTS
+% - r       [logical] true or false (0 or 1)
+%
+% REMARKS
+% 1. This function will fail under Octave.
+
+% Copyright (C) 2008-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+r = verLessThan('matlab', verstr);
\ No newline at end of file
diff --git a/src/utilities/missing/shiftS/shiftS.m b/src/utilities/missing/shiftS/shiftS.m
new file mode 100644
index 0000000000000000000000000000000000000000..c62d22f194af2dfb6225ef76a3a05c0e88b964da
--- /dev/null
+++ b/src/utilities/missing/shiftS/shiftS.m
@@ -0,0 +1,58 @@
+function S = shiftS(S,n) % --*-- Unitary tests --*--
+
+% Removes the first n elements of a one dimensional cell array.
+
+% Copyright (C) 2009-2017 Dynare Team
+%
+% This code 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 dates submodule 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 <http://www.gnu.org/licenses/>.
+
+if length(S) >= n+1
+    S = S(n+1:end);
+else
+    S = {};
+end
+
+%@test:1
+%$ Cell = {'1', '2', '3'};
+%$ try
+%$     Cell = shiftS(Cell,1);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(length(Cell), 2);
+%$     t(3) = dassert(Cell, {'2', '3'});
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:1
+%$ Cell = {'1', '2', '3'};
+%$ try
+%$     Cell = shiftS(Cell,3);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(length(Cell), 0);
+%$     t(3) = dassert(isequal(Cell, {}), true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
diff --git a/src/utilities/op/add_periods_to_array_of_dates.m b/src/utilities/op/add_periods_to_array_of_dates.m
new file mode 100644
index 0000000000000000000000000000000000000000..6a2171a164b34c713e5c002a8e85d679bfb8b5e6
--- /dev/null
+++ b/src/utilities/op/add_periods_to_array_of_dates.m
@@ -0,0 +1,83 @@
+function time = add_periods_to_array_of_dates(time, freq, p)  % --*-- Unitary tests --*--
+
+% Adds a p periods (p can be negative) to a date (or a set of dates) characterized by array time and frequency freq.
+
+% Copyright (C) 2013-2017 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 <http://www.gnu.org/licenses/>.
+
+if isequal(rows(time),1) && length(p)>1
+    time = repmat(time,length(p),1);
+end
+
+time(:,1) = time(:,1) + fix(p/freq);
+time(:,2) = time(:,2) + rem(p,freq);
+
+id1 = find(time(:,2)>freq);
+if ~isempty(id1)
+    time(id1,1) = time(id1,1) + 1;
+    time(id1,2) = time(id1,2) - freq;
+end
+
+id2 = find(time(:,2)<1);
+if ~isempty(id2)
+    time(id2,1) = time(id2,1) - 1;
+    time(id2,2) = time(id2,2) + freq;
+end
+
+%@test:1
+%$ t(1) = dassert(add_periods_to_array_of_dates([1950 1], 4, 1),[1950 2]);
+%$ t(2) = dassert(add_periods_to_array_of_dates([1950 1], 4, 2),[1950 3]);
+%$ t(3) = dassert(add_periods_to_array_of_dates([1950 1], 4, 3),[1950 4]);
+%$ t(4) = dassert(add_periods_to_array_of_dates([1950 1], 4, 4),[1951 1]);
+%$ t(5) = dassert(add_periods_to_array_of_dates([1950 1], 4, 5),[1951 2]);
+%$ t(6) = dassert(add_periods_to_array_of_dates([1950 1], 4, 6),[1951 3]);
+%$ t(7) = dassert(add_periods_to_array_of_dates([1950 1], 4, 7),[1951 4]);
+%$ t(8) = dassert(add_periods_to_array_of_dates([1950 1], 4, 8),[1952 1]);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ t(1) = dassert(add_periods_to_array_of_dates(repmat([1950 1],8,1), 4, transpose(1:8)),[1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4; 1952 1]);
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ t(1) = dassert(add_periods_to_array_of_dates([1950 1], 1, 1),[1951 1]);
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ t(1) = dassert(add_periods_to_array_of_dates([1950 1; 1950 2; 1950 3; 1950 4], 4, 1),[1950 2; 1950 3; 1950 4; 1951 1]);
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ t(1) = dassert(add_periods_to_array_of_dates([1950 1], 4, transpose(1:8)),[1950 2; 1950 3; 1950 4; 1951 1; 1951 2; 1951 3; 1951 4; 1952 1]);
+%$ T = all(t);
+%@eof:5
+
+%@test:6
+%$ t(1) = dassert(add_periods_to_array_of_dates([1950 1], 4, -1),[1949 4]);
+%$ t(2) = dassert(add_periods_to_array_of_dates([1950 1], 4, -2),[1949 3]);
+%$ t(3) = dassert(add_periods_to_array_of_dates([1950 1], 4, -3),[1949 2]);
+%$ t(4) = dassert(add_periods_to_array_of_dates([1950 1], 4, -4),[1949 1]);
+%$ t(5) = dassert(add_periods_to_array_of_dates([1950 1], 4, -5),[1948 4]);
+%$ t(6) = dassert(add_periods_to_array_of_dates([1950 1], 4, -6),[1948 3]);
+%$ t(7) = dassert(add_periods_to_array_of_dates([1950 1], 4, -7),[1948 2]);
+%$ t(8) = dassert(add_periods_to_array_of_dates([1950 1], 4, -8),[1948 1]);
+%$ T = all(t);
+%@eof:6
\ No newline at end of file
diff --git a/src/utilities/op/add_periods_to_date.m b/src/utilities/op/add_periods_to_date.m
new file mode 100644
index 0000000000000000000000000000000000000000..6cfee337d206b49f6fa23c325a433941b412b0eb
--- /dev/null
+++ b/src/utilities/op/add_periods_to_date.m
@@ -0,0 +1,57 @@
+function time = add_periods_to_date(time, freq, p)  % --*-- Unitary tests --*--
+
+% Adds a p periods (p can be negative) to a date (or a set of dates) characterized by array time and frequency freq.
+
+% Copyright (C) 2013-2017 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 <http://www.gnu.org/licenses/>.
+
+time(1) = time(1) + fix(p/freq);
+time(2) = time(2) + rem(p,freq);
+
+if time(2)>freq
+    time(1) = time(1) + 1;
+    time(2) = time(2) - freq;
+end
+
+if time(2)<1
+    time(1) = time(1) - 1;
+    time(2) = time(2) + freq;
+end
+
+%@test:1
+%$ t(1) = dassert(add_periods_to_date([1950 1], 4, 1),[1950 2]);
+%$ t(2) = dassert(add_periods_to_date([1950 1], 4, 2),[1950 3]);
+%$ t(3) = dassert(add_periods_to_date([1950 1], 4, 3),[1950 4]);
+%$ t(4) = dassert(add_periods_to_date([1950 1], 4, 4),[1951 1]);
+%$ t(5) = dassert(add_periods_to_date([1950 1], 4, 5),[1951 2]);
+%$ t(6) = dassert(add_periods_to_date([1950 1], 4, 6),[1951 3]);
+%$ t(7) = dassert(add_periods_to_date([1950 1], 4, 7),[1951 4]);
+%$ t(8) = dassert(add_periods_to_date([1950 1], 4, 8),[1952 1]);
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ t(1) = dassert(add_periods_to_date([1950 1], 4, -1),[1949 4]);
+%$ t(2) = dassert(add_periods_to_date([1950 1], 4, -2),[1949 3]);
+%$ t(3) = dassert(add_periods_to_date([1950 1], 4, -3),[1949 2]);
+%$ t(4) = dassert(add_periods_to_date([1950 1], 4, -4),[1949 1]);
+%$ t(5) = dassert(add_periods_to_date([1950 1], 4, -5),[1948 4]);
+%$ t(6) = dassert(add_periods_to_date([1950 1], 4, -6),[1948 3]);
+%$ t(7) = dassert(add_periods_to_date([1950 1], 4, -7),[1948 2]);
+%$ t(8) = dassert(add_periods_to_date([1950 1], 4, -8),[1948 1]);
+%$ T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/tests/runalltests.m b/tests/runalltests.m
new file mode 100644
index 0000000000000000000000000000000000000000..35194e231efbf1d5618bf60da27d07512e2e817b
--- /dev/null
+++ b/tests/runalltests.m
@@ -0,0 +1,58 @@
+function runalltests()
+
+% Copyright (C) 2015-2018 Dynare Team
+%
+% This code 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 dseries submodule 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 <http://www.gnu.org/licenses/>.
+
+dates_src_root = []; % Initialize path as an array to be updated
+                     % when calling initialize_dseries_toolbox() script.
+
+opath = path();
+
+system('rm -f failed');
+system('rm -f pass');
+
+% Initialize m-unit-test submodule
+try
+    initialize_unit_tests_toolbox;
+catch
+    error('Missing dependency: m-unit-tests module is not available.')
+end
+
+% Initialize the dates submodule
+try
+    initialize_dates_toolbox;
+catch
+    unit_tests_root = strrep(which('runalltests'),'runalltests.m','');
+    addpath([unit_tests_root '../src']);
+    initialize_dates_toolbox;
+end
+
+if isoctave
+    more off;
+end
+
+r = run_unitary_tests_in_directory(dates_src_root(1:end-1));
+
+delete('*.log');
+
+if any(~[r{:,3}])
+    system('touch failed');
+else
+    system('touch pass');
+end
+
+path(opath);
+
+display_report(r);
\ No newline at end of file