GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
time.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <string>
28 
29 #include "defun.h"
30 #include "error.h"
31 #include "oct-map.h"
32 #include "oct-time.h"
33 #include "ov.h"
34 #include "oct-obj.h"
35 
36 // Date and time functions.
37 
38 static octave_scalar_map
40 {
42 
43  m.assign ("usec", static_cast<double> (t.usec ()));
44  m.assign ("sec", static_cast<double> (t.sec ()));
45  m.assign ("min", static_cast<double> (t.min ()));
46  m.assign ("hour", static_cast<double> (t.hour ()));
47  m.assign ("mday", static_cast<double> (t.mday ()));
48  m.assign ("mon", static_cast<double> (t.mon ()));
49  m.assign ("year", static_cast<double> (t.year ()));
50  m.assign ("wday", static_cast<double> (t.wday ()));
51  m.assign ("yday", static_cast<double> (t.yday ()));
52  m.assign ("isdst", static_cast<double> (t.isdst ()));
53  m.assign ("zone", t.zone ());
54 
55  return m;
56 }
57 
58 static inline int
59 intfield (const octave_scalar_map& m, const std::string& k)
60 {
61  int retval = 0;
62 
63  octave_value v = m.getfield (k);
64 
65  if (! v.is_empty ())
66  retval = v.int_value ();
67 
68  return retval;
69 }
70 
71 static inline std::string
72 stringfield (const octave_scalar_map& m, const std::string& k)
73 {
74  std::string retval;
75 
76  octave_value v = m.getfield (k);
77 
78  if (! v.is_empty ())
79  retval = v.string_value ();
80 
81  return retval;
82 }
83 
84 static octave_base_tm
86 {
87  octave_base_tm tm;
88 
89  tm.usec (intfield (m, "usec"));
90  tm.sec (intfield (m, "sec"));
91  tm.min (intfield (m, "min"));
92  tm.hour (intfield (m, "hour"));
93  tm.mday (intfield (m, "mday"));
94  tm.mon (intfield (m, "mon"));
95  tm.year (intfield (m, "year"));
96  tm.wday (intfield (m, "wday"));
97  tm.yday (intfield (m, "yday"));
98  tm.isdst (intfield (m, "isdst"));
99  tm.zone (stringfield (m, "zone"));
100 
101  return tm;
102 }
103 
104 DEFUN (time, args, ,
105  "-*- texinfo -*-\n\
106 @deftypefn {Built-in Function} {@var{seconds} =} time ()\n\
107 Return the current time as the number of seconds since the epoch. The\n\
108 epoch is referenced to 00:00:00 CUT (Coordinated Universal Time) 1 Jan\n\
109 1970. For example, on Monday February 17, 1997 at 07:15:06 CUT, the\n\
110 value returned by @code{time} was 856163706.\n\
111 @seealso{strftime, strptime, localtime, gmtime, mktime, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
112 @end deftypefn")
113 {
114  octave_value retval;
115 
116  if (args.length () == 0)
117  retval = octave_time ();
118  else
119  print_usage ();
120 
121  return retval;
122 }
123 
124 /*
125 %!assert (time () > 0)
126 */
127 
128 DEFUN (gmtime, args, ,
129  "-*- texinfo -*-\n\
130 @deftypefn {Built-in Function} {@var{tm_struct} =} gmtime (@var{t})\n\
131 Given a value returned from @code{time}, or any non-negative integer,\n\
132 return a time structure corresponding to CUT (Coordinated Universal Time).\n\
133 For example:\n\
134 \n\
135 @example\n\
136 @group\n\
137 gmtime (time ())\n\
138  @result{} @{\n\
139  usec = 0\n\
140  sec = 6\n\
141  min = 15\n\
142  hour = 7\n\
143  mday = 17\n\
144  mon = 1\n\
145  year = 97\n\
146  wday = 1\n\
147  yday = 47\n\
148  isdst = 0\n\
149  zone = CST\n\
150  @}\n\
151 @end group\n\
152 @end example\n\
153 @seealso{strftime, strptime, localtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
154 @end deftypefn")
155 {
156  octave_value retval;
157 
158  if (args.length () == 1)
159  {
160  double tmp = args(0).double_value ();
161 
162  if (! error_state)
163  retval = octave_value (mk_tm_map (octave_gmtime (tmp)));
164  }
165  else
166  print_usage ();
167 
168  return retval;
169 }
170 
171 /*
172 %!test
173 %! ts = gmtime (time ());
174 %! assert (isstruct (ts));
175 %! assert (isfield (ts, "usec"));
176 %! assert (isfield (ts, "year"));
177 %! assert (isfield (ts, "mon"));
178 %! assert (isfield (ts, "mday"));
179 %! assert (isfield (ts, "sec"));
180 %! assert (isfield (ts, "min"));
181 %! assert (isfield (ts, "wday"));
182 %! assert (isfield (ts, "hour"));
183 %! assert (isfield (ts, "isdst"));
184 %! assert (isfield (ts, "yday"));
185 
186 %!error gmtime ()
187 %!error gmtime (1, 2)
188 */
189 
190 DEFUN (localtime, args, ,
191  "-*- texinfo -*-\n\
192 @deftypefn {Built-in Function} {@var{tm_struct} =} localtime (@var{t})\n\
193 Given a value returned from @code{time}, or any non-negative integer,\n\
194 return a time structure corresponding to the local time zone.\n\
195 \n\
196 @example\n\
197 @group\n\
198 localtime (time ())\n\
199  @result{} @{\n\
200  usec = 0\n\
201  sec = 6\n\
202  min = 15\n\
203  hour = 1\n\
204  mday = 17\n\
205  mon = 1\n\
206  year = 97\n\
207  wday = 1\n\
208  yday = 47\n\
209  isdst = 0\n\
210  zone = CST\n\
211  @}\n\
212 @end group\n\
213 @end example\n\
214 @seealso{strftime, strptime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
215 @end deftypefn")
216 {
217  octave_value retval;
218 
219  if (args.length () == 1)
220  {
221  double tmp = args(0).double_value ();
222 
223  if (! error_state)
224  retval = octave_value (mk_tm_map (octave_localtime (tmp)));
225  }
226  else
227  print_usage ();
228 
229  return retval;
230 }
231 
232 /*
233 %!test
234 %! ts = localtime (time ());
235 %! assert (isstruct (ts));
236 %! assert (isfield (ts, "usec"));
237 %! assert (isfield (ts, "year"));
238 %! assert (isfield (ts, "mon"));
239 %! assert (isfield (ts, "mday"));
240 %! assert (isfield (ts, "sec"));
241 %! assert (isfield (ts, "min"));
242 %! assert (isfield (ts, "wday"));
243 %! assert (isfield (ts, "hour"));
244 %! assert (isfield (ts, "isdst"));
245 %! assert (isfield (ts, "yday"));
246 
247 %!error localtime ()
248 %!error localtime (1, 2)
249 */
250 
251 DEFUN (mktime, args, ,
252  "-*- texinfo -*-\n\
253 @deftypefn {Built-in Function} {@var{seconds} =} mktime (@var{tm_struct})\n\
254 Convert a time structure corresponding to the local time to the number\n\
255 of seconds since the epoch. For example:\n\
256 \n\
257 @example\n\
258 @group\n\
259 mktime (localtime (time ()))\n\
260  @result{} 856163706\n\
261 @end group\n\
262 @end example\n\
263 @seealso{strftime, strptime, localtime, gmtime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
264 @end deftypefn")
265 {
266  octave_value retval;
267 
268  if (args.length () == 1)
269  {
270  octave_scalar_map map = args(0).scalar_map_value ();
271 
272  if (! error_state)
273  {
274  octave_base_tm tm = extract_tm (map);
275 
276  if (! error_state)
277  retval = octave_time (tm);
278  else
279  error ("mktime: invalid TM_STRUCT argument");
280  }
281  else
282  error ("mktime: TM_STRUCT argument must be a structure");
283  }
284  else
285  print_usage ();
286 
287  return retval;
288 }
289 
290 /*
291 %!test
292 %! t = time ();
293 %! assert (fix (mktime (localtime (t))) == fix (t));
294 
295 ## These tests fail on systems with mktime functions of limited
296 ## intelligence:
297 %!assert (datestr (datenum (1969, 1, 1), 0), "01-Jan-1969 00:00:00")
298 %!assert (datestr (datenum (1901, 1, 1), 0), "01-Jan-1901 00:00:00")
299 %!assert (datestr (datenum (1795, 1, 1), 0), "01-Jan-1795 00:00:00")
300 
301 %!error mktime ()
302 %!error mktime (1, 2, 3)
303 */
304 
305 DEFUN (strftime, args, ,
306  "-*- texinfo -*-\n\
307 @deftypefn {Built-in Function} {} strftime (@var{fmt}, @var{tm_struct})\n\
308 Format the time structure @var{tm_struct} in a flexible way using the\n\
309 format string @var{fmt} that contains @samp{%} substitutions\n\
310 similar to those in @code{printf}. Except where noted, substituted\n\
311 fields have a fixed size; numeric fields are padded if necessary.\n\
312 Padding is with zeros by default; for fields that display a single\n\
313 number, padding can be changed or inhibited by following the @samp{%}\n\
314 with one of the modifiers described below. Unknown field specifiers are\n\
315 copied as normal characters. All other characters are copied to the\n\
316 output without change. For example:\n\
317 \n\
318 @example\n\
319 @group\n\
320 strftime (\"%r (%Z) %A %e %B %Y\", localtime (time ()))\n\
321  @result{} \"01:15:06 AM (CST) Monday 17 February 1997\"\n\
322 @end group\n\
323 @end example\n\
324 \n\
325 Octave's @code{strftime} function supports a superset of the ANSI C\n\
326 field specifiers.\n\
327 \n\
328 @noindent\n\
329 Literal character fields:\n\
330 \n\
331 @table @code\n\
332 @item %%\n\
333 % character.\n\
334 \n\
335 @item %n\n\
336 Newline character.\n\
337 \n\
338 @item %t\n\
339 Tab character.\n\
340 @end table\n\
341 \n\
342 @noindent\n\
343 Numeric modifiers (a nonstandard extension):\n\
344 \n\
345 @table @code\n\
346 @item - (dash)\n\
347 Do not pad the field.\n\
348 \n\
349 @item _ (underscore)\n\
350 Pad the field with spaces.\n\
351 @end table\n\
352 \n\
353 @noindent\n\
354 Time fields:\n\
355 \n\
356 @table @code\n\
357 @item %H\n\
358 Hour (00-23).\n\
359 \n\
360 @item %I\n\
361 Hour (01-12).\n\
362 \n\
363 @item %k\n\
364 Hour (0-23).\n\
365 \n\
366 @item %l\n\
367 Hour (1-12).\n\
368 \n\
369 @item %M\n\
370 Minute (00-59).\n\
371 \n\
372 @item %p\n\
373 Locale's AM or PM.\n\
374 \n\
375 @item %r\n\
376 Time, 12-hour (hh:mm:ss [AP]M).\n\
377 \n\
378 @item %R\n\
379 Time, 24-hour (hh:mm).\n\
380 \n\
381 @item %s\n\
382 Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).\n\
383 \n\
384 @item %S\n\
385 Second (00-61).\n\
386 \n\
387 @item %T\n\
388 Time, 24-hour (hh:mm:ss).\n\
389 \n\
390 @item %X\n\
391 Locale's time representation (%H:%M:%S).\n\
392 \n\
393 @item %Z\n\
394 Time zone (EDT), or nothing if no time zone is determinable.\n\
395 @end table\n\
396 \n\
397 @noindent\n\
398 Date fields:\n\
399 \n\
400 @table @code\n\
401 @item %a\n\
402 Locale's abbreviated weekday name (Sun-Sat).\n\
403 \n\
404 @item %A\n\
405 Locale's full weekday name, variable length (Sunday-Saturday).\n\
406 \n\
407 @item %b\n\
408 Locale's abbreviated month name (Jan-Dec).\n\
409 \n\
410 @item %B\n\
411 Locale's full month name, variable length (January-December).\n\
412 \n\
413 @item %c\n\
414 Locale's date and time (Sat Nov 04 12:02:33 EST 1989).\n\
415 \n\
416 @item %C\n\
417 Century (00-99).\n\
418 \n\
419 @item %d\n\
420 Day of month (01-31).\n\
421 \n\
422 @item %e\n\
423 Day of month ( 1-31).\n\
424 \n\
425 @item %D\n\
426 Date (mm/dd/yy).\n\
427 \n\
428 @item %h\n\
429 Same as %b.\n\
430 \n\
431 @item %j\n\
432 Day of year (001-366).\n\
433 \n\
434 @item %m\n\
435 Month (01-12).\n\
436 \n\
437 @item %U\n\
438 Week number of year with Sunday as first day of week (00-53).\n\
439 \n\
440 @item %w\n\
441 Day of week (0-6).\n\
442 \n\
443 @item %W\n\
444 Week number of year with Monday as first day of week (00-53).\n\
445 \n\
446 @item %x\n\
447 Locale's date representation (mm/dd/yy).\n\
448 \n\
449 @item %y\n\
450 Last two digits of year (00-99).\n\
451 \n\
452 @item %Y\n\
453 Year (1970-).\n\
454 @end table\n\
455 @seealso{strptime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
456 @end deftypefn")
457 {
458  octave_value retval;
459 
460  if (args.length () == 2)
461  {
462  std::string fmt = args(0).string_value ();
463 
464  if (! error_state)
465  {
466  octave_scalar_map map = args(1).scalar_map_value ();
467 
468  if (! error_state)
469  {
470  octave_base_tm tm = extract_tm (map);
471 
472  if (! error_state)
473  retval = tm.strftime (fmt);
474  else
475  error ("strftime: invalid TM_STRUCT argument");
476  }
477  else
478  error ("strftime: TM_STRUCT must be a structure");
479  }
480  else
481  error ("strftime: FMT must be a string");
482  }
483  else
484  print_usage ();
485 
486  return retval;
487 }
488 
489 /*
490 %!assert (ischar (strftime ("%%%n%t%H%I%k%l", localtime (time ()))));
491 %!assert (ischar (strftime ("%M%p%r%R%s%S%T", localtime (time ()))));
492 %!assert (ischar (strftime ("%X%Z%z%a%A%b%B", localtime (time ()))));
493 %!assert (ischar (strftime ("%c%C%d%e%D%h%j", localtime (time ()))));
494 %!assert (ischar (strftime ("%m%U%w%W%x%y%Y", localtime (time ()))));
495 
496 %!error strftime ()
497 %!error strftime ("foo", localtime (time ()), 1)
498 */
499 
500 DEFUN (strptime, args, ,
501  "-*- texinfo -*-\n\
502 @deftypefn {Built-in Function} {[@var{tm_struct}, @var{nchars}] =} strptime (@var{str}, @var{fmt})\n\
503 Convert the string @var{str} to the time structure @var{tm_struct} under\n\
504 the control of the format string @var{fmt}.\n\
505 \n\
506 If @var{fmt} fails to match, @var{nchars} is 0; otherwise, it is set to the\n\
507 position of last matched character plus 1. Always check for this unless\n\
508 you're absolutely sure the date string will be parsed correctly.\n\
509 @seealso{strftime, localtime, gmtime, mktime, time, now, date, clock, datenum, datestr, datevec, calendar, weekday}\n\
510 @end deftypefn")
511 {
512  octave_value_list retval;
513 
514  if (args.length () == 2)
515  {
516  std::string str = args(0).string_value ();
517 
518  if (! error_state)
519  {
520  std::string fmt = args(1).string_value ();
521 
522  if (! error_state)
523  {
524  octave_strptime t (str, fmt);
525 
526  retval(1) = t.characters_converted ();
527  retval(0) = octave_value (mk_tm_map (t));
528  }
529  else
530  error ("strptime: FMT must be a string");
531  }
532  else
533  error ("strptime: argument STR must be a string");
534  }
535  else
536  print_usage ();
537 
538  return retval;
539 }