changelog shortlog tags changeset files revisions annotate raw

scripts/time/datenum.m

changeset 10289: 4b124317dc38
parent:4ab2488ab2b4
author: John W. Eaton <jwe@octave.org>
date: Tue Feb 09 20:58:55 2010 -0500 (51 minutes ago)
permissions: -rw-r--r--
description: base_properties::set_children: account for hidden children
1## Copyright (C) 2006, 2007, 2008 Paul Kienzle
2##
3## This file is part of Octave.
4##
5## Octave is free software; you can redistribute it and/or modify it
6## under the terms of the GNU General Public License as published by
7## the Free Software Foundation; either version 3 of the License, or (at
8## your option) any later version.
9##
10## Octave is distributed in the hope that it will be useful, but
11## WITHOUT ANY WARRANTY; without even the implied warranty of
12## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13## General Public License for more details.
14##
15## You should have received a copy of the GNU General Public License
16## along with Octave; see the file COPYING. If not, see
17## <http://www.gnu.org/licenses/>.
18
19## -*- texinfo -*-
20## @deftypefn {Function File} {} datenum (@var{year}, @var{month}, @var{day})
21## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour})
22## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute})
23## @deftypefnx {Function File} {} datenum (@var{year}, @var{month}, @var{day}, @var{hour}, @var{minute}, @var{second})
24## @deftypefnx {Function File} {} datenum (@code{"date"})
25## @deftypefnx {Function File} {} datenum (@code{"date"}, @var{p})
26## Returns the specified local time as a day number, with Jan 1, 0000
27## being day 1. By this reckoning, Jan 1, 1970 is day number 719529.
28## The fractional portion, @var{p}, corresponds to the portion of the
29## specified day.
30##
31## Notes:
32##
33## @itemize
34## @item
35## Years can be negative and/or fractional.
36## @item
37## Months below 1 are considered to be January.
38## @item
39## Days of the month start at 1.
40## @item
41## Days beyond the end of the month go into subsequent months.
42## @item
43## Days before the beginning of the month go to the previous month.
44## @item
45## Days can be fractional.
46## @end itemize
47##
48## @strong{Warning:} this function does not attempt to handle Julian
49## calendars so dates before Octave 15, 1582 are wrong by as much
50## as eleven days. Also be aware that only Roman Catholic countries
51## adopted the calendar in 1582. It took until 1924 for it to be
52## adopted everywhere. See the Wikipedia entry on the Gregorian
53## calendar for more details.
54##
55## @strong{Warning:} leap seconds are ignored. A table of leap seconds
56## is available on the Wikipedia entry for leap seconds.
57## @seealso{date, clock, now, datestr, datevec, calendar, weekday}
58## @end deftypefn
59
60## Algorithm: Peter Baum (http://vsg.cape.com/~pbaum/date/date0.htm)
61## Author: pkienzle <pkienzle@users.sf.net>
62
63function [days, secs] = datenum (Y, M, D, h, m, s)
64
65 ## Days until start of month assuming year starts March 1.
66 persistent monthstart = [306; 337; 0; 31; 61; 92; 122; 153; 184; 214; 245; 275];
67
68 if (nargin == 0 || (nargin > 2 && ischar (Y)) || nargin > 6)
69 print_usage ();
70 endif
71 if (ischar (Y))
72 if (nargin < 2)
73 M = [];
74 endif
75 [Y, M, D, h, m, s] = datevec (Y, M);
76 else
77 if (nargin < 6) s = 0; endif
78 if (nargin < 5) m = 0; endif
79 if (nargin < 4) h = 0; endif
80 if (nargin == 1)
81 nc = columns (Y);
82 if (nc > 6 || nc < 3)
83 error ("expected date vector containing [Y, M, D, h, m, s]");
84 endif
85 s = m = h = 0;
86 if (nc >= 6) s = Y(:,6); endif
87 if (nc >= 5) m = Y(:,5); endif
88 if (nc >= 4) h = Y(:,4); endif
89 D = Y(:,3);
90 M = Y(:,2);
91 Y = Y(:,1);
92 endif
93 endif
94
95 M(M<1) = 1; ## For compatibility. Otherwise allow negative months.
96
97 ## Set start of year to March by moving Jan. and Feb. to previous year.
98 ## Correct for months > 12 by moving to subsequent years.
99 Y += fix ((M-14)/12);
100
101 ## Lookup number of days since start of the current year.
102 if (numel (M) == 1 || numel (D) == 1)
103 ## Allow M or D to be scalar while other values may be vectors or
104 ## matrices.
105 D += monthstart (mod (M-1,12) + 1) + 60;
106 if (numel (M) > 1)
107 D = reshape (D, size (M));
108 endif
109 else
110 D += reshape (monthstart (mod (M-1,12) + 1), size (D)) + 60;
111 endif
112
113 ## Add number of days to the start of the current year. Correct
114 ## for leap year every 4 years except centuries not divisible by 400.
115 D += 365*Y + floor (Y/4) - floor (Y/100) + floor (Y/400);
116
117 ## Add fraction representing current second of the day.
118 days = D + (h+(m+s/60)/60)/24;
119
120 ## Output seconds if asked so that etime can be more accurate
121 secs = 86400*D + h*3600 + m*60 + s;
122
123endfunction
124
125%!shared part
126%! part = 0.514623842592593;
127%!assert(datenum(2001,5,19), 730990)
128%!assert(datenum([1417,6,12]), 517712)
129%!assert(datenum([2001,5,19;1417,6,12]), [730990;517712])
130%!assert(datenum(2001,5,19,12,21,3.5), 730990+part, eps)
131%!assert(datenum([1417,6,12,12,21,3.5]), 517712+part, eps)
132## Test vector inputs
133%!test
134%! t = [2001,5,19,12,21,3.5; 1417,6,12,12,21,3.5];
135%! n = [730990; 517712] + part;
136%! assert(datenum(t), n, 2*eps);
137## Make sure that the vectors can have either orientation
138%!test
139%! t = [2001,5,19,12,21,3.5; 1417,6,12,12,21,3.5]';
140%! n = [730990 517712] + part;
141%! assert(datenum(t(1,:), t(2,:), t(3,:), t(4,:), t(5,:), t(6,:)), n, 2*eps);
142
143## Test mixed vectors and scalars
144%!assert (datenum([2008;2009], 1, 1), [datenum(2008, 1, 1);datenum(2009, 1, 1)]);
145%!assert (datenum(2008, [1;2], 1), [datenum(2008, 1, 1);datenum(2008, 2, 1)]);
146%!assert (datenum(2008, 1, [1;2]), [datenum(2008, 1, 1);datenum(2008, 1, 2)]);
147%!assert (datenum([2008;2009], [1;2], 1), [datenum(2008, 1, 1);datenum(2009, 2, 1)]);
148%!assert (datenum([2008;2009], 1, [1;2]), [datenum(2008, 1, 1);datenum(2009, 1, 2)]);
149%!assert (datenum(2008, [1;2], [1;2]), [datenum(2008, 1, 1);datenum(2008, 2, 2)]);
150## And the other orientation
151%!assert (datenum([2008 2009], 1, 1), [datenum(2008, 1, 1) datenum(2009, 1, 1)]);
152%!assert (datenum(2008, [1 2], 1), [datenum(2008, 1, 1) datenum(2008, 2, 1)]);
153%!assert (datenum(2008, 1, [1 2]), [datenum(2008, 1, 1) datenum(2008, 1, 2)]);
154%!assert (datenum([2008 2009], [1 2], 1), [datenum(2008, 1, 1) datenum(2009, 2, 1)]);
155%!assert (datenum([2008 2009], 1, [1 2]), [datenum(2008, 1, 1) datenum(2009, 1, 2)]);
156%!assert (datenum(2008, [1 2], [1 2]), [datenum(2008, 1, 1) datenum(2008, 2, 2)]);