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