octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Many Date Functions


From: Bill Denney
Subject: Re: Many Date Functions
Date: Tue, 29 Jan 2008 07:07:01 -0500
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Bill Denney wrote:
Attached are many date functions and a diff that updates a few of the current date functions. I'm separating them into several messages which will be replies to this one because I had trouble sending everything in one message.
More date functions.

Bill
## Copyright (C) 2008 Bill Denney
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {h =} hour (Date)
##
## Returns the hour from a serial date number or a date string.
##
## @seealso{date, datevec, now, minute, second}
## @end deftypefn

## Author: Bill Denney <address@hidden>
## Created: 21 Jan 2008

function t = hour (dates)

  t = datevec (dates);
  t = t (:,4);

endfunction

## Copyright (C) 2008 Bill Denney
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {h =} holidays (startdate, enddate)
##
## Return a vector of datenums that were holidays between
## @var{startdate} and @var{enddate}, inclusive.  These holidays are
## trading holidays observed by the NYSE according to its rule 51.10. It
## does not take into account the exceptions for "unusual business
## conditions" or for additional days that have been called as holidays
## for one-time purposes.
##
## The complete list can be found at
## http://www.chronos-st.org/NYSE_Observed_Holidays-1885-Present.html
##
## @seealso{busdate, lbusdate, isbusday, fbusdate}
## @end deftypefn

## Author: Bill Denney <address@hidden>
## Created: 21 Jan 2008

function hol = holidays (sd, ed)

  sd = datenum (datevec (sd));
  ed = datenum (datevec (ed));

  ## just get the start and end years and generate all holidays in that range
  yrs = year(sd):year(ed);

  hol = [];
  ## New Year's Day
  tmphol = datenum (yrs, 1, 1);
  hol = [hol; tmphol(:)];
  ## Martin Luther King Day, the third Monday in January
  tmphol = nweekdate (3, 2, yrs, 1);
  hol = [hol; tmphol(:)];
  ## Washington's Birthday, the third Monday in February
  tmphol = nweekdate (3, 2, yrs, 2);
  hol = [hol; tmphol(:)];
  ## Good Friday
  tmphol = easter (yrs) - 2;
  hol = [hol; tmphol(:)];
  ## Memorial Day, the last Monday in May
  tmphol = lweekdate (2, yrs, 5);
  hol = [hol; tmphol(:)];
  ## Independence Day, July 4
  tmphol = datenum (yrs, 7, 4);
  hol = [hol; tmphol(:)];
  ## Labor Day, the first Monday in September
  tmphol = nweekdate (1, 2, yrs, 9);
  hol = [hol; tmphol(:)];
  ## Thanksgiving Day, the fourth Thursday in November
  tmphol = nweekdate (4, 5, yrs, 11);
  hol = [hol; tmphol(:)];
  ## Christmas Day
  tmphol = datenum (yrs, 12, 25);
  hol = [hol; tmphol(:)];

  ## Adjust for Saturdays and Sundays
  wd = weekday (hol);
  if any (wd == 1)
        hol(wd == 1) = hol(wd == 1) + 1;
  endif
  if any (wd == 7)
        hol(wd == 7) = hol(wd == 7) - 1;
  endif

  ## Trim out the days that are not in the date range
  hol(hol > ed | hol < sd) = [];
  hol = sort (hol);

endfunction

## Tests
%!assert(holidays(datenum(2008,1,1), datenum(2008,12,31)), 
datenum(2008*ones(9,1), [1;1;2;3;5;7;9;11;12], [1;21;18;21;26;4;1;27;25]))
## Test Independence day observing on a Monday (July 5) and Christmas
## observing on a Friday (Dec 24)
%!assert(holidays(datenum(2004,1,1), datenum(2004,12,31)), 
datenum(2004*ones(9,1), [1;1;2;4;5;7;9;11;12], [1;19;16;9;31;5;6;25;24]))

## Copyright (C) 2008 Bill Denney
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} address@hidden =} eomdate (@var{y}, @var{m})
## Return the last day of the month @var{m} for the year @var{y} in
## datenum format.
## @seealso{datenum, datevec, weekday, eomday}
## @end deftypefn

## Author: Bill Denney <address@hidden>
## Created: 22 Jan 2008

function e = eomdate (y, m)

  if (nargin != 2)
    print_usage ();
  endif

  d = eomday (y, m);
  e = datenum(y, m, d);

endfunction

## Copyright (C) 2008 Bill Denney
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {[m, d] =} easter (y)
## @deftypefnx {Function File} {datenum =} easter (y)
##
## Return the month (@var{m}) and day (@var{d}) of Easter in the
## Gregorial calendar on a given year or years.
##
## @seealso{holidays}
## @end deftypefn

## Author: Bill Denney <address@hidden>
## Created: 23 Jan 2008

function varargout = easter (y)

  ## This uses the Meesus/Jones/Butcher Gregorian algorithm as described
  ## on http://en.wikipedia.org/wiki/Computus#Algorithms
  a = mod (y, 19);
  b = floor (y/100);
  c = mod (y, 100);
  d = floor (b/4);
  e = mod (b, 4);
  f = floor ((b + 8)/25);
  g = floor ((b - f + 1)/3);
  h = mod ((19*a+b-d-g+15), 30);
  i = floor (c/4);
  k = mod (c, 4);
  L = mod ((32 + 2*e + 2*i - h - k), 7);
  m = floor ((a + 11*h + 22*L)/451);
  mon = floor ((h + L - 7*m + 114)/31);
  day = 1 + mod ((h + L - 7*m + 114), 31);

  if nargout == 2
        varargout = {mon(:), day(:)};
  else
        varargout{1} = reshape (datenum (y(:), mon(:), day(:)), size (y));
  end

endfunction

## Copyright (C) 2008 Bill Denney
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {dom =} day (Date)
##
## Returns the day of the month from a serial date number or a date
## string.
##
## @seealso{date, datevec, now, month, year}
## @end deftypefn

## Author: Bill Denney <address@hidden>
## Created: 21 Jan 2008

function t = day (dates)

  t = datevec (dates);
  t = t (:,3);

endfunction

## Copyright (C) 2008 Bill Denney
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {indices =} datefind (subset, superset, tol)
##
## Find any instances of the @code{subset} in the @code{superset} with
## the @code{tol}erance.  @code{tol} is 0 by default.
##
## @seealso{date, datenum}
## @end deftypefn

## Author: Bill Denney <address@hidden>
## Created: 21 Jan 2008

function idx = datefind (subset, superset, tol)

  if nargin == 2
        tol = 0;
  end
  idx = [];
  for i = 1:numel (subset)
        newidx = find (superset(:) >= subset(i)-tol & superset(:) <= 
subset(i)+tol);
        idx = [idx;newidx(:)];
  end

endfunction

## Copyright (C) 2008 Bill Denney
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} address@hidden =} yeardays (@var{y})
## @deftypefnx {Function File} address@hidden =} yeardays (@var{y}, @var{b})
## Return the number of days in the year @var{y} with an optional basis
## @var{b}.
##
## Valid bases
## @itemize @bullet
## @item 0
##   actual/actual (default)
## @item 1
##   30/360 (SIA)
## @item 2
##   actual/360
## @item 3
##   actual/365
## @item 4
##   30/360 (PSA)
## @item 5
##   30/360 (IDSA)
## @item 6
##   30/360 (European)
## @item 7
##   actual/365 (Japanese)
## @item 8
##   actual/actual (ISMA)
## @item 9
##   actual/360 (ISMA)
## @item 10
##   actual/365 (ISMA)
## @item 11
##   30/360E (ISMA)
## @end itemize
## @seealso{days365, days360, daysact, daysdif}
## @end deftypefn

## Author: Bill Denney <address@hidden>
## Created: 22 Jan 2008

function d = yeardays (y, basis)

  if (nargin == 1)
        basis = 0;
  elseif (nargin != 2)
    print_usage ();
  endif

  if isscalar (y)
        d = zeros (size (basis));
  elseif isscalar (basis)
        ## the rest of the code is much simpler if you can be sure that
        ## basis is a matrix if y is a matrix
        basis = basis * ones (size (y));
        d = zeros (size (y));
  else
        if ndims (y) == ndims (basis)
          if ~ all (size (y) == size (basis))
                error ("year and basis must be the same size or one must be a 
scalar");
          else
                d = zeros (size (y));
          endif
        else
          error ("year and basis must be the same size or one must be a 
scalar.")
        endif
  endif

  bact = ismember (basis(:), [0 8]);
  b360 = ismember (basis(:), [1 2 4 5 6 9 11]);
  b365 = ismember (basis(:), [3 7 10]);

  badbasismask = ~ (bact | b360 | b365);
  if any (badbasismask)
        badbasis = unique (basis(badbasismask));
        error ("Unsupported basis: %g\n", badbasis)
  endif

  d(bact) = 365 + (eomday(y(bact), 2) == 29);
  d(b360) = 360;
  d(b365) = 365;

endfunction

## Tests
%!assert(yeardays(2000), 366)
%!assert(yeardays(2001), 365)
%!assert(yeardays(2000:2004), [366 365 365 365 366])
%!assert(yeardays(2000, 0), 366)
%!assert(yeardays(2000, 1), 360)
%!assert(yeardays(2000, 2), 360)
%!assert(yeardays(2000, 3), 365)
%!assert(yeardays(2000, 4), 360)
%!assert(yeardays(2000, 5), 360)
%!assert(yeardays(2000, 6), 360)
%!assert(yeardays(2000, 7), 365)
%!assert(yeardays(2000, 8), 366)
%!assert(yeardays(2000, 9), 360)
%!assert(yeardays(2000, 10), 365)
%!assert(yeardays(2000, 11), 360)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]