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