diff --git a/src/@dates/append_.m b/src/@dates/append_.m
index ba5b03eaecd8b0e96a0ce336525d06e6bf6a6c19..398f0325899c65b2794e084c7eb57df055972763 100644
--- a/src/@dates/append_.m
+++ b/src/@dates/append_.m
@@ -228,4 +228,28 @@ catch
 end
 
 T = all(t);
-%@eof:8
\ No newline at end of file
+%@eof:8
+
+%@test:9
+% Define some dates
+B1 = '2020W1';
+B2 = '2020W2';
+B3 = '2020W3';
+B4 = '2020W4';
+
+% Call the tested routine.
+try
+    d1 = dates(B1,B2,B3);
+    d2 = dates(B4);
+    d1.append_(d2);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = isequal(d1, dates(B1, B2, B3, B4));
+end
+
+T = all(t);
+%@eof:9
\ No newline at end of file
diff --git a/src/@dates/char.m b/src/@dates/char.m
index 864df76b50b13a5b9b9355920157a7fa360dc97d..b68b2e1c3cc9e78422e4784ea98fbd71fb1d1a12 100644
--- a/src/@dates/char.m
+++ b/src/@dates/char.m
@@ -8,7 +8,7 @@ function s = char(o) % --*-- Unitary tests --*--
 % OUTPUTS
 % - s  [string]
 
-% Copyright © 2014-2020 Dynare Team
+% Copyright © 2014-2021 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
@@ -119,4 +119,22 @@ if t(1)
     t(2) = isequal(str,'1950Y');
 end
 T = all(t);
-%@eof:5
\ No newline at end of file
+%@eof:5
+
+%@test:6
+% Define a dates object
+o = dates('1950W1');
+
+% Call the tested routine.
+try
+    str = char(o);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = isequal(str,'1950W1');
+end
+T = all(t);
+%@eof:6
diff --git a/src/@dates/dates.m b/src/@dates/dates.m
index fcc95b6aa783d93de46fb723a59a738dc3eaf39a..ee5d93d49a4c9132782e050aa34beaf9f560b37b 100644
--- a/src/@dates/dates.m
+++ b/src/@dates/dates.m
@@ -66,10 +66,23 @@ methods
             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}(:)*o.freq+varargin{3}(:);
+                    if o.freq==52
+                        if all(varargin{3}>=1)
+                            if any(islongyear(varargin{2}(:))) && any(varargin{3}(islongyear(varargin{2}(:)))>53)
+                                error('dates:ArgCheck', 'Third input specifies non existing ISO weeks (argument cannot be greater than 53).')
+                            end
+                            if any(~islongyear(varargin{2}(:))) && any(varargin{3}(~islongyear(varargin{2}(:)))>52)
+                                error('dates:ArgCheck', 'Third input specifies non existing ISO weeks (argument cannot be greater than 52 except in long years).')
+                            end
+                        else
+                            error('dates:ArgCheck', 'Third input must contain strictly positive integers.')
+                        end
                     else
-                        error('dates:ArgCheck', 'Third input must contain integers between 1 and %i.', o.freq)
+                        if all(varargin{3}>=1) && all(varargin{3}<=o.freq)
+                            o.time = varargin{2}(:)*o.freq+varargin{3}(:);
+                        else
+                            error('dates:ArgCheck', 'Third input must contain integers between 1 and %i.', o.freq)
+                        end
                     end
                 else
                     error('dates:ArgCheck', 'Third input must be a vector of integers.')
diff --git a/src/@dates/double.m b/src/@dates/double.m
index 1470c5c754aa465c7a7ab31896b8a675e0499016..8a96eed5519352041afb4b8decf9fa3758c61fee 100644
--- a/src/@dates/double.m
+++ b/src/@dates/double.m
@@ -28,9 +28,9 @@ function [m, f]  = double(o) % --*-- Unitary tests --*--
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
-if o.freq==365
+if o.freq==365 || o.freq==52
     error('This method is not implemented for daily frequency.')
-    % Would need to find a way to deal with leap years
+    % Would need to find a way to deal with leap years and long years.
 end
 
 if o.freq == 1
diff --git a/src/utilities/convert/date2string.m b/src/utilities/convert/date2string.m
index 623b28e89cfe5e9d397107ddf84d3e725308adce..47a40e25709c40355d1ed5f7f6bb424ef100d9cb 100644
--- a/src/utilities/convert/date2string.m
+++ b/src/utilities/convert/date2string.m
@@ -27,6 +27,8 @@ function s = date2string(varargin) % --*-- Unitary tests --*--
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
+Eschaton = 10000; % End time
+
 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!'])
@@ -37,7 +39,7 @@ if isequal(nargin, 1)
 end
 
 if isequal(nargin, 2)
-    if ~isscalar(varargin{2}) || ~isint(varargin{2}) || ~ismember(varargin{2}, [1 2 4 12 365])
+    if ~isscalar(varargin{2}) || ~isint(varargin{2}) || ~ismember(varargin{2}, [1 2 4 12 52 365])
         error('Second input argument must be an integer scalar equal to 1, 2, 4, 12, or 365 (frequency).')
     end
     freq = varargin{2};
@@ -51,6 +53,22 @@ if freq==365
     s = datestr(time(1), 'yyyy-mm-dd');
 elseif freq==1
     s = sprintf('%iY', time);
+elseif freq==52
+    t0 = cumsum(transpose(islongyear(0:Eschaton))+52);
+    t1 = find(t0<=time, true, 'last');
+    if isempty(t1)
+        year = 0;
+        subperiod = time;
+    else
+        if time==t0(t1)
+            year = t1-1;
+            subperiod = 52+islongyear(year);
+        else
+            year = t1;
+            subperiod = time-t0(t1);
+        end
+    end
+    s = sprintf('%iW%i', year, subperiod);
 else
     year = floor((time-1)/freq);
     subperiod = time-year*freq;
diff --git a/src/utilities/convert/freq2string.m b/src/utilities/convert/freq2string.m
index a3b90f0dc35e646d91bcbbd2698ed886237dc41e..249abded5e2c253c6541aca237612ab22989e76d 100644
--- a/src/utilities/convert/freq2string.m
+++ b/src/utilities/convert/freq2string.m
@@ -1,10 +1,10 @@
 function s = freq2string(freq) % --*-- Unitary tests --*--
 
 % INPUTS
-% - freq  [integer]   scalar equal to 1, 2, 4, 12, or 365 (resp. annual, bi-annual, quaterly, monthly, or daily)
+% - freq  [integer]   scalar equal to 1, 2, 4, 12, 52, or 365 (resp. annual, bi-annual, quaterly, monthly, weekly, or daily)
 %
 % OUTPUTS
-% - s     [char]      scalar equal to Y, S, Q, M, or D (resp. annual, bi-annual, quaterly, monthly, or daily)
+% - s     [char]      scalar equal to Y, S, Q, M, W, or D (resp. annual, bi-annual, quaterly, monthly, weekly, or daily)
 
 % Copyright © 2013-2021 Dynare Team
 %
@@ -32,6 +32,8 @@ switch freq
     s = 'Q';
   case 12
     s = 'M';
+  case 52
+    s = 'W';
   case 365
     s = 'D';
   otherwise
@@ -46,6 +48,7 @@ try
     strH = freq2string(2);
     strQ = freq2string(4);
     strM = freq2string(12);
+    strW = freq2string(52);
     strD = freq2string(365);
     t(1) = true;
 catch
@@ -57,6 +60,7 @@ if t(1)
     t(3) = isequal(strH, 'S');
     t(4) = isequal(strQ, 'Q');
     t(5) = isequal(strM, 'M');
+    t(6) = isequal(strW, 'W');
     t(6) = isequal(strD, 'D');
 end
 
diff --git a/src/utilities/convert/string2date.m b/src/utilities/convert/string2date.m
index 718397bd56bd7791f507d131ee54c2d82a45005a..c3ce5deb03af63bbf490f03d5d9dbded4e6cbd5a 100644
--- a/src/utilities/convert/string2date.m
+++ b/src/utilities/convert/string2date.m
@@ -51,6 +51,13 @@ if ismonthly(a)
     return
 end
 
+if isweekly(a)
+    period = cellfun(@str2double, strsplit(a, {'W','w'}));
+    date.freq = 52;
+    date.time = weeksince(period(1), period(2));
+    return
+end
+
 if isdaily(a)
     date.freq = 365;
     date.time(1) = datenum(a, 'yyyy-mm-dd');
diff --git a/src/utilities/is/isdate.m b/src/utilities/is/isdate.m
index 673a1bcc42f835fa7b3aae2f7da702731de5dea3..41ba5e9e3412c37d1350b71a851b502809be21f0 100644
--- a/src/utilities/is/isdate.m
+++ b/src/utilities/is/isdate.m
@@ -8,7 +8,7 @@ function b = isdate(str)  % --*-- Unitary tests --*--
 % OUTPUTS
 % - b       [logical]   scalar equal to true iff str can be interpreted as a date.
 
-% Copyright © 2013-2020 Dynare Team
+% Copyright © 2013-2021 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -43,18 +43,20 @@ date_5 = ' 1950';
 date_6 = '1950Y';
 date_7 = '-1950a';
 date_8 = '1950m ';
-date_9 = '2000-01-01';
-date_10 = '2000-02-30';
+date_9 = '1950w50';
+date_10 = '2000-01-01';
+date_11 = '2000-02-30';
 
-t(1) = isequal(isdate(date_1), true);
-t(2) = isequal(isdate(date_2), true);
-t(3) = isequal(isdate(date_3), true);
-t(4) = isequal(isdate(date_4), false);
-t(5) = isequal(isdate(date_5), false);
-t(6) = isequal(isdate(date_6), true);
-t(7) = isequal(isdate(date_7), true);
-t(8) = isequal(isdate(date_8), false);
-t(9) = isequal(isdate(date_9), true);
-t(10) = isequal(isdate(date_10), false);
+t(1) = isdate(date_1);
+t(2) = isdate(date_2);
+t(3) = isdate(date_3);
+t(4) = ~isdate(date_4);
+t(5) = ~isdate(date_5);
+t(6) = isdate(date_6);
+t(7) = isdate(date_7);
+t(8) = ~isdate(date_8);
+t(9) = isdate(date_9);
+t(10) = isdate(date_10);
+t(11) = ~isdate(date_11);
 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
index 005156aa70320fddc511a3f8f28c7ec37422ae12..e781dddae4579a383e502436fcd7fb8f7315a577 100644
--- a/src/utilities/is/isdates.m
+++ b/src/utilities/is/isdates.m
@@ -96,4 +96,19 @@ if t(1)
 end
 
 T = all(t);
-%@eof:5
\ No newline at end of file
+%@eof:5
+
+%@test:6
+try
+    boolean = isdates('1938W11');
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = dassert(boolean, false);
+end
+
+T = all(t);
+%@eof:6
\ No newline at end of file
diff --git a/src/utilities/is/isfreq.m b/src/utilities/is/isfreq.m
index 6344945c3cfba49cfd20a65dfafae00172423ac9..af117ad859c327853aa151940c772bd961082fe4 100644
--- a/src/utilities/is/isfreq.m
+++ b/src/utilities/is/isfreq.m
@@ -8,7 +8,7 @@ function B = isfreq(A) % --*-- Unitary tests --*--
 % OUTPUTS
 % - B     [logical]        scalar equal to true iff A can be interpreted as a frequency.
 
-% Copyright © 2013-2020 Dynare Team
+% Copyright © 2013-2021 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -28,7 +28,7 @@ function B = isfreq(A) % --*-- Unitary tests --*--
 B = false;
 
 if ischar(A)
-    if isequal(length(A),1) && ismember(upper(A),{'Y','A', 'H', 'Q', 'M', 'D'})
+    if isequal(length(A),1) && ismember(upper(A),{'Y','A', 'H', 'Q', 'M', 'W', 'D'})
         B = true;
         return
     end
@@ -113,4 +113,19 @@ if t(1)
 end
 
 T = all(t);
-%@eof:5
\ No newline at end of file
+%@eof:5
+
+%@test:6
+try
+    b = isfreq('W') && isfreq(52);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = b;
+end
+
+T = all(t);
+%@eof:6
\ No newline at end of file
diff --git a/src/utilities/is/isleapyear.m b/src/utilities/is/isleapyear.m
index 0a51259dc315f8015eac9a0c1fd7c9dca35bdbcc..ae3a984ad5194faac7fc536438cca39a6cdbfc82 100644
--- a/src/utilities/is/isleapyear.m
+++ b/src/utilities/is/isleapyear.m
@@ -26,6 +26,11 @@ function b = isleapyear(y) % --*-- Unitary tests --*--
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
+if isempty(y)
+    b = false;
+    return
+end
+
 if isnumeric(y) && isvector(y) && all(isint(y))
     b = mod(y,4)==0 & ( mod(y, 100)~=0 | mod(y, 400)==0 );
 else
diff --git a/src/utilities/is/islongyear.m b/src/utilities/is/islongyear.m
new file mode 100644
index 0000000000000000000000000000000000000000..22de544ea41a1fe3f37b46633548ac42e677ccde
--- /dev/null
+++ b/src/utilities/is/islongyear.m
@@ -0,0 +1,72 @@
+function b = islongyear(y) % --*-- Unitary tests --*--
+
+% Returns true iff y is a year with 53 weeks.
+%
+% INPUTS
+% - y     [integer]     scalar or vector, year(s).
+%
+% OUTPUTS
+% - b     [logical]     scalar or vector, equal to true iff y is a leap year.
+
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+b = mod(y+fix(y/4)-fix(y/100)+fix(y/400),7)==4 | mod(y-1+fix((y-1)/4)-fix((y-1)/100)+fix((y-1)/400),7)==3;
+
+return
+
+%@test:1
+Years = [4; 9 ; 15 ; 20 ; 26 ; 32 ; 37 ; 43 ; 48 ; 54 ; 60 ; 65 ; 71 ; 76 ; 82 ; 88 ; 93 ; 99 ;
+         105 ; 111 ; 116 ; 122 ; 128 ; 133 ; 139 ; 144 ; 150 ; 156 ; 161 ; 167 ; 172 ; 178 ; 184 ; 189 ; 195 ;
+         201 ; 207 ; 212 ; 218 ; 224 ; 229 ; 235 ; 240 ; 246 ; 252 ; 257 ; 263 ; 268 ; 274 ; 280 ; 285 ; 291 ; 296 ;
+         303 ; 308 ; 314 ; 320 ; 325 ; 331 ; 336 ; 342 ; 348 ; 353 ; 359 ; 364 ; 370 ; 376 ; 381 ; 387 ; 392 ; 398];
+try
+    ly = islongyear(Years);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = all(ly);
+end
+
+T = all(t);
+%@eof:1
+
+%@test:2
+LongYears = [4; 9 ; 15 ; 20 ; 26 ; 32 ; 37 ; 43 ; 48 ; 54 ; 60 ; 65 ; 71 ; 76 ; 82 ; 88 ; 93 ; 99 ;
+             105 ; 111 ; 116 ; 122 ; 128 ; 133 ; 139 ; 144 ; 150 ; 156 ; 161 ; 167 ; 172 ; 178 ; 184 ; 189 ; 195 ;
+             201 ; 207 ; 212 ; 218 ; 224 ; 229 ; 235 ; 240 ; 246 ; 252 ; 257 ; 263 ; 268 ; 274 ; 280 ; 285 ; 291 ; 296 ;
+             303 ; 308 ; 314 ; 320 ; 325 ; 331 ; 336 ; 342 ; 348 ; 353 ; 359 ; 364 ; 370 ; 376 ; 381 ; 387 ; 392 ; 398];
+
+Years = setdiff(1:400, LongYears);
+
+try
+    ly = islongyear(Years);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = all(~ly);
+end
+
+T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/utilities/is/isstringdate.m b/src/utilities/is/isstringdate.m
index 9f780d4e147e155b45e908f8dfc4a876eef92ea0..d025b2f285709c71cea8d6d217213ef733bf9ff6 100644
--- a/src/utilities/is/isstringdate.m
+++ b/src/utilities/is/isstringdate.m
@@ -8,7 +8,7 @@ function b = isstringdate(str)  % --*-- Unitary tests --*--
 % OUTPUTS
 %  o b       integer scalar, equal to 1 if str can be interpreted as a date or 0 otherwise.
 
-% Copyright (C) 2013-2020 Dynare Team
+% Copyright (C) 2013-2021 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -26,7 +26,7 @@ function b = isstringdate(str)  % --*-- Unitary tests --*--
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
 if ischar(str)
-    b = isquarterly(str) || isyearly(str) || isbiannual(str) || ismonthly(str) || isdaily(str);
+    b = isquarterly(str) || isyearly(str) || isbiannual(str) || ismonthly(str) || isweekly(str) || isdaily(str);
 else
     b = false;
 end
@@ -53,6 +53,7 @@ date_16 = '1948H1';
 date_17 = 'h2';
 date_18 = '1948-02-12';
 date_19 = '12-30';
+date_20 = '1950W2';
 
 t(1) = isstringdate(date_1);
 t(2) = isstringdate(date_2);
@@ -71,8 +72,9 @@ t(14) = ~isstringdate(date_14);
 t(15) = ~isstringdate(date_15);
 t(16) = isstringdate(date_16);
 t(17) = ~isstringdate(date_17);
-t(16) = isstringdate(date_18);
-t(17) = ~isstringdate(date_19);
+t(18) = isstringdate(date_18);
+t(19) = ~isstringdate(date_19);
+t(20) = isstringdate(date_20);
 
 T = all(t);
 %@eof:1
\ 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..75f31debb3ea7007e6817fc651396cd221a4b99a
--- /dev/null
+++ b/src/utilities/is/isweekly.m
@@ -0,0 +1,74 @@
+function b = isweekly(str)  % --*-- Unitary tests --*--
+
+% Tests if the input can be interpreted as a monthly date.
+%
+% INPUTS
+%  o str     string.
+%
+% OUTPUTS
+%  o b       logical scalar, equal to true if str can be interpreted as a weekly date or false otherwise.
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+if ischar(str)
+    if isempty(regexp(str,'^-?[0-9]+[Ww]([1-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-3])$','once'))
+        b = false;
+        return
+    else
+        b = true;
+    end
+else
+    b = false;
+    return
+end
+
+% TODO Also test w.r.t. the number of weeks in a year.
+if b
+    period = cellfun(@str2double, strsplit(str, {'W','w'}));
+    if isequal(period(2), 0) || period(2)>(52+islongyear(period(1)))
+        b = false;
+    end
+end
+
+
+return
+
+%@test:1
+date_1 = '1950M2';
+date_2 = '1950W2';
+date_3 = '-1950w2';
+date_4 = '1950W52';
+date_5 = '1950 azd ';
+date_6 = '1950Y';
+date_7 = '1950Q3';
+date_8 = '1950m24';
+date_9 = '2003W53';
+date_10 = '2004W53';
+
+t(1) = ~isweekly(date_1);
+t(2) = isweekly(date_2);
+t(3) = isweekly(date_3);
+t(4) = isweekly(date_4);
+t(5) = ~isweekly(date_5);
+t(6) = ~isweekly(date_6);
+t(7) = ~isweekly(date_7);
+t(8) = ~isweekly(date_8);
+t(9) = ~isweekly(date_9);
+t(10) = isweekly(date_10);
+T = all(t);
+%@eof:1
\ No newline at end of file
diff --git a/src/utilities/misc/firstdayofyear.m b/src/utilities/misc/firstdayofyear.m
new file mode 100644
index 0000000000000000000000000000000000000000..6eff5b25fc5b2ba8fcfc74d76d013ceb1ad00b51
--- /dev/null
+++ b/src/utilities/misc/firstdayofyear.m
@@ -0,0 +1,75 @@
+function daycode = firstdayofyear(y) % --*-- Unitary tests --*--
+
+% Returns the first day of year y.
+%
+% INPUTS
+% - y           [integer]     scalar or vector, year(s).
+%
+% OUTPUTS
+% - daycode     [integer]     scalar or vector.
+%
+% REMARKS
+% Days are encoded as follows:
+%
+%   1 -> Monday
+%   2 -> Tuesday
+%   3 -> Wednesday
+%   4 -> Thursday
+%   5 -> Friday
+%   6 -> Saturday
+%   7 -> Sunday
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+daycode = mod(1+5*mod(y-1,4)+4*mod(y-1,100)+6*mod(y-1,400), 7);
+
+% Monday is the first day of the week acoording to ISO-8607
+id = (daycode==0);
+daycode(id) = 7;
+
+return
+
+%@test:1
+try
+    dc = firstdayofyear(2000);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = dc==6;
+end
+
+T = all(t);
+%@eof:1
+
+%@test:2
+try
+    dc = firstdayofyear([2001;2002]);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = isequal(dc, [1;2]);
+end
+
+T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/utilities/misc/firstweekofyear.m b/src/utilities/misc/firstweekofyear.m
new file mode 100644
index 0000000000000000000000000000000000000000..3455144ef2347a641fef96f3b144856bb4ff035b
--- /dev/null
+++ b/src/utilities/misc/firstweekofyear.m
@@ -0,0 +1,91 @@
+function [d, m, y] = firstweekofyear(y) % --*-- Unitary tests --*--
+
+% Returns the month and day the first week of the year.
+%
+% INPUTS 
+% - y   [integer] the year.
+%
+% OUTPUS 
+% - y   [integer] the year of the first iso-8601 week of year y (may be equal to y-1)
+% - m   [integer] the month number (1 or 12)
+% - d   [integer] the day of the month.
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+d = firstdayofyear(y);
+
+m = ones(length(d), 1);
+
+id = d==2 | d==3 | d==4;
+if any(id)
+    % Tuesday, Wednesday, or Thursday
+    m(id) = 12;
+    y(id) = y(id)-1;
+    d(id) = 33-d(id);
+end
+
+id = d==5 | d==6 | d==7;
+if any(id)
+    % Friday, Saturday, or Sunday
+    d(id) = 9-d(id);
+end
+
+return
+
+%@test:1
+t = false(2,1);
+
+try
+    [d, m, y] = firstweekofyear(1971);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = d==4;
+end
+
+T = all(t);
+%@eof:1
+
+
+%@test:2
+t = false(10,1);
+
+try
+    [d, m, y] = firstweekofyear([1972;1973;1974]);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = d(1)==3;
+    t(3) = d(2)==1;
+    t(4) = d(3)==31;
+    t(5) = m(1)==1;
+    t(6) = m(2)==1;
+    t(7) = m(3)==12;
+    t(8) = y(1)==1972;
+    t(9) = y(2)==1973;
+    t(10) = y(3)==1973;    
+end
+
+T = all(t);
+%@eof:2
\ No newline at end of file
diff --git a/src/utilities/misc/longyearsince.m b/src/utilities/misc/longyearsince.m
new file mode 100644
index 0000000000000000000000000000000000000000..d305c2340e45c1a2e1795f2f335a2ac758a508fa
--- /dev/null
+++ b/src/utilities/misc/longyearsince.m
@@ -0,0 +1,39 @@
+function n = longyearsince(y, z)
+
+% Returns the number of long years since base year z.
+%
+% INPUTS 
+% - y   [integer] scalar or vector, the year.
+% - z   [integer] scalar, base year (default is 0).
+%
+% OUTPUTS 
+% - n   [integer] scalar or vector, number of long years.
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+if nargin<2
+    z = 0; % Default value for base year.
+end
+
+n = zeros(length(y), 1);
+
+for i=1:length(y)
+    if y(i)>=z
+        n(i) = sum(islongyear(z:y));
+    end
+end
\ No newline at end of file
diff --git a/src/utilities/misc/ordinal.m b/src/utilities/misc/ordinal.m
new file mode 100644
index 0000000000000000000000000000000000000000..afc4446f987ca1b5236f525cafae5f86c5e9283a
--- /dev/null
+++ b/src/utilities/misc/ordinal.m
@@ -0,0 +1,55 @@
+function o = ordinalinyear(y, m, d)
+
+% Returns the ordinal date (day number in current year).
+%
+% INPUTS 
+% - y   [integer] scalar or vector, the year.
+% - m   [integer] scalar or vector, the month.
+% - d   [integer] scalar or vector, the day in a month.
+%
+% OUTPUS 
+% - o   [integer] scalar or vector, day number in year y.
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+D = [31; 28; 31; 30; 31; 30; 31; 31; 30; 31; 30]; % Number of days in January, February, ..., November
+
+if ~(isvector(y) && isvector(m) && isvector(d)) || ~(isint(y) && isint(m) && isint(d))
+    error('Arguments must be vectors of integers.')
+end
+
+if ~(length(y)==length(m) && length(y)==length(d))
+    error('Arguments must have same lengths.')
+end
+
+o = zeros(length(y), 1);
+
+for i=1:length(o)
+    o(i) = d(i) + days(y(i), m(i));
+end
+
+function d = days(y, m)
+    if m>1
+        d = cumsum(D(1:m-1));
+    else
+        d = 0;
+    end
+    if m>2
+        d = d + isleapyear(y);
+    end
+end
\ No newline at end of file
diff --git a/src/utilities/misc/ordinalinisoyear.m b/src/utilities/misc/ordinalinisoyear.m
new file mode 100644
index 0000000000000000000000000000000000000000..4f82289fab09d95a5448f718d9d357a2d93c3dde
--- /dev/null
+++ b/src/utilities/misc/ordinalinisoyear.m
@@ -0,0 +1,74 @@
+function o = ordinalinisoyear(y, m, d)
+
+% Returns the ordinal date (day number in current year).
+%
+% INPUTS 
+% - y   [integer] scalar or vector, the year.
+% - m   [integer] scalar or vector, the month.
+% - d   [integer] scalar or vector, the day in a month.
+%
+% OUTPUTS 
+% - o   [integer] scalar or vector, day number in year y.
+%
+% REMARKS 
+% odinalinyear(2000,1,1) returns 1.
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+D = [31; 28; 31; 30; 31; 30; 31; 31; 30; 31; 30; 31]; % Number of days in January, February, ..., December (for a non leap year)
+
+if ~(isvector(y) && isvector(m) && isvector(d)) || ~(isint(y) && isint(m) && isint(d))
+    error('Arguments must be vectors of integers.')
+end
+
+if ~(length(y)==length(m) && length(y)==length(d))
+    error('Arguments must have same lengths.')
+end
+
+if any(m>12) || any(m<1)
+    error('Second argument must be an integer between 1 and 12 (month).')
+end
+
+if any(d<1)
+    error('Third argument must be a positive integer (day).')
+end
+
+id = m==2; % February requires a special treatment.
+
+if any(d(~id)>D(m(~id))) || any(d(id)>28+isleapyear(y(id)))
+    error('Dates are wrong (third argument cannot be greater than 28, 29, 30 or 31 depending on the value of the second argument).')
+end
+
+o = zeros(length(y), 1);
+
+for i=1:length(o)
+    o(i) = d(i) + days(y(i), m(i));
+end
+
+function n = days(y, m)
+    if m>1
+        n = sum(D(1:m-1));
+    else
+        n = 0;
+    end
+    if m>2
+        n = n + isleapyear(y);
+    end
+end
+
+end
\ No newline at end of file
diff --git a/src/utilities/misc/ordinalinyear.m b/src/utilities/misc/ordinalinyear.m
new file mode 100644
index 0000000000000000000000000000000000000000..44d78b3d941fd0f5cc826a34585cd778c966ef19
--- /dev/null
+++ b/src/utilities/misc/ordinalinyear.m
@@ -0,0 +1,74 @@
+function o = ordinalinyear(y, m, d)
+
+% Returns the ordinal date (day number in current year).
+%
+% INPUTS 
+% - y   [integer] scalar or vector, the year.
+% - m   [integer] scalar or vector, the month.
+% - d   [integer] scalar or vector, the day in a month.
+%
+% OUTPUTS 
+% - o   [integer] scalar or vector, day number in year y.
+%
+% REMARKS 
+% odinalinyear(2000,1,1) returns 1.
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+D = [31; 28; 31; 30; 31; 30; 31; 31; 30; 31; 30; 31]; % Number of days in January, February, ..., December (for a non leap year)
+
+if ~(isvector(y) && isvector(m) && isvector(d)) || ~(isint(y) && isint(m) && isint(d))
+    error('Arguments must be vectors of integers.')
+end
+
+if ~(length(y)==length(m) && length(y)==length(d))
+    error('Arguments must have same lengths.')
+end
+
+if any(m>12) || any(m<1)
+    error('Second argument must be an integer between 1 and 12 (month).')
+end
+
+if any(d<1)
+    error('Third argument must be a positive integer (day).')
+end
+
+id = m==2; % February requires a special treatment.
+
+if any(d(~id)>D(m(~id))) || any(d(id)>28+isleapyear(y(id)))
+    error('Dates are wrong (third argument cannot be greater than 28, 29, 30 or 31 depending on the value of the second argument).')
+end
+
+o = zeros(length(y), 1);
+
+for i=1:length(o)
+    o(i) = d(i) + days(y(i), m(i));
+end
+
+function n = days(y, m)
+    if m>1
+        n = sum(D(1:m-1));
+    else
+        n = 0;
+    end
+    if m>2
+        n = n + isleapyear(y);
+    end
+end
+
+end
\ No newline at end of file
diff --git a/src/utilities/misc/weeksince.m b/src/utilities/misc/weeksince.m
new file mode 100644
index 0000000000000000000000000000000000000000..830d347ebbd749f7bad879a75d13432e34a1051e
--- /dev/null
+++ b/src/utilities/misc/weeksince.m
@@ -0,0 +1,119 @@
+function o = weeksince(y, w, z) % --*-- Unitary tests --*--
+
+% Returns the number of ISO weeks since base year z.
+%
+% INPUTS 
+% - y   [integer] scalar or vector, the year.
+% - w   [integer] scalar or vector, the week.
+% - z   [integer] scalar, base year.
+%
+% OUTPUTS 
+% - o   [integer] scalar or vector, number of weeks.
+
+% Copyright © 2021 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 <https://www.gnu.org/licenses/>.
+
+if nargin<3
+    z = 0; % Default value for base year.
+end
+
+n = zeros(length(y), 1);
+
+id = y-1>=z;
+
+if ~isempty(id)
+    n(id) = longyearsince(y(id)-1, z);
+end
+
+o = 52*(y-z)+n+w;
+
+return
+
+%@test:1
+try
+    w = weeksince(2001, 1, 2000);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = w==53;
+end
+
+T = all(t);
+%@eof:1
+
+%@test:2
+try
+    w = weeksince(2002, 1, 2000);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = w==105;
+end
+
+T = all(t);
+%@eof:2
+
+%@test:3
+try
+    w = weeksince(2003, 1, 2000);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = w==157;
+end
+
+T = all(t);
+%@eof:3
+
+%@test:4
+try
+    w = weeksince(2004, 1, 2000);
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = w==209;
+end
+
+T = all(t);
+%@eof:4
+
+%@test:5
+try
+    w = weeksince(2005, 1, 2000); % 2004 is a long year (53 weeks).
+    t(1) = true;
+catch
+    t(1) = false;
+end
+
+if t(1)
+    t(2) = w==262;
+end
+
+T = all(t);
+%@eof:5
\ No newline at end of file