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