GNU Octave  8.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
oct-time.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1999-2023 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 <cmath>
31 #include <ctime>
32 
33 #include <iomanip>
34 #include <limits>
35 #include <ostream>
36 
37 #if defined (OCTAVE_USE_WINDOWS_API)
38 # include <windows.h>
39 #endif
40 
41 #include "lo-error.h"
42 #include "lo-utils.h"
43 #include "lo-sysdep.h"
44 #include "oct-locbuf.h"
45 #include "oct-time.h"
47 #include "strftime-wrapper.h"
48 #include "strptime-wrapper.h"
49 #include "time-wrappers.h"
50 
52 
54 
55 time::time (double d)
56  : m_ot_unix_time (static_cast<OCTAVE_TIME_T> (d)), m_ot_usec (0)
57 {
58  double ip;
59  m_ot_usec = static_cast<int> (std::modf (d, &ip) * 1e6);
60 }
61 
62 time::time (const base_tm& tm)
63  : m_ot_unix_time (), m_ot_usec ()
64 {
65  struct ::tm t;
66 
67  t.tm_sec = tm.sec ();
68  t.tm_min = tm.min ();
69  t.tm_hour = tm.hour ();
70  t.tm_mday = tm.mday ();
71  t.tm_mon = tm.mon ();
72  t.tm_year = tm.year ();
73  t.tm_wday = tm.wday ();
74  t.tm_yday = tm.yday ();
75  t.tm_isdst = tm.isdst ();
76 
77 #if defined (HAVE_TM_GMTOFF)
78  t.tm_gmtoff = tm.gmtoff ();
79 #endif
80 
81 #if defined (HAVE_STRUCT_TM_TM_ZONE)
82  std::string s = tm.zone ();
83  char *ps = strsave (s.c_str ());
84  t.tm_zone = ps;
85 #endif
86 
88 
89 #if defined (HAVE_STRUCT_TM_TM_ZONE)
90  delete [] ps;
91 #endif
92 
93  m_ot_usec = tm.usec ();
94 }
95 
96 std::string
97 time::ctime (void) const
98 {
99  return localtime (*this).asctime ();
100 }
101 
102 std::ostream&
103 operator << (std::ostream& os, const time& ot)
104 {
105  preserve_stream_state stream_state (os);
106 
107  os << ot.m_ot_unix_time << '.'
108  << std::setw (6) << std::setfill ('0') << ot.m_ot_usec;
109 
110  return os;
111 }
112 
113 void
115 {
116  time_t ot_unix_time;
117  octave_gettimeofday_wrapper (&ot_unix_time, &m_ot_usec);
118  m_ot_unix_time = ot_unix_time;
119 }
120 
121 // From the mktime() manual page:
122 //
123 // The mktime() function converts a broken-down time structure,
124 // expressed as local time, to calendar time representation.
125 //
126 // <snip>
127 //
128 // If structure members are outside their legal interval, they
129 // will be normalized (so that, e.g., 40 October is changed into
130 // 9 November).
131 //
132 // So, we no longer check limits here.
133 
134 #define DEFINE_SET_FIELD_FCN(type, f, lo, hi) \
135  base_tm& \
136  base_tm::f (type v) \
137  { \
138  m_ ## f = v; \
139  \
140  return *this; \
141  }
142 
143 #define DEFINE_SET_INT_FIELD_FCN(f, lo, hi) \
144  DEFINE_SET_FIELD_FCN (int, f, lo, hi)
145 
146 DEFINE_SET_INT_FIELD_FCN (usec, 0, 1000000)
152 DEFINE_SET_INT_FIELD_FCN (year, std::numeric_limits<int>::min (),
153  std::numeric_limitd<int>::max ())
157 DEFINE_SET_FIELD_FCN (long, gmtoff, -86400, 0)
158 
159 base_tm&
160 base_tm::zone (const std::string& s)
161 {
162  m_zone = s;
163  return *this;
164 }
165 
166 #if ! defined STRFTIME_BUF_INITIAL_SIZE
167 # define STRFTIME_BUF_INITIAL_SIZE 128
168 #endif
169 
170 std::string
171 base_tm::strftime (const std::string& fmt) const
172 {
173  std::string retval;
174 
175  if (! fmt.empty ())
176  {
177  struct ::tm t;
178 
179  t.tm_sec = m_sec;
180  t.tm_min = m_min;
181  t.tm_hour = m_hour;
182  t.tm_mday = m_mday;
183  t.tm_mon = m_mon;
184  t.tm_year = m_year;
185  t.tm_wday = m_wday;
186  t.tm_yday = m_yday;
187  t.tm_isdst = m_isdst;
188 
189 #if defined (HAVE_TM_GMTOFF)
190  t.tm_gmtoff = m_gmtoff;
191 #endif
192 
193 #if defined (HAVE_STRUCT_TM_TM_ZONE)
194  char *ps = strsave (m_zone.c_str ());
195  t.tm_zone = ps;
196 #endif
197 
198  const char *fmt_str = fmt.c_str ();
199 
200  char *buf = nullptr;
201  std::size_t bufsize = STRFTIME_BUF_INITIAL_SIZE;
202  std::size_t chars_written = 0;
203 
204  while (chars_written == 0)
205  {
206  delete [] buf;
207  buf = new char [bufsize];
208  buf[0] = '\0';
209 
210  chars_written
211  = octave_strftime_wrapper (buf, bufsize, fmt_str, &t);
212 
213  bufsize *= 2;
214  }
215 
216 #if defined (HAVE_STRUCT_TM_TM_ZONE)
217  delete [] ps;
218 #endif
219 
220  retval = buf;
221 
222  delete [] buf;
223  }
224 
225  return retval;
226 }
227 
228 void
229 base_tm::init (void *p)
230 {
231  if (! p)
232  return;
233 
234  struct ::tm *t = static_cast<struct ::tm *> (p);
235 
236  m_sec = t->tm_sec;
237  m_min = t->tm_min;
238  m_hour = t->tm_hour;
239  m_mday = t->tm_mday;
240  m_mon = t->tm_mon;
241  m_year = t->tm_year;
242  m_wday = t->tm_wday;
243  m_yday = t->tm_yday;
244  m_isdst = t->tm_isdst;
245 
246 #if defined (HAVE_TM_GMTOFF)
247  m_gmtoff = t->tm_gmtoff;
248 #elif defined (OCTAVE_USE_WINDOWS_API)
249  TIME_ZONE_INFORMATION tzi;
250 
251  GetTimeZoneInformationForYear (m_year, nullptr, &tzi);
252 
253  if (m_isdst)
254  m_gmtoff = -60 * (tzi.Bias + tzi.DaylightBias);
255  else
256  m_gmtoff = -60 * (tzi.Bias + tzi.StandardBias);
257 #endif
258 
259 #if defined (HAVE_STRUCT_TM_TM_ZONE)
260  if (t->tm_zone)
261  m_zone = t->tm_zone;
262 #elif defined (OCTAVE_USE_WINDOWS_API)
263  if (m_isdst)
264  m_zone = sys::u8_from_wstring (tzi.DaylightName);
265  else
266  m_zone = sys::u8_from_wstring (tzi.StandardName);
267 #elif defined (HAVE_TZNAME)
268  if (t->tm_isdst == 0 || t->tm_isdst == 1)
269  m_zone = tzname[t->tm_isdst];
270 #endif
271 }
272 
273 void
275 {
276  m_usec = ot.usec ();
277 
278  time_t t = ot.unix_time ();
279 
280  base_tm::init (std::localtime (&t));
281 }
282 
283 void
284 gmtime::init (const time& ot)
285 {
286  m_usec = ot.usec ();
287 
288  time_t t = ot.unix_time ();
289 
290  base_tm::init (std::gmtime (&t));
291 }
292 
293 void
294 strptime::init (const std::string& str, const std::string& fmt)
295 {
296  struct ::tm t;
297 
298  t.tm_sec = 0;
299  t.tm_min = 0;
300  t.tm_hour = 0;
301  t.tm_mday = 0;
302  t.tm_mon = -1;
303  t.tm_year = std::numeric_limits<int>::min ();
304  t.tm_wday = 0;
305  t.tm_yday = 0;
306  t.tm_isdst = 0;
307 
308 #if defined (HAVE_TM_GMTOFF)
309  t.tm_gmtoff = 0;
310 #endif
311 
312 #if defined (HAVE_STRUCT_TM_TM_ZONE)
313  char *ps = strsave ("");
314  t.tm_zone = ps;
315 #endif
316 
317  const char *p = str.c_str ();
318 
319  char *q = octave_strptime_wrapper (p, fmt.c_str (), &t);
320 
321  // Fill in wday and yday, but only if mday is valid and the mon and year
322  // are filled in, avoiding issues with mktime and invalid dates.
323  if (t.tm_mday != 0 && t.tm_mon >= 0
324  && t.tm_year != std::numeric_limits<int>::min ())
325  {
326  t.tm_isdst = -1;
328  }
329 
330  if (t.tm_mon < 0)
331  t.tm_mon = 0;
332 
333  if (t.tm_year == std::numeric_limits<int>::min ())
334  t.tm_year = 0;
335 
336  if (q)
337  m_nchars = q - p + 1;
338  else
339  m_nchars = 0;
340 
341  base_tm::init (&t);
342 
343 #if defined (HAVE_STRUCT_TM_TM_ZONE)
344  delete [] ps;
345 #endif
346 }
347 
348 void
350 {
351  time_t usr_sec, sys_sec;
352  octave_cpu_time (&usr_sec, &sys_sec, &m_usr_usec, &m_sys_usec);
353  m_usr_sec = usr_sec;
354  m_sys_sec = sys_sec;
355 }
356 
357 void
359 {
360  time_t usr_sec, sys_sec;
361  long usr_usec, sys_usec;
362 
363  octave_getrusage_wrapper (&usr_sec, &sys_sec, &usr_usec,
364  &sys_usec, &m_maxrss, &m_ixrss,
365  &m_idrss, &m_isrss, &m_minflt,
369 
370  m_cpu = cpu_time (usr_sec, sys_sec, usr_usec, sys_usec);
371 }
372 
OCTAVE_END_NAMESPACE(octave)
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
int yday(void) const
Definition: oct-time.h:233
int usec(void) const
Definition: oct-time.h:225
long gmtoff(void) const
Definition: oct-time.h:235
int m_sec
Definition: oct-time.h:262
int m_isdst
Definition: oct-time.h:286
int m_year
Definition: oct-time.h:277
int m_usec
Definition: oct-time.h:259
int m_mday
Definition: oct-time.h:271
int m_min
Definition: oct-time.h:265
std::string m_zone
Definition: oct-time.h:292
int sec(void) const
Definition: oct-time.h:226
std::string asctime(void) const
Definition: oct-time.h:253
OCTAVE_API void init(void *p)
Definition: oct-time.cc:229
long m_gmtoff
Definition: oct-time.h:289
int m_hour
Definition: oct-time.h:268
int wday(void) const
Definition: oct-time.h:232
std::string zone(void) const
Definition: oct-time.h:236
int mday(void) const
Definition: oct-time.h:229
int m_wday
Definition: oct-time.h:280
int year(void) const
Definition: oct-time.h:231
int min(void) const
Definition: oct-time.h:227
OCTAVE_API std::string strftime(const std::string &fmt) const
Definition: oct-time.cc:171
int m_yday
Definition: oct-time.h:283
int hour(void) const
Definition: oct-time.h:228
int mon(void) const
Definition: oct-time.h:230
int m_mon
Definition: oct-time.h:274
int isdst(void) const
Definition: oct-time.h:234
OCTAVE_TIME_T m_usr_sec
Definition: oct-time.h:431
long m_sys_usec
Definition: oct-time.h:435
OCTAVE_TIME_T m_sys_sec
Definition: oct-time.h:432
OCTAVE_API void stamp(void)
Definition: oct-time.cc:349
long m_usr_usec
Definition: oct-time.h:434
OCTAVE_API void init(const time &ot)
Definition: oct-time.cc:284
OCTAVE_API void init(const time &ot)
Definition: oct-time.cc:274
long m_nsignals
Definition: oct-time.h:527
cpu_time m_cpu
Definition: oct-time.h:514
long m_oublock
Definition: oct-time.h:524
OCTAVE_API void stamp(void)
Definition: oct-time.cc:358
long m_inblock
Definition: oct-time.h:523
int m_nchars
Definition: oct-time.h:375
OCTAVE_API void init(const std::string &str, const std::string &fmt)
Definition: oct-time.cc:294
Definition: oct-time.h:52
long m_ot_usec
Definition: oct-time.h:124
OCTAVE_TIME_T unix_time(void) const
Definition: oct-time.h:110
OCTAVE_API std::string ctime(void) const
Definition: oct-time.cc:97
long usec(void) const
Definition: oct-time.h:112
OCTAVE_TIME_T m_ot_unix_time
Definition: oct-time.h:121
time(void)
Definition: oct-time.h:55
OCTAVE_API void stamp(void)
Definition: oct-time.cc:114
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
std::string u8_from_wstring(const std::wstring &wchar_string)
Definition: lo-sysdep.cc:537
static char * strsave(const char *s)
Definition: main.in.cc:214
#define DEFINE_SET_INT_FIELD_FCN(f, lo, hi)
Definition: oct-time.cc:143
#define STRFTIME_BUF_INITIAL_SIZE
Definition: oct-time.cc:167
std::ostream & operator<<(std::ostream &os, const time &ot)
Definition: oct-time.cc:103
#define DEFINE_SET_FIELD_FCN(type, f, lo, hi)
Definition: oct-time.cc:134
size_t octave_strftime_wrapper(char *buf, size_t len, const char *fmt, const struct tm *t)
char * octave_strptime_wrapper(const char *p, const char *fmt, struct tm *t)
int octave_cpu_time(time_t *usr_sec, time_t *sys_sec, long *usr_usec, long *sys_usec)
Definition: time-wrappers.c:63
int octave_gettimeofday_wrapper(time_t *sec, long *usec)
Definition: time-wrappers.c:42
time_t octave_mktime_wrapper(struct tm *tp)
int octave_getrusage_wrapper(time_t *usr_sec, time_t *sys_sec, long *usr_usec, long *sys_usec, long *maxrss, long *ixrss, long *idrss, long *isrss, long *minflt, long *majflt, long *nswap, long *inblock, long *oublock, long *msgsnd, long *msgrcv, long *nsignals, long *nvcsw, long *nivcsw)
Definition: time-wrappers.c:91