GNU Octave 7.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-2022 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
39OCTAVE_NAMESPACE_BEGIN
40
41// Date and time functions.
42
44mk_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
64static inline int
65intfield (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
77static inline std::string
78stringfield (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
90static sys::base_tm
91extract_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
111DEFUN (time, args, ,
112 doc: /* -*- texinfo -*-
113@deftypefn {} {@var{seconds} =} time ()
114Return the current time as the number of seconds since the epoch.
115
116The epoch is referenced to 00:00:00 UTC (Coordinated Universal Time) 1 Jan
1171970. For example, on Monday February 17, 1997 at 07:15:06 UTC, the value
118returned by @code{time} was 856163706.
119@seealso{strftime, strptime, localtime, gmtime, mktime, now, date, clock,
120datenum, 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
135DEFUN (gmtime, args, ,
136 doc: /* -*- texinfo -*-
137@deftypefn {} {@var{tm_struct} =} gmtime (@var{t})
138Given a value returned from @code{time}, or any non-negative integer,
139return a time structure corresponding to UTC (Coordinated Universal Time).
140
141For example:
142
143@example
144@group
145gmtime (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,
163datestr, 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
193DEFUN (localtime, args, ,
194 doc: /* -*- texinfo -*-
195@deftypefn {} {@var{tm_struct} =} localtime (@var{t})
196Given a value returned from @code{time}, or any non-negative integer,
197return a time structure corresponding to the local time zone.
198
199@example
200@group
201localtime (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,
219datestr, 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
249DEFUN (mktime, args, ,
250 doc: /* -*- texinfo -*-
251@deftypefn {} {@var{seconds} =} mktime (@var{tm_struct})
252Convert a time structure corresponding to the local time to the number of
253seconds since the epoch.
254
255For example:
256
257@example
258@group
259mktime (localtime (time ()))
260 @result{} 856163706
261@end group
262@end example
263@seealso{strftime, strptime, localtime, gmtime, time, now, date, clock, datenum,
264datestr, 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
294DEFUN (strftime, args, ,
295 doc: /* -*- texinfo -*-
296@deftypefn {} {} strftime (@var{fmt}, @var{tm_struct})
297Format the time structure @var{tm_struct} in a flexible way using the format
298string @var{fmt} that contains @samp{%} substitutions similar to those in
299@code{printf}.
300
301Except where noted, substituted fields have a fixed size; numeric fields are
302padded if necessary. Padding is with zeros by default; for fields that
303display a single number, padding can be changed or inhibited by following
304the @samp{%} with one of the modifiers described below. Unknown field
305specifiers are copied as normal characters. All other characters are copied
306to the output without change. For example:
307
308@example
309@group
310strftime ("%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
315Octave's @code{strftime} function supports a superset of the ANSI C field
316specifiers.
317
318@noindent
319Literal character fields:
320
321@table @code
322@item %%
323% character.
324
325@item %n
326Newline character.
327
328@item %t
329Tab character.
330@end table
331
332@noindent
333Numeric modifiers (a nonstandard extension):
334
335@table @code
336@item - (dash)
337Do not pad the field.
338
339@item _ (underscore)
340Pad the field with spaces.
341@end table
342
343@noindent
344Time fields:
345
346@table @code
347@item %H
348Hour (00-23).
349
350@item %I
351Hour (01-12).
352
353@item %k
354Hour (0-23).
355
356@item %l
357Hour (1-12).
358
359@item %M
360Minute (00-59).
361
362@item %p
363Locale's AM or PM.
364
365@item %r
366Time, 12-hour (hh:mm:ss [AP]M).
367
368@item %R
369Time, 24-hour (hh:mm).
370
371@item %s
372Time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension).
373
374@item %S
375Second (00-61).
376
377@item %T
378Time, 24-hour (hh:mm:ss).
379
380@item %X
381Locale's time representation (%H:%M:%S).
382
383@item %z
384Offset from UTC (±@nospell{hhmm}), or nothing if no time zone is
385determinable.
386
387@item %Z
388Time zone (EDT), or nothing if no time zone is determinable.
389@end table
390
391@noindent
392Date fields:
393
394@table @code
395@item %a
396Locale's abbreviated weekday name (Sun-Sat).
397
398@item %A
399Locale's full weekday name, variable length (Sunday-Saturday).
400
401@item %b
402Locale's abbreviated month name (Jan-Dec).
403
404@item %B
405Locale's full month name, variable length (January-December).
406
407@item %c
408Locale's date and time (Sat Nov 04 12:02:33 EST 1989).
409
410@item %C
411Century (00-99).
412
413@item %d
414Day of month (01-31).
415
416@item %e
417Day of month ( 1-31).
418
419@item %D
420Date (mm/dd/yy).
421
422@item %h
423Same as %b.
424
425@item %j
426Day of year (001-366).
427
428@item %m
429Month (01-12).
430
431@item %U
432Week number of year with Sunday as first day of week (00-53).
433
434@item %w
435Day of week (0-6).
436
437@item %W
438Week number of year with Monday as first day of week (00-53).
439
440@item %x
441Locale's date representation (mm/dd/yy).
442
443@item %y
444Last two digits of year (00-99).
445
446@item %Y
447Year (1970-).
448@end table
449@seealso{strptime, localtime, gmtime, mktime, time, now, date, clock, datenum,
450datestr, 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
478DEFUN (strptime, args, ,
479 doc: /* -*- texinfo -*-
480@deftypefn {} {[@var{tm_struct}, @var{nchars}] =} strptime (@var{str}, @var{fmt})
481Convert the string @var{str} to the time structure @var{tm_struct} under
482the control of the format string @var{fmt}.
483
484If @var{fmt} fails to match, @var{nchars} is 0; otherwise, it is set to the
485position of last matched character plus 1. Always check for this unless
486you're absolutely sure the date string will be parsed correctly.
487@seealso{strftime, localtime, gmtime, mktime, time, now, date, clock, datenum,
488datestr, 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
523OCTAVE_NAMESPACE_END
void assign(const std::string &k, const octave_value &val)
Definition: oct-map.h:238
octave_value getfield(const std::string &key) const
Definition: oct-map.cc:183
OCTINTERP_API std::string xstring_value(const char *fmt,...) const
OCTINTERP_API int xint_value(const char *fmt,...) const
bool isempty(void) const
Definition: ov.h:646
OCTINTERP_API 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::size_type numel(const T &str)
Definition: oct-string.cc:71
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
static std::string stringfield(const octave_scalar_map &m, const std::string &k, const char *who)
Definition: time.cc:78
static int intfield(const octave_scalar_map &m, const std::string &k, const char *who)
Definition: time.cc:65
static OCTAVE_NAMESPACE_BEGIN octave_scalar_map mk_tm_map(const sys::base_tm &t)
Definition: time.cc:44
static sys::base_tm extract_tm(const octave_scalar_map &m, const char *who)
Definition: time.cc:91