GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
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