This file is indexed.

/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]))