/usr/share/octave/packages/3.2/time-1.0.9/busdays.m is in octave-time 1.0.9-3.
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 | ## Copyright (C) 2008 Bill Denney
##
## This software 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 software 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 software; see the file COPYING. If not, see
## <http://www.gnu.org/licenses/>.
## -*- texinfo -*-
## @deftypefn {Function File} {@var{bdates} =} busdays (@var{sdate}, @var{edate})
## @deftypefn {Function File} {@var{bdates} =} busdays (@var{sdate}, @var{edate}, @var{bdmode})
## @deftypefn {Function File} {@var{bdates} =} busdays (@var{sdate}, @var{edate}, @var{bdmode}, @var{holvec})
## Generate a list of business dates at the end of the periods defined
## between (including) @var{sdate} and @var{edate}.
##
## @var{sdate} is the starting date, @var{edate} is the ending date,
## both are in serial date format (see datenum). @var{bdmode} is the
## business day frequency ("daily", "weekly", "monthly", "quarterly",
## "semiannual", or "annual"); these can be abbreviated by the first
## letter and they may also use an integer corresponding to the order in
## the above list (i.e. "daily" = 1). @var{holvec} is an optional list
## of holidays. If the holidays are not given, then the holidays
## function is used.
## @seealso{holidays, busdate, lbusdate, isbusday, fbusdate, datenum}
## @end deftypefn
## Author: Bill Denney <bill@denney.ws>
## Created: 17 May 2008
function bd = busdays (sd, ed, mode=1, hol=[])
if nargin < 2 || nargin > 4
print_usage ();
endif
if ~isnumeric (sd)
sd = datenum (sd);
endif
if ~isnumeric (ed)
ed = datenum (ed);
endif
if ed < sd
error ("busdays: the start date must be less than the end date")
endif
if isempty (hol)
## make the holidays take into account the whole ending year because
## the day may extend beyond the actual ending date
edtmp = datevec (ed);
edtmp(2:3) = [12 31];
hol = holidays (sd, datenum (edtmp));
endif
## Convert the mode to the numeric
modestr = "dwmqsa";
if ischar (mode)
mode = find (lower (mode(1)) == modestr);
if isempty (mode)
error ("busdays: mode must be one of '%s'", modestr)
endif
elseif isnumeric (mode)
if mode < 1 || mode > length (modestr)
error ("busdays: mode must be between 1 and %d", length (modestr))
endif
else
error ("busdays: mode must be a number or string")
endif
## do the computation
if mode == 1
## daily
bd = (sd:ed)'(isbusday (sd:ed, hol));
elseif mode < 6
if mode == 2
## weekly make the start and end dates Fridays and then move back
## from there
wd = weekday ([sd;ed]);
d = [sd;ed] - wd + 7;
## there are generally not more than one week of holidays at a
## time, but the call to unique will make certain of that.
bd = unique (busdate ([d(1):7:d(2)]', -1, hol));
else
d = datevec ([sd:ed]);
## unique year and month list within the date range
ym = unique (d(:,1:2), "rows");
if mode == 3
## monthly, do nothing to the ym list
elseif mode == 4
## quarterly
if mod (ym(end), 3) != 0
## make the last month an end of quarter month
ym(end) = ym(end) + 3 - mod (ym(end), 3);
endif
ym(mod (ym(:,2), 3) != 0, :) = [];
elseif mode == 5
## semi-annually
if mod (ym(end), 6) != 0
## make the last month an end of semi-annual month (6, 12)
ym(end) = ym(end) + 6 - mod (ym(end), 6);
endif
ym(mod (ym(:,2), 6) != 0, :) = [];
endif
bd = lbusdate (ym(:,1), ym(:,2), hol);
endif
elseif mode == 6
## annual
d = datevec ([sd;ed]);
bd = lbusdate ((d(1,1):d(2,1))', 12, hol);
else
## this should have been caught before now
error ("busdays: invalid mode")
endif
endfunction
## Tests
%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 12)), datenum (2008, 1, [2;3;4;7;8;9;10;11]))
%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 12), "d"), datenum (2008, 1, [2;3;4;7;8;9;10;11]))
%!assert (busdays (datenum (2001, 1, 2), datenum (2001, 1, 9), "w"), datenum (2001, 1, [5;12]))
%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 2), "m"), datenum (2008, 1, 31))
%!assert (busdays (datenum (2008, 1, 1), datenum (2010, 5, 2), "m"), lbusdate ([2008*ones(12,1);2009*ones(12,1);2010*ones(5,1)], [1:12 1:12 1:5]'))
%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 2), "q"), datenum (2008, 3, 31))
%!assert (busdays (datenum (2008, 1, 1), datenum (2010, 5, 2), "q"), lbusdate ([2008*ones(4,1);2009*ones(4,1);2010*ones(2,1)], [3:3:12 3:3:12 3 6]'))
%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 2), "s"), datenum (2008, 6, 30))
%!assert (busdays (datenum (2008, 1, 1), datenum (2010, 5, 2), "s"), lbusdate ([2008;2008;2009;2009;2010], [6 12 6 12 6]'))
%!assert (busdays (datenum (2008, 1, 1), datenum (2011, 1, 2), "a"), datenum ([2008;2009;2010;2011], [12;12;12;12], [31;31;30;30]))
|