# HG changeset patch # User bill@denney.ws # Date 1206643898 14400 # Node ID d448ac8a4874626adc655f26d03df5a01b222e0c # Parent ea2344c4140b7d12653430c0907cc98adb281d14 addtodate.m: new function diff -r ea2344c4140b -r d448ac8a4874 scripts/ChangeLog --- a/scripts/ChangeLog Thu Mar 27 14:48:36 2008 -0400 +++ b/scripts/ChangeLog Thu Mar 27 14:51:38 2008 -0400 @@ -1,5 +1,7 @@ 2008-03-27 Bill Denney + * time/addtodate.m: New function. + * geometry/rectint.m: Vectorize and add more tests. 2008-03-27 John W. Eaton diff -r ea2344c4140b -r d448ac8a4874 scripts/time/Makefile.in --- a/scripts/time/Makefile.in Thu Mar 27 14:48:36 2008 -0400 +++ b/scripts/time/Makefile.in Thu Mar 27 14:51:38 2008 -0400 @@ -32,8 +32,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ -SOURCES = asctime.m calendar.m clock.m ctime.m date.m datenum.m \ - datestr.m datevec.m eomday.m etime.m is_leap_year.m now.m \ +SOURCES = addtodate.m asctime.m calendar.m clock.m ctime.m date.m \ + datenum.m datestr.m datevec.m eomday.m etime.m is_leap_year.m now.m \ weekday.m DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES)) diff -r ea2344c4140b -r d448ac8a4874 scripts/time/addtodate.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/time/addtodate.m Thu Mar 27 14:51:38 2008 -0400 @@ -0,0 +1,111 @@ +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{d} =} addtodate (@var{d}, @var{q}, @var{f}) +## Add @var{q} amount of time (with units @var{f}) to the datenum, @var{d}. +## +## @var{f} must be one of "year", "month", "day", "hour", "minute", or +## "second". +## @seealso{datenum, datevec} +## @end deftypefn + +## Author: Bill Denney + +function d = addtodate (d, q, f) + + if (nargin != 3) + print_usage (); + elseif (! (ischar (f) && rows (f) == 1)) + ## FIXME: enhance the function so that it works with cellstrs of the + ## same size as the output. + error ("addtodate: f must be a single row character string.") + endif + + if (numel (d) == 1 && numel (q) > 1) + ## expand d to the size of q if d only has one element to make + ## addition later eaiser. + d = d.*ones (size (q)); + endif + + ## in case the user gives f as a plural, remove the s + if ("s" == f(end)) + f(end) = []; + endif + + if (any (strcmpi ({"year" "month"}, f))) + dtmp = datevec (d); + if (strcmpi ("year", f)) + dtmp(:,1) += q(:); + elseif (strcmpi ("month", f)) + dtmp(:,2) += q(:); + ## adjust the years and months if the date rolls over a year + dtmp(:,1) += floor ((dtmp(:,2)-1)/12); + dtmp(:,2) = mod (dtmp(:,2)-1, 12) + 1; + endif + dnew = datenum (dtmp); + ## make the output the right shape + if (numel (d) == numel (dnew)) + d = reshape (dnew, size (d)); + else + d = reshape (dnew, size (q)); + endif + elseif (any (strcmpi ({"day" "hour" "minute" "second"}, f))) + mult = struct ("day", 1, "hour", 1/24, "minute", 1/1440, "second", 1/86400); + d += q.*mult.(f); + else + error ("addtodate: Invalid time unit: %s", f) + endif + +endfunction + +## tests +%!shared d +%! d = datenum (2008, 1, 1); +## Identity +%!assert (addtodate (d, 0, "year"), d) +%!assert (addtodate (d, 0, "month"), d) +%!assert (addtodate (d, 0, "day"), d) +%!assert (addtodate (d, 0, "hour"), d) +%!assert (addtodate (d, 0, "minute"), d) +%!assert (addtodate (d, 0, "second"), d) +## Add one of each +## leap year +%!assert (addtodate (d, 1, "year"), d+366) +%!assert (addtodate (d, 1, "month"), d+31) +%!assert (addtodate (d, 1, "day"), d+1) +%!assert (addtodate (d, 1, "hour"), d+1/24) +%!assert (addtodate (d, 1, "minute"), d+1/1440) +%!assert (addtodate (d, 1, "second"), d+1/86400) +## substract one of each +%!assert (addtodate (d, -1, "year"), d-365) +%!assert (addtodate (d, -1, "month"), d-31) +%!assert (addtodate (d, -1, "day"), d-1) +%!assert (addtodate (d, -1, "hour"), d-1/24) +%!assert (addtodate (d, -1, "minute"), d-1/1440) +%!assert (addtodate (d, -1, "second"), d-1/86400) +## rollover +%!assert (addtodate (d, 12, "month"), d+366) +%!assert (addtodate (d, 13, "month"), d+366+31) +## multiple inputs and output orientation +%!assert (addtodate ([d d], [1 13], "month"), [d+31 d+366+31]) +%!assert (addtodate ([d;d], [1;13], "month"), [d+31;d+366+31]) +%!assert (addtodate (d, [1;13], "month"), [d+31;d+366+31]) +%!assert (addtodate (d, [1 13], "month"), [d+31 d+366+31]) +%!assert (addtodate ([d;d+1], 1, "month"), [d+31;d+1+31]) +%!assert (addtodate ([d d+1], 1, "month"), [d+31 d+1+31])