7017
|
1 ## Copyright (C) 2006, 2007 Paul Kienzle |
5661
|
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 |
7016
|
7 ## the Free Software Foundation; either version 3 of the License, or (at |
|
8 ## your option) any later version. |
5661
|
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 |
7016
|
16 ## along with Octave; see the file COPYING. If not, see |
|
17 ## <http://www.gnu.org/licenses/>. |
5661
|
18 |
5660
|
19 ## -*- texinfo -*- |
5661
|
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}) |
5660
|
26 ## Returns the specified local time as a day number, with Jan 1, 0000 |
5661
|
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. |
5660
|
30 ## |
5661
|
31 ## Notes: |
|
32 ## |
|
33 ## @itemize |
|
34 ## @item |
5660
|
35 ## Years can be negative and/or fractional. |
5661
|
36 ## @item |
5660
|
37 ## Months below 1 are considered to be January. |
5661
|
38 ## @item |
5660
|
39 ## Days of the month start at 1. |
5661
|
40 ## @item |
5660
|
41 ## Days beyond the end of the month go into subsequent months. |
5661
|
42 ## @item |
5660
|
43 ## Days before the beginning of the month go to the previous month. |
5661
|
44 ## @item |
5660
|
45 ## Days can be fractional. |
5661
|
46 ## @end itemize |
5660
|
47 ## |
5661
|
48 ## @strong{Warning:} this function does not attempt to handle Julian |
5660
|
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 ## |
5661
|
55 ## @strong{Warning:} leap seconds are ignored. A table of leap seconds |
5660
|
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) |
5687
|
61 ## Author: pkienzle <pkienzle@users.sf.net> |
5660
|
62 |
5661
|
63 function [days, secs] = datenum (Y, M, D, h, m, s) |
|
64 |
5660
|
65 ## Days until start of month assuming year starts March 1. |
5661
|
66 persistent monthstart = [306; 337; 0; 31; 61; 92; 122; 153; 184; 214; 245; 275]; |
5660
|
67 |
5661
|
68 if (nargin == 0 || (nargin > 2 && ischar (Y)) || nargin > 6) |
6046
|
69 print_usage (); |
5660
|
70 endif |
5661
|
71 if (ischar (Y)) |
|
72 if (nargin < 2) |
|
73 M = []; |
|
74 endif |
5973
|
75 [Y, M, D, h, m, s] = datevec (Y, M); |
5660
|
76 else |
5661
|
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]"); |
5660
|
84 endif |
5661
|
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 |
5660
|
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. |
5661
|
99 Y += fix ((M-14)/12); |
5660
|
100 |
|
101 ## Lookup number of days since start of the current year. |
|
102 D += monthstart (mod (M-1,12) + 1) + 60; |
|
103 |
|
104 ## Add number of days to the start of the current year. Correct |
|
105 ## for leap year every 4 years except centuries not divisible by 400. |
5661
|
106 D += 365*Y + floor (Y/4) - floor (Y/100) + floor (Y/400); |
5660
|
107 |
|
108 ## Add fraction representing current second of the day. |
|
109 days = D + (h+(m+s/60)/60)/24; |
|
110 |
|
111 ## Output seconds if asked so that etime can be more accurate |
|
112 secs = 86400*D + h*3600 + m*60 + s; |
|
113 |
|
114 endfunction |
|
115 |
|
116 %!shared part |
|
117 %! part = 0.514623842592593; |
|
118 %!assert(datenum(2001,5,19), 730990) |
|
119 %!assert(datenum([1417,6,12]), 517712) |
|
120 %!assert(datenum([2001,5,19;1417,6,12]), [730990;517712]) |
|
121 %!assert(datenum(2001,5,19,12,21,3.5), 730990+part, eps) |
|
122 %!assert(datenum([1417,6,12,12,21,3.5]), 517712+part, eps) |
|
123 %!test |
|
124 %! t = [2001,5,19,12,21,3.5; 1417,6,12,12,21,3.5]; |
|
125 %! n = [730990; 517712] + part; |
|
126 %! assert(datenum(t), n, 2*eps); |