octave-maintainers
[Top][All Lists]
Advanced

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

Re: Octave-forge Date Functions Patch


From: John W. Eaton
Subject: Re: Octave-forge Date Functions Patch
Date: Thu, 16 Mar 2006 15:25:44 -0500

On  7-Jan-2006, William Poetra Yoga Hadisoeseno wrote:

| On 1/7/06, Bill Denney <address@hidden> wrote:
| > Here is a patch to the functions datesplit, datevec, and datenum to allow
| > formats (as in strptime) to be used.  It's very slow (at least on my
| > testing in cygwin which I know is slow to begin with), so it may be
| > worthwhile for someone to vectorize strptime.
| >
| 
| Hi, maybe you would like to ask around before doing this to prevent
| duplication of work ;) I've fixed the functions, and they're attached;
| you would like to look at the links below :) I haven't really looked
| at your attachment (just skimmed over it), but you might want to merge
| the patches, so...
| 
| Actually I don't count on merged patches being committed (remember
| your patch about the docstrings?)
| 
| I've done those more than two weeks ago, but I haven't actually
| committed the patches yet, since I'm still waiting for strfind (in
| discussion with Alois) and strptime (needs a patch). Unfortunately,
| John hasn't applied my strptime patch yet :(
| 
| http://www.octave.org/mailing-lists/bug-octave/2005/1316
| http://www.octave.org/mailing-lists/bug-octave/2005/1317

I included all of these functions except datenum, which is already in
the Octave CVS archive.  The version in the archive is significantly
different from the one that you sent.  Could someone please reconcile
the differences between these two versions?  For reference, I've
attached the version you sent.

Thanks,

jwe

## Copyright (C) 2000, 2001, 2003, 2004, 2005 Paul Kienzle
##
## This program 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 2 of the License, or
## (at your option) any later version.
##
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

## -*- texinfo -*-
## @deftypefn {Function File} {n =} datenum(@var{v})
## @deftypefnx {Function File} {n =} datenum(@var{y}, address@hidden, 
address@hidden, address@hidden, address@hidden, address@hidden)
## @deftypefnx {Function File} {n =} datenum(@var{str})
## @deftypefnx {Function File} {n =} datenum(@var{str}, @var{f})
## @deftypefnx {Function File} {n =} datenum(@var{str}, @var{p})
## @deftypefnx {Function File} {n =} datenum(@var{str}, @var{f}, @var{p})
## Convert the specified time to a serial date number.
##
## A serial date number is comprised of two parts:
##
## @itemize
## @item
## An integral part, specifying the number of days since a fixed base
## date. The day 0000-01-01 is defined as serial date number 1.
## @item
## A fractional part, specifying the fraction of the day, beggining at
## midnight.
## @end itemize
##
## If called with a single numeric martix, it is taken to be an array
## of date vectors (see @code{datevec}). Missing values are set to their
## default values below.
##
## If called with numeric arguments, they are taken to be the year, month,
## date, hour, minute, second respectively. Missing values are also set
## to their default values.
##
## If the first argument is a string, it is taken to be a date string
## (see @code{datestr}). @var{f} is the format string used to interpret
## @var{str} and @var{p} is the beginning of the century with the pivot
## year in the middle.
##
## Default values for @var{m} is 1, @var{d} is 1, @var{h} is 0, @var{mi}
## is 0, @var{s} is 0.
##
## Days before beginning of the month go into the previous month, and
## days after the end of the month go into the next month. Months after
## December go into the next year. Also, days and years can be fractional.
##
## For Matlab compatibility, months less than 1 are set to be 1. All other
## values can be negative or zero.
##
## XXX WARNING XXX 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
## adopted the calendar in 1582, and it took until 1928 for it to be
## adopted everywhere. See the Wikipedia entry on the Gregorian
## calendar for more details.
##
## XXX WARNING XXX leap seconds are ignored.  A table of leap seconds
## is available on the Wikipedia entry for leap seconds.
##
## Note: 32-bit architectures only handle times between Dec 14, 1901
## and Jan 19, 2038, with special handling for 0000-01-01. @code{datenum}
## returns -1 in case of a range error.
## @end deftypefn
##
## @seealso{datestr, datevec, date, clock, now, datetick}

## Algorithm: Peter Baum (http://vsg.cape.com/~pbaum/date/date0.htm)
## Author: pkienzle <pkienzle at users dot sf dot net>
## Created: 10 October 2001 (CVS)
## Adapted-By: wpyh

function n = datenum (varargin)

  persistent monthstart;

  if (isempty (monthstart))
    monthstart = [306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275];
  endif

  nin = nargin;

  if (nin < 1 || nin > 6)
    error ("see `help datenum' for usage info");
  endif

  if (ischar (varargin{1}))
    if (nin == 1)
      f = [];
      p = [];
    elseif (nin == 2)
      if (ischar (varargin{2}))
        f = varargin{2};
        p = [];
      else
        f = [];
        p = varargin{2};
      endif
    elseif (nin == 3)
      f = varargin{2};
      p = varargin{3};
    else
      usage ("n = datenum (str, [f | p]) or n = datenum (str, f, p)");
    endif
    [y, m, d, h, mi, s] = datevec (varargin{1}, f, p);
  else
    nc1 = columns (varargin{1});
    if (nin == 1)
      if (nc1 >= 1 && nc1 <= 6)
        y = varargin{1}(:,1);
        m = 1;
        d = 1;
        h = 0;
        mi = 0;
        s = 0;
        if (nc1 > 1)
          m = varargin{1}(:,2);
        endif
        if (nc1 > 2)
          d = varargin{1}(:,3);
        endif
        if (nc1 > 3)
          h = varargin{1}(:,4);
        endif
        if (nc1 > 4)
          mi = varargin{1}(:,5);
        endif
        if (nc1 > 5)
          s = varargin{1}(:,6);
        endif
      else
        usage ("n = datenum (v); v must be a date vector");
      endif
    elseif (nin > 1)
      if (nin > 6)
        usage ("n = datenum (y, [m, [d, [h, [mi, [s]]]]])");
      endif
      y = varargin{1};
      m = 1;
      d = 1;
      h = 0;
      mi = 0;
      s = 0;
      if (nin > 1)
        m = varargin{2};
      endif
      if (nin > 2)
        d = varargin{3};
      endif
      if (nin > 3)
        h = varargin{4};
      endif
      if (nin > 4)
        mi = varargin{5};
      endif
      if (nin > 5)
        s = varargin{6};
      endif
    else
      usage ("n = datenum (v) or n = datenum (y, [m, [d, [h, [mi, [s]]]]])");
    endif
  endif

  ## For compatibility with Matlab (but other values can be negative).
  m(m < 1) = 1;

  ## Set start of year to March by moving Jan. and Feb. to previous year.
  ## Correct for months > 12 by moving to subsequent years.
  z = y + fix ((m - 14) / 12);

  ## Lookup number of days to beginning of the month.
  m = mod (m - 1, 12) + 1;
  f = m;
  f(:) = monthstart(m);

  ## Add y+m+d+h+mi+s and correct for leap years.
  n = d + f + 365 * z + floor (z / 4) - floor (z / 100) + floor(z / 400) + 60 \
      + (h + (mi + s / 60) / 60) / 24;

endfunction

%!assert(datevec(datenum(2003,11,28)),[2003,11,28,0,0,0]);

reply via email to

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