GNU Octave  6.2.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-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 <cmath>
31 #include <ctime>
32 
33 #include <iomanip>
34 #include <limits>
35 #include <ostream>
36 
37 #include "lo-error.h"
38 #include "lo-utils.h"
39 #include "oct-locbuf.h"
40 #include "oct-time.h"
42 #include "strftime-wrapper.h"
43 #include "strptime-wrapper.h"
44 #include "time-wrappers.h"
45 
46 namespace octave
47 {
48  namespace sys
49  {
50  time::time (double d)
51  : ot_unix_time (static_cast<time_t> (d)), ot_usec (0)
52  {
53  double ip;
54  ot_usec = static_cast<int> (std::modf (d, &ip) * 1e6);
55  }
56 
57  time::time (const base_tm& tm)
58  : ot_unix_time (), ot_usec ()
59  {
60  struct ::tm t;
61 
62  t.tm_sec = tm.sec ();
63  t.tm_min = tm.min ();
64  t.tm_hour = tm.hour ();
65  t.tm_mday = tm.mday ();
66  t.tm_mon = tm.mon ();
67  t.tm_year = tm.year ();
68  t.tm_wday = tm.wday ();
69  t.tm_yday = tm.yday ();
70  t.tm_isdst = tm.isdst ();
71 
72 #if defined (HAVE_TM_GMTOFF)
73  t.tm_gmtoff = tm.gmtoff ();
74 #endif
75 
76 #if defined (HAVE_STRUCT_TM_TM_ZONE)
77  std::string s = tm.zone ();
78  char *ps = strsave (s.c_str ());
79  t.tm_zone = ps;
80 #endif
81 
83 
84 #if defined (HAVE_STRUCT_TM_TM_ZONE)
85  delete [] ps;
86 #endif
87 
88  ot_usec = tm.usec ();
89  }
90 
91  std::string
92  time::ctime (void) const
93  {
94  return localtime (*this).asctime ();
95  }
96 
97  std::ostream&
98  operator << (std::ostream& os, const time& ot)
99  {
100  preserve_stream_state stream_state (os);
101 
102  os << ot.ot_unix_time << '.'
103  << std::setw (6) << std::setfill ('0') << ot.ot_usec;
104 
105  return os;
106  }
107 
108  void
109  time::stamp (void)
110  {
112  }
113 
114  // From the mktime() manual page:
115  //
116  // The mktime() function converts a broken-down time structure,
117  // expressed as local time, to calendar time representation.
118  //
119  // <snip>
120  //
121  // If structure members are outside their legal interval, they
122  // will be normalized (so that, e.g., 40 October is changed into
123  // 9 November).
124  //
125  // So, we no longer check limits here.
126 
127 #define DEFINE_SET_FIELD_FCN(type, f, lo, hi) \
128  base_tm& \
129  base_tm::f (type v) \
130  { \
131  m_ ## f = v; \
132  \
133  return *this; \
134  }
135 
136 #define DEFINE_SET_INT_FIELD_FCN(f, lo, hi) \
137  DEFINE_SET_FIELD_FCN (int, f, lo, hi)
138 
139  DEFINE_SET_INT_FIELD_FCN (usec, 0, 1000000)
145  DEFINE_SET_INT_FIELD_FCN (year, std::numeric_limits<int>::min (),
146  std::numeric_limitd<int>::max ())
150  DEFINE_SET_FIELD_FCN (long, gmtoff, -86400, 0)
151 
152  base_tm&
153  base_tm::zone (const std::string& s)
154  {
155  m_zone = s;
156  return *this;
157  }
158 
159 #if ! defined STRFTIME_BUF_INITIAL_SIZE
160 # define STRFTIME_BUF_INITIAL_SIZE 128
161 #endif
162 
163  std::string
164  base_tm::strftime (const std::string& fmt) const
165  {
166  std::string retval;
167 
168  if (! fmt.empty ())
169  {
170  struct ::tm t;
171 
172  t.tm_sec = m_sec;
173  t.tm_min = m_min;
174  t.tm_hour = m_hour;
175  t.tm_mday = m_mday;
176  t.tm_mon = m_mon;
177  t.tm_year = m_year;
178  t.tm_wday = m_wday;
179  t.tm_yday = m_yday;
180  t.tm_isdst = m_isdst;
181 
182 #if defined (HAVE_TM_GMTOFF)
183  t.tm_gmtoff = m_gmtoff;
184 #endif
185 
186 #if defined (HAVE_STRUCT_TM_TM_ZONE)
187  char *ps = strsave (m_zone.c_str ());
188  t.tm_zone = ps;
189 #endif
190 
191  const char *fmt_str = fmt.c_str ();
192 
193  char *buf = nullptr;
194  size_t bufsize = STRFTIME_BUF_INITIAL_SIZE;
195  size_t chars_written = 0;
196 
197  while (chars_written == 0)
198  {
199  delete [] buf;
200  buf = new char [bufsize];
201  buf[0] = '\0';
202 
203  chars_written
204  = octave_strftime_wrapper (buf, bufsize, fmt_str, &t);
205 
206  bufsize *= 2;
207  }
208 
209 #if defined (HAVE_STRUCT_TM_TM_ZONE)
210  delete [] ps;
211 #endif
212 
213  retval = buf;
214 
215  delete [] buf;
216  }
217 
218  return retval;
219  }
220 
221  void
222  base_tm::init (void *p)
223  {
224  if (! p)
225  return;
226 
227  struct ::tm *t = static_cast<struct ::tm *> (p);
228 
229  m_sec = t->tm_sec;
230  m_min = t->tm_min;
231  m_hour = t->tm_hour;
232  m_mday = t->tm_mday;
233  m_mon = t->tm_mon;
234  m_year = t->tm_year;
235  m_wday = t->tm_wday;
236  m_yday = t->tm_yday;
237  m_isdst = t->tm_isdst;
238 
239 #if defined (HAVE_TM_GMTOFF)
240  m_gmtoff = t->tm_gmtoff;
241 #endif
242 
243 #if defined (HAVE_STRUCT_TM_TM_ZONE)
244  if (t->tm_zone)
245  m_zone = t->tm_zone;
246 #elif defined (HAVE_TZNAME)
247  if (t->tm_isdst == 0 || t->tm_isdst == 1)
248  m_zone = tzname[t->tm_isdst];
249 #endif
250  }
251 
252  void
253  localtime::init (const time& ot)
254  {
255  m_usec = ot.usec ();
256 
257  time_t t = ot.unix_time ();
258 
259  base_tm::init (std::localtime (&t));
260  }
261 
262  void
263  gmtime::init (const time& ot)
264  {
265  m_usec = ot.usec ();
266 
267  time_t t = ot.unix_time ();
268 
269  base_tm::init (std::gmtime (&t));
270  }
271 
272  void
273  strptime::init (const std::string& str, const std::string& fmt)
274  {
275  struct ::tm t;
276 
277  t.tm_sec = 0;
278  t.tm_min = 0;
279  t.tm_hour = 0;
280  t.tm_mday = 0;
281  t.tm_mon = -1;
282  t.tm_year = std::numeric_limits<int>::min ();
283  t.tm_wday = 0;
284  t.tm_yday = 0;
285  t.tm_isdst = 0;
286 
287 #if defined (HAVE_TM_GMTOFF)
288  t.tm_gmtoff = 0;
289 #endif
290 
291 #if defined (HAVE_STRUCT_TM_TM_ZONE)
292  char *ps = strsave ("");
293  t.tm_zone = ps;
294 #endif
295 
296  const char *p = str.c_str ();
297 
298  char *q = octave_strptime_wrapper (p, fmt.c_str (), &t);
299 
300  // Fill in wday and yday, but only if mday is valid and the mon and year
301  // are filled in, avoiding issues with mktime and invalid dates.
302  if (t.tm_mday != 0 && t.tm_mon >= 0
303  && t.tm_year != std::numeric_limits<int>::min ())
304  {
305  t.tm_isdst = -1;
307  }
308 
309  if (t.tm_mon < 0)
310  t.tm_mon = 0;
311 
312  if (t.tm_year == std::numeric_limits<int>::min ())
313  t.tm_year = 0;
314 
315  if (q)
316  nchars = q - p + 1;
317  else
318  nchars = 0;
319 
320  base_tm::init (&t);
321 
322 #if defined (HAVE_STRUCT_TM_TM_ZONE)
323  delete [] ps;
324 #endif
325  }
326 
327  void
329  {
331  }
332 
333  void
335  {
336  time_t usr_sec, sys_sec;
337  long usr_usec, sys_usec;
338 
339  octave_getrusage_wrapper (&usr_sec, &sys_sec, &usr_usec,
340  &sys_usec, &m_maxrss, &m_ixrss,
341  &m_idrss, &m_isrss, &m_minflt,
345 
346  m_cpu = cpu_time (usr_sec, sys_sec, usr_usec, sys_usec);
347  }
348  }
349 }
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
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
void init(void *p)
Definition: oct-time.cc:222
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
std::string m_zone
Definition: oct-time.h:296
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
std::string asctime(void) const
Definition: oct-time.h:257
long gmtoff(void) const
Definition: oct-time.h:239
int year(void) const
Definition: oct-time.h:235
void init(const time &ot)
Definition: oct-time.cc:263
void init(const time &ot)
Definition: oct-time.cc:253
void init(const std::string &str, const std::string &fmt)
Definition: oct-time.cc:273
long usec(void) const
Definition: oct-time.h:115
void stamp(void)
Definition: oct-time.cc:109
time_t ot_unix_time
Definition: oct-time.h:124
std::string ctime(void) const
Definition: oct-time.cc:92
time_t unix_time(void) const
Definition: oct-time.h:113
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
static char * strsave(const char *s)
Definition: main.in.cc:195
std::ostream & operator<<(std::ostream &os, const time &ot)
Definition: oct-time.cc:98
#define DEFINE_SET_INT_FIELD_FCN(f, lo, hi)
Definition: oct-time.cc:136
#define STRFTIME_BUF_INITIAL_SIZE
Definition: oct-time.cc:160
#define DEFINE_SET_FIELD_FCN(type, f, lo, hi)
Definition: oct-time.cc:127
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
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