/usr/share/octave/packages/financial-0.4.0/nweekdate.m is in octave-financial 0.4.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | ## Copyright (C) 2008 Bill Denney <bill@denney.ws>
##
## This program 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.
##
## This program 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
## this program; if not, see <http://www.gnu.org/licenses/>.
## -*- texinfo -*-
## @deftypefn {Function File} {last =} nweekdate (n, weekday, year, month, nextday)
##
## Returns the @var{n}th occurrence of @var{weekday} from the
## @var{month} and @var{year}. If the optional @var{nextday} argument
## is given, then the week must also contain @var{nextday}. If @var{n}
## is greater than the number of occurrences of that day in the month, 0
## is returned.
##
## @seealso{eomdate, lweekdate, weekday}
## @end deftypefn
function t = nweekdate (varargin)
if nargin < 4 || nargin > 5
error ("4 or 5 input arguments are required")
elseif nargin == 4
varargin{5} = 0;
endif
## special handling so that most of this code will not need to be
## duplicated in lweekdate
do_lweekdate = is_lweekdate(varargin{1});
if do_lweekdate
varargin{1} = 1;
endif
scale = cellfun (@numel, varargin);
if ~ all (scale == 1 | scale == max(scale));
error("All inputs must be either scalars or have the same number of elements");
else
## make sure that the sizes are the same for any non-scalar inputs
ind = find (scale > 1);
if length(ind) > 1
for i = 2:length (ind)
if ndims (varargin{ind(1)}) ~= ndims (varargin{ind(i)})
error("Mismatching dimensions on inputs %d and %d", ind(1), ind(i));
elseif ~ all (size (varargin{ind(1)}) == size (varargin{ind(i)}))
error("The sizes of inputs %d and %d do not match", ind(1), ind(i));
endif
endfor
endif
endif
if max(scale) > 1
t = zeros (size (varargin{ind(1)}));
for i = 1:numel (varargin{ind(1)})
args = cell(5,1);
for j = 1:5
if isscalar (varargin{j})
args{j} = varargin{j};
else
args{j} = varargin{j}(i);
endif
endfor
if do_lweekdate
args{1} = "lweekdate";
end
t(i) = nweekdate (args{:});
endfor
else
## Do the real work.
n = varargin{1};
wd = varargin{2};
y = varargin{3};
mon = varargin{4};
nextday = varargin{5};
## Find the day of the week for the last day of the mon.
doml = eomday (y, mon);
dowl = weekday (datenum (y, mon, doml));
## Make sure that the day is in the weeks for the last then the
## first week.
if (wd < nextday) || (dowl < wd)
## adjust the last day
adjust = 7;
else
adjust = 0;
endif
dom = sort((doml - dowl + wd - adjust):-7:1);
if nextday && (dom(1) <= wd - nextday)
# adjust the first day
dom(1) = [];
endif
if do_lweekdate
t = datenum (y, mon, dom(end));
elseif n > length(dom)
t = 0;
else
t = datenum (y, mon, dom(n));
end
endif
endfunction
function v = is_lweekdate(v)
if ischar(v)
if strcmp (v, "lweekdate")
v = true();
else
error("Invalid input for n")
endif
else
v = false();
endif
endfunction
# Tests for all calling options
# Find the first Wednesday in Jan 2008
%!assert(nweekdate(1, 4, 2008, 1), datenum(2008, 1, 2))
# Find the second Wednesday in Jan 2008
%!assert(nweekdate(2, 4, 2008, 1), datenum(2008, 1, 9))
# Find the third Wednesday in Jan 2008
%!assert(nweekdate(3, 4, 2008, 1), datenum(2008, 1, 16))
# Find the fourth Wednesday in Jan 2008
%!assert(nweekdate(4, 4, 2008, 1), datenum(2008, 1, 23))
# Find the fifth Wednesday in Jan 2008
%!assert(nweekdate(5, 4, 2008, 1), datenum(2008, 1, 30))
# Find the sixth Wednesday in Jan 2008, it doesn't exist, so return 0
%!assert(nweekdate(6, 4, 2008, 1), 0)
# Find the fifth Friday in Jan 2008, it doesn't exist, so return 0
%!assert(nweekdate(5, 6, 2008, 1), 0)
# Find the first Wednesday in Jan 2008 in the same week as a Monday
# WARNING: it is unclear from the Matlab docs if this should work or if
# this should be called the second Wednesday in Jan 2008.
%!assert(nweekdate(1, 4, 2008, 1, 2), datenum(2008, 1, 9))
# Find the fifth Wednesday in Jan 2008 in the same week as a Friday.
# It doesn't exist, so return 0
%!assert(nweekdate(5, 4, 2008, 1, 6), 0)
# Try vector arguments
%!assert(nweekdate(1:6, 4, 2008, 1, 6), [datenum(2008, 1, 2:7:23), 0, 0])
# Try the lweekdate operation of this function:
# Find the last Wednesday in Jan 2008
%!assert(nweekdate('lweekdate', 4, 2008, 1), datenum(2008, 1, 30))
# Find the last Wednesday in Jan 2008 with a Friday
%!assert(nweekdate('lweekdate', 4, 2008, 1, 6), datenum(2008, 1, 23))
|