Mercurial > hg > octave-lyh
diff scripts/time/datenum.m @ 13848:40e32fe44aaa
Ugrade time functions to accept millisecond format string FFF (Bug #34586)
* datestr.m: Add millisecond FFF format. Change numerical formats 21,22,29
to match Matlab. Remove unused persistent variables. Vectorize some for
loops. Use strrep rather than regexp where possible for speed.
* datevec.m: Add millisecond FFF format. Use strrep rather than regexp where
possible for speed.
* datenum.m: Update docstring. Use modern coding style. Only calculate
second output argument if requested. Allow cellstr inputs.
author | Rik <octave@nomad.inbox5.com> |
---|---|
date | Wed, 09 Nov 2011 14:49:09 -0800 |
parents | b80b18f537ca |
children | d490ca8ab1a5 |
line wrap: on
line diff
--- a/scripts/time/datenum.m +++ b/scripts/time/datenum.m @@ -17,16 +17,25 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} datenum (@var{year}, @var{month}, @var{day}) -## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}) -## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}) -## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}, @var{second}) -## @deftypefnx {Function File} {} datenum ("date") -## @deftypefnx {Function File} {} datenum ("date", @var{p}) -## Return the specified local time as a day number, with Jan 1, 0000 -## being day 1. By this reckoning, Jan 1, 1970 is day number 719529. -## The fractional portion, @var{p}, corresponds to the portion of the -## specified day. +## @deftypefn {Function File} {@var{days} =} datenum (@var{datevec}) +## @deftypefnx {Function File} {@var{days} =} datenum (@var{year}, @var{month}, @var{day}) +## @deftypefnx {Function File} {@var{days} =} datenum (@var{year}, @var{month}, @var{day}, @var{hour}) +## @deftypefnx {Function File} {@var{days} =} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}) +## @deftypefnx {Function File} {@var{days} =} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}, @var{second}) +## @deftypefnx {Function File} {@var{days} =} datenum ("datestr") +## @deftypefnx {Function File} {@var{days} =} datenum ("datestr", @var{p}) +## @deftypefnx {Function File} {[@var{days}, @var{secs}] =} datenum (@dots{}) +## Return the date/time input as a serial day number, with Jan 1, 0000 +## being day 1. The fractional portion of @var{days} corresponds to the time +## on the given day. The input may be a date vector (see @code{datevec}), +## datestr (see @code{datestr}), or directly specified as input. +## +## When processing datestrings, @var{p} is the year at the start of the century +## to which two-digit years will be referenced. If not specified, it defaults +## to the current year minus 50. +## +## The optional output @var{secs} holds the time on the specified day with greater +## precision than @var{days}. ## ## Notes: ## @@ -52,48 +61,43 @@ ## ## @strong{Caution:} this function does not attempt to handle Julian ## calendars so dates before Octave 15, 1582 are wrong by as much -## as eleven days. Also be aware that only Roman Catholic countries +## as eleven days. Also, be aware that only Roman Catholic countries ## adopted the calendar in 1582. It took until 1924 for it to be ## adopted everywhere. See the Wikipedia entry on the Gregorian ## calendar for more details. ## ## @strong{Warning:} leap seconds are ignored. A table of leap seconds ## is available on the Wikipedia entry for leap seconds. -## @seealso{date, clock, now, datestr, datevec, calendar, weekday} +## @seealso{datestr, datevec, date, clock, now, calendar, weekday} ## @end deftypefn ## Algorithm: Peter Baum (http://vsg.cape.com/~pbaum/date/date0.htm) ## Author: pkienzle <pkienzle@users.sf.net> -function [days, secs] = datenum (year, month, day, hour, minute, second) +function [days, secs] = datenum (year, month = [], day = [], hour = 0, minute = 0, second = 0) ## Days until start of month assuming year starts March 1. persistent monthstart = [306; 337; 0; 31; 61; 92; 122; 153; 184; 214; 245; 275]; - if (nargin == 0 || (nargin > 2 && ischar (year)) || nargin > 6) + if (nargin == 0 || nargin > 6 || + (nargin > 2 && (ischar (year) || iscellstr (year)))) print_usage (); endif - if (ischar (year)) - if (nargin < 2) - month = []; - endif + + if (ischar (year) || iscellstr (year)) [year, month, day, hour, minute, second] = datevec (year, month); else - if (nargin < 6) second = 0; endif - if (nargin < 5) minute = 0; endif - if (nargin < 4) hour = 0; endif if (nargin == 1) nc = columns (year); if (nc > 6 || nc < 3) error ("datenum: expected date vector containing [YEAR, MONTH, DAY, HOUR, MINUTE, SECOND]"); endif - second = minute = hour = 0; if (nc >= 6) second = year(:,6); endif if (nc >= 5) minute = year(:,5); endif - if (nc >= 4) hour = year(:,4); endif - day = year(:,3); + if (nc >= 4) hour = year(:,4); endif + day = year(:,3); month = year(:,2); - year = year(:,1); + year = year(:,1); endif endif @@ -120,30 +124,32 @@ day += 365*year + floor (year/4) - floor (year/100) + floor (year/400); ## Add fraction representing current second of the day. - days = day + (hour+(minute+second/60)/60)/24; + days = day + (hour + (minute + second/60)/60)/24; ## Output seconds if asked so that etime can be more accurate - secs = 86400*day + hour*3600 + minute*60 + second; + if (isargout (2)) + secs = day*86400 + hour*3600 + minute*60 + second; + endif endfunction + %!shared part %! part = 0.514623842592593; -%!assert(datenum(2001,5,19), 730990) -%!assert(datenum([1417,6,12]), 517712) -%!assert(datenum([2001,5,19;1417,6,12]), [730990;517712]) -%!assert(datenum(2001,5,19,12,21,3.5), 730990+part, eps) -%!assert(datenum([1417,6,12,12,21,3.5]), 517712+part, eps) +%!assert (datenum (2001,5,19), 730990) +%!assert (datenum ([1417,6,12]), 517712) +%!assert (datenum ([2001,5,19;1417,6,12]), [730990;517712]) +%!assert (datenum (2001,5,19,12,21,3.5), 730990+part, eps) +%!assert (datenum ([1417,6,12,12,21,3.5]), 517712+part, eps) ## Test vector inputs %!test %! t = [2001,5,19,12,21,3.5; 1417,6,12,12,21,3.5]; %! n = [730990; 517712] + part; -%! assert(datenum(t), n, 2*eps); -## Make sure that the vectors can have either orientation -%!test -%! t = [2001,5,19,12,21,3.5; 1417,6,12,12,21,3.5]'; -%! n = [730990 517712] + part; -%! assert(datenum(t(1,:), t(2,:), t(3,:), t(4,:), t(5,:), t(6,:)), n, 2*eps); +%! assert (datenum (t), n, 2*eps); +%! ## Check that vectors can have either orientation +%! t = t'; +%! n = n'; +%! assert (datenum (t(1,:), t(2,:), t(3,:), t(4,:), t(5,:), t(6,:)), n, 2*eps); ## Test mixed vectors and scalars %!assert (datenum([2008;2009], 1, 1), [datenum(2008, 1, 1);datenum(2009, 1, 1)]); @@ -159,3 +165,14 @@ %!assert (datenum([2008 2009], [1 2], 1), [datenum(2008, 1, 1) datenum(2009, 2, 1)]); %!assert (datenum([2008 2009], 1, [1 2]), [datenum(2008, 1, 1) datenum(2009, 1, 2)]); %!assert (datenum(2008, [1 2], [1 2]), [datenum(2008, 1, 1) datenum(2008, 2, 2)]); +## Test string and cellstr inputs +%!assert (datenum ("5/19/2001"), 730990) +%!assert (datenum ({"5/19/2001"}), 730990) +%!assert (datenum (char ("5/19/2001", "6/6/1944")), [730990; 710189]) +%!assert (datenum ({"5/19/2001", "6/6/1944"}), [730990; 710189]) + +%% Test input validation +%!error datenum () +%!error datenum (1,2,3,4,5,6,7) +%!error datenum ([1, 2]) +%!error datenum ([1,2,3,4,5,6,7])