time.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <string>
00028 
00029 #include "defun-dld.h"
00030 #include "error.h"
00031 #include "oct-map.h"
00032 #include "oct-time.h"
00033 #include "ov.h"
00034 #include "oct-obj.h"
00035 
00036 // Date and time functions.
00037 
00038 static octave_scalar_map
00039 mk_tm_map (const octave_base_tm& t)
00040 {
00041   octave_scalar_map m;
00042 
00043   m.assign ("usec", static_cast<double> (t.usec ()));
00044   m.assign ("sec", static_cast<double> (t.sec ()));
00045   m.assign ("min", static_cast<double> (t.min ()));
00046   m.assign ("hour", static_cast<double> (t.hour ()));
00047   m.assign ("mday", static_cast<double> (t.mday ()));
00048   m.assign ("mon", static_cast<double> (t.mon ()));
00049   m.assign ("year", static_cast<double> (t.year ()));
00050   m.assign ("wday", static_cast<double> (t.wday ()));
00051   m.assign ("yday", static_cast<double> (t.yday ()));
00052   m.assign ("isdst", static_cast<double> (t.isdst ()));
00053   m.assign ("zone", t.zone ());
00054 
00055   return m;
00056 }
00057 
00058 static inline int
00059 intfield (const octave_scalar_map& m, const std::string& k)
00060 {
00061   int retval = 0;
00062 
00063   octave_value v = m.getfield (k);
00064 
00065   if (! v.is_empty ())
00066     retval = v.int_value ();
00067 
00068   return retval;
00069 }
00070 
00071 static inline std::string
00072 stringfield (const octave_scalar_map& m, const std::string& k)
00073 {
00074   std::string retval;
00075 
00076   octave_value v = m.getfield (k);
00077 
00078   if (! v.is_empty ())
00079     retval = v.string_value ();
00080 
00081   return retval;
00082 }
00083 
00084 static octave_base_tm
00085 extract_tm (const octave_scalar_map& m)
00086 {
00087   octave_base_tm tm;
00088 
00089   tm.usec (intfield (m, "usec"));
00090   tm.sec (intfield (m, "sec"));
00091   tm.min (intfield (m, "min"));
00092   tm.hour (intfield (m, "hour"));
00093   tm.mday (intfield (m, "mday"));
00094   tm.mon (intfield (m, "mon"));
00095   tm.year (intfield (m, "year"));
00096   tm.wday (intfield (m, "wday"));
00097   tm.yday (intfield (m, "yday"));
00098   tm.isdst (intfield (m, "isdst"));
00099   tm.zone (stringfield (m, "zone"));
00100 
00101   return tm;
00102 }
00103 
00104 DEFUN_DLD (time, args, ,
00105   "-*- texinfo -*-\n\
00106 @deftypefn {Loadable Function} {@var{seconds} =} time ()\n\
00107 Return the current time as the number of seconds since the epoch.  The\n\
00108 epoch is referenced to 00:00:00 CUT (Coordinated Universal Time) 1 Jan\n\
00109 1970.  For example, on Monday February 17, 1997 at 07:15:06 CUT, the\n\
00110 value returned by @code{time} was 856163706.\n\
00111 @seealso{strftime, strptime, localtime, gmtime, mktime, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
00112 @end deftypefn")
00113 {
00114   octave_value retval;
00115 
00116   if (args.length () == 0)
00117     retval = octave_time ();
00118   else
00119     print_usage ();
00120 
00121   return retval;
00122 }
00123 
00124 /*
00125 
00126 %!assert(time () > 0);
00127 
00128 */
00129 
00130 DEFUN_DLD (gmtime, args, ,
00131   "-*- texinfo -*-\n\
00132 @deftypefn {Loadable Function} {@var{tm_struct} =} gmtime (@var{t})\n\
00133 Given a value returned from @code{time}, or any non-negative integer,\n\
00134 return a time structure corresponding to CUT (Coordinated Universal Time).\n\
00135 For example:\n\
00136 \n\
00137 @example\n\
00138 @group\n\
00139 gmtime (time ())\n\
00140      @result{} @{\n\
00141            usec = 0\n\
00142            sec = 6\n\
00143            min = 15\n\
00144            hour = 7\n\
00145            mday = 17\n\
00146            mon = 1\n\
00147            year = 97\n\
00148            wday = 1\n\
00149            yday = 47\n\
00150            isdst = 0\n\
00151            zone = CST\n\
00152          @}\n\
00153 @end group\n\
00154 @end example\n\
00155 @seealso{strftime, strptime, localtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
00156 @end deftypefn")
00157 {
00158   octave_value retval;
00159 
00160   if (args.length () == 1)
00161     {
00162       double tmp = args(0).double_value ();
00163 
00164       if (! error_state)
00165         retval = octave_value (mk_tm_map (octave_gmtime (tmp)));
00166     }
00167   else
00168     print_usage ();
00169 
00170   return retval;
00171 }
00172 
00173 /*
00174 
00175 %!test
00176 %! ts = gmtime (time ());
00177 %! assert((isstruct (ts)
00178 %! && isfield (ts, "usec")
00179 %! && isfield (ts, "year")
00180 %! && isfield (ts, "mon")
00181 %! && isfield (ts, "mday")
00182 %! && isfield (ts, "sec")
00183 %! && isfield (ts, "min")
00184 %! && isfield (ts, "wday")
00185 %! && isfield (ts, "hour")
00186 %! && isfield (ts, "isdst")
00187 %! && isfield (ts, "yday")));
00188 
00189 %!error <Invalid call to gmtime> gmtime ();
00190 
00191 %!error <Invalid call to gmtime> gmtime (1, 2);
00192 
00193 */
00194 
00195 DEFUN_DLD (localtime, args, ,
00196   "-*- texinfo -*-\n\
00197 @deftypefn {Loadable Function} {@var{tm_struct} =} localtime (@var{t})\n\
00198 Given a value returned from @code{time}, or any non-negative integer,\n\
00199 return a time structure corresponding to the local time zone.\n\
00200 \n\
00201 @example\n\
00202 @group\n\
00203 localtime (time ())\n\
00204      @result{} @{\n\
00205            usec = 0\n\
00206            sec = 6\n\
00207            min = 15\n\
00208            hour = 1\n\
00209            mday = 17\n\
00210            mon = 1\n\
00211            year = 97\n\
00212            wday = 1\n\
00213            yday = 47\n\
00214            isdst = 0\n\
00215            zone = CST\n\
00216          @}\n\
00217 @end group\n\
00218 @end example\n\
00219 @seealso{strftime, strptime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
00220 @end deftypefn")
00221 {
00222   octave_value retval;
00223 
00224   if (args.length () == 1)
00225     {
00226       double tmp = args(0).double_value ();
00227 
00228       if (! error_state)
00229         retval = octave_value (mk_tm_map (octave_localtime (tmp)));
00230     }
00231   else
00232     print_usage ();
00233 
00234   return retval;
00235 }
00236 
00237 /*
00238 
00239 %!test
00240 %! ts = localtime (time ());
00241 %! assert((isstruct (ts)
00242 %! && isfield (ts, "usec")
00243 %! && isfield (ts, "year")
00244 %! && isfield (ts, "mon")
00245 %! && isfield (ts, "mday")
00246 %! && isfield (ts, "sec")
00247 %! && isfield (ts, "min")
00248 %! && isfield (ts, "wday")
00249 %! && isfield (ts, "hour")
00250 %! && isfield (ts, "isdst")
00251 %! && isfield (ts, "yday")));
00252 
00253 %!error <Invalid call to localtime> localtime ();
00254 
00255 %!error <Invalid call to localtime> localtime (1, 2);
00256 
00257 */
00258 
00259 DEFUN_DLD (mktime, args, ,
00260   "-*- texinfo -*-\n\
00261 @deftypefn {Loadable Function} {@var{seconds} =} mktime (@var{tm_struct})\n\
00262 Convert a time structure corresponding to the local time to the number\n\
00263 of seconds since the epoch.  For example:\n\
00264 \n\
00265 @example\n\
00266 @group\n\
00267 mktime (localtime (time ()))\n\
00268      @result{} 856163706\n\
00269 @end group\n\
00270 @end example\n\
00271 @seealso{strftime, strptime, localtime, gmtime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
00272 @end deftypefn")
00273 {
00274   octave_value retval;
00275 
00276   if (args.length () == 1)
00277     {
00278       octave_scalar_map map = args(0).scalar_map_value ();
00279 
00280       if (! error_state)
00281         {
00282           octave_base_tm tm = extract_tm (map);
00283 
00284           if (! error_state)
00285             retval = octave_time (tm);
00286           else
00287             error ("mktime: invalid TM_STRUCT argument");
00288         }
00289       else
00290         error ("mktime: TM_STRUCT argument must be a structure");
00291     }
00292   else
00293     print_usage ();
00294 
00295   return retval;
00296 }
00297 
00298 /*
00299 
00300 %!test
00301 %! t = time ();
00302 %! assert(fix (mktime (localtime (t))) == fix (t));
00303 
00304 %!error <Invalid call to mktime> mktime ();
00305 
00306 %!error <Invalid call to mktime> mktime (1, 2, 3);
00307 
00308 %% These tests fail on systems with mktime functions of limited
00309 %% intelligence:
00310 %!assert (datestr (datenum (1969, 1, 1), 0), "01-Jan-1969 00:00:00")
00311 %!assert (datestr (datenum (1901, 1, 1), 0), "01-Jan-1901 00:00:00")
00312 %!assert (datestr (datenum (1795, 1, 1), 0), "01-Jan-1795 00:00:00")
00313 
00314 */
00315 
00316 DEFUN_DLD (strftime, args, ,
00317   "-*- texinfo -*-\n\
00318 @deftypefn {Loadable Function} {} strftime (@var{fmt}, @var{tm_struct})\n\
00319 Format the time structure @var{tm_struct} in a flexible way using the\n\
00320 format string @var{fmt} that contains @samp{%} substitutions\n\
00321 similar to those in @code{printf}.  Except where noted, substituted\n\
00322 fields have a fixed size; numeric fields are padded if necessary.\n\
00323 Padding is with zeros by default; for fields that display a single\n\
00324 number, padding can be changed or inhibited by following the @samp{%}\n\
00325 with one of the modifiers described below.  Unknown field specifiers are\n\
00326 copied as normal characters.  All other characters are copied to the\n\
00327 output without change.  For example:\n\
00328 \n\
00329 @example\n\
00330 @group\n\
00331 strftime (\"%r (%Z) %A %e %B %Y\", localtime (time ()))\n\
00332      @result{} \"01:15:06 AM (CST) Monday 17 February 1997\"\n\
00333 @end group\n\
00334 @end example\n\
00335 \n\
00336 Octave's @code{strftime} function supports a superset of the ANSI C\n\
00337 field specifiers.\n\
00338 \n\
00339 @noindent\n\
00340 Literal character fields:\n\
00341 \n\
00342 @table @code\n\
00343 @item %%\n\
00344 % character.\n\
00345 \n\
00346 @item %n\n\
00347 Newline character.\n\
00348 \n\
00349 @item %t\n\
00350 Tab character.\n\
00351 @end table\n\
00352 \n\
00353 @noindent\n\
00354 Numeric modifiers (a nonstandard extension):\n\
00355 \n\
00356 @table @code\n\
00357 @item - (dash)\n\
00358 Do not pad the field.\n\
00359 \n\
00360 @item _ (underscore)\n\
00361 Pad the field with spaces.\n\
00362 @end table\n\
00363 \n\
00364 @noindent\n\
00365 Time fields:\n\
00366 \n\
00367 @table @code\n\
00368 @item %H\n\
00369 Hour (00-23).\n\
00370 \n\
00371 @item %I\n\
00372 Hour (01-12).\n\
00373 \n\
00374 @item %k\n\
00375 Hour (0-23).\n\
00376 \n\
00377 @item %l\n\
00378 Hour (1-12).\n\
00379 \n\
00380 @item %M\n\
00381 Minute (00-59).\n\
00382 \n\
00383 @item %p\n\
00384 Locale's AM or PM.\n\
00385 \n\
00386 @item %r\n\
00387 Time, 12-hour (hh:mm:ss [AP]M).\n\
00388 \n\
00389 @item %R\n\
00390 Time, 24-hour (hh:mm).\n\
00391 \n\
00392 @item %s\n\
00393 Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).\n\
00394 \n\
00395 @item %S\n\
00396 Second (00-61).\n\
00397 \n\
00398 @item %T\n\
00399 Time, 24-hour (hh:mm:ss).\n\
00400 \n\
00401 @item %X\n\
00402 Locale's time representation (%H:%M:%S).\n\
00403 \n\
00404 @item %Z\n\
00405 Time zone (EDT), or nothing if no time zone is determinable.\n\
00406 @end table\n\
00407 \n\
00408 @noindent\n\
00409 Date fields:\n\
00410 \n\
00411 @table @code\n\
00412 @item %a\n\
00413 Locale's abbreviated weekday name (Sun-Sat).\n\
00414 \n\
00415 @item %A\n\
00416 Locale's full weekday name, variable length (Sunday-Saturday).\n\
00417 \n\
00418 @item %b\n\
00419 Locale's abbreviated month name (Jan-Dec).\n\
00420 \n\
00421 @item %B\n\
00422 Locale's full month name, variable length (January-December).\n\
00423 \n\
00424 @item %c\n\
00425 Locale's date and time (Sat Nov 04 12:02:33 EST 1989).\n\
00426 \n\
00427 @item %C\n\
00428 Century (00-99).\n\
00429 \n\
00430 @item %d\n\
00431 Day of month (01-31).\n\
00432 \n\
00433 @item %e\n\
00434 Day of month ( 1-31).\n\
00435 \n\
00436 @item %D\n\
00437 Date (mm/dd/yy).\n\
00438 \n\
00439 @item %h\n\
00440 Same as %b.\n\
00441 \n\
00442 @item %j\n\
00443 Day of year (001-366).\n\
00444 \n\
00445 @item %m\n\
00446 Month (01-12).\n\
00447 \n\
00448 @item %U\n\
00449 Week number of year with Sunday as first day of week (00-53).\n\
00450 \n\
00451 @item %w\n\
00452 Day of week (0-6).\n\
00453 \n\
00454 @item %W\n\
00455 Week number of year with Monday as first day of week (00-53).\n\
00456 \n\
00457 @item %x\n\
00458 Locale's date representation (mm/dd/yy).\n\
00459 \n\
00460 @item %y\n\
00461 Last two digits of year (00-99).\n\
00462 \n\
00463 @item %Y\n\
00464 Year (1970-).\n\
00465 @end table\n\
00466 @seealso{strptime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
00467 @end deftypefn")
00468 {
00469   octave_value retval;
00470 
00471   if (args.length () == 2)
00472     {
00473       std::string fmt = args(0).string_value ();
00474 
00475       if (! error_state)
00476         {
00477           octave_scalar_map map = args(1).scalar_map_value ();
00478 
00479           if (! error_state)
00480             {
00481               octave_base_tm tm = extract_tm (map);
00482 
00483               if (! error_state)
00484                 retval = tm.strftime (fmt);
00485               else
00486                 error ("strftime: invalid TM_STRUCT argument");
00487             }
00488           else
00489             error ("strftime: TM_STRUCT must be a structure");
00490         }
00491       else
00492         error ("strftime: FMT must be a string");
00493     }
00494   else
00495     print_usage ();
00496 
00497   return retval;
00498 }
00499 
00500 /*
00501 
00502 %!assert((ischar (strftime ("%%%n%t%H%I%k%l", localtime (time ())))
00503 %! && ischar (strftime ("%M%p%r%R%s%S%T", localtime (time ())))
00504 %! && ischar (strftime ("%X%Z%z%a%A%b%B", localtime (time ())))
00505 %! && ischar (strftime ("%c%C%d%e%D%h%j", localtime (time ())))
00506 %! && ischar (strftime ("%m%U%w%W%x%y%Y", localtime (time ())))));
00507 
00508 %!error <Invalid call to strftime> strftime ();
00509 
00510 %!error <Invalid call to strftime> strftime ("foo", localtime (time ()), 1);
00511 
00512 */
00513 
00514 DEFUN_DLD (strptime, args, ,
00515  "-*- texinfo -*-\n\
00516 @deftypefn {Loadable Function} {[@var{tm_struct}, @var{nchars}] =} strptime (@var{str}, @var{fmt})\n\
00517 Convert the string @var{str} to the time structure @var{tm_struct} under\n\
00518 the control of the format string @var{fmt}.\n\
00519 \n\
00520 If @var{fmt} fails to match, @var{nchars} is 0; otherwise, it is set to the\n\
00521 position of last matched character plus 1. Always check for this unless\n\
00522 you're absolutely sure the date string will be parsed correctly.\n\
00523 @seealso{strftime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
00524 @end deftypefn")
00525 {
00526   octave_value_list retval;
00527 
00528   if (args.length () == 2)
00529     {
00530       std::string str = args(0).string_value ();
00531 
00532       if (! error_state)
00533         {
00534           std::string fmt = args(1).string_value ();
00535 
00536           if (! error_state)
00537             {
00538               octave_strptime t (str, fmt);
00539 
00540               retval(1) = t.characters_converted ();
00541               retval(0) = octave_value (mk_tm_map (t));
00542             }
00543           else
00544             error ("strptime: FMT must be a string");
00545         }
00546       else
00547         error ("strptime: argument STR must be a string");
00548     }
00549   else
00550     print_usage ();
00551 
00552   return retval;
00553 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines