QOF: qoftime.c Source File

QOF 0.7.5

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

qoftime.c
1 /********************************************************************
2 * qoftime.c - QofTime, 64bit UTC time handling (seconds).
3 * Rewritten from scratch for QOF 0.7.0
4 *
5 * Fri May 5 15:05:24 2006
6 * Copyright 2006 Neil Williams
7 * linux@codehelp.co.uk
8 ********************************************************************/
9 /*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but 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 this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
23 */
24
25 #include "config.h"
26 #include <glib.h>
27 #include <math.h>
28 #include <ctype.h>
29 #include <time.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include "qof.h"
34 #include "qofdate-p.h"
35
36 static QofLogModule log_module = QOF_MOD_TIME;
37
38 struct QofTime64
39 {
40 QofTimeSecs qt_sec;
41 glong qt_nsec;
42 gboolean valid;
43 };
44
45 QofTime *
46 qof_time_new (void)
47 {
48 QofTime *qt;
49
50 qt = g_new0 (QofTime, 1);
51 qt->valid = FALSE;
52 return qt;
53 }
54
55 void
56 qof_time_free (QofTime * qt)
57 {
58 if (qt == NULL)
59 return;
60 g_free (qt);
61 qt = NULL;
62 }
63
64 void
65 qof_time_add_secs (QofTime * qt, QofTimeSecs secs)
66 {
67 g_return_if_fail (qt);
68 g_return_if_fail (qt->valid);
69 qt->qt_sec += secs;
70 }
71
72 QofTime *
73 qof_time_add_secs_copy (QofTime * qt, QofTimeSecs secs)
74 {
75 QofTime *copy;
76
77 g_return_val_if_fail (qt, NULL);
78 g_return_val_if_fail (qt->valid, NULL);
79 copy = qof_time_copy (qt);
80 copy->qt_sec += secs;
81 return copy;
82 }
83
84 static QofTime *
85 time_normalize (QofTime * qt)
86 {
87 g_return_val_if_fail (qt->valid, NULL);
88 if ((qt->qt_sec < 0) && (qt->qt_nsec > QOF_NSECS))
89 {
90 qt->qt_sec -= (qt->qt_nsec / QOF_NSECS);
91 qt->qt_nsec = qt->qt_nsec % QOF_NSECS;
92 }
93 if ((qt->qt_sec >= 0) && (qt->qt_nsec > QOF_NSECS))
94 {
95 qt->qt_sec += (qt->qt_nsec / QOF_NSECS);
96 qt->qt_nsec = qt->qt_nsec % QOF_NSECS;
97 }
98 if ((qt->qt_sec < 0) && (qt->qt_nsec < -QOF_NSECS))
99 {
100 qt->qt_sec -= -(-qt->qt_nsec / QOF_NSECS);
101 qt->qt_nsec = -(-qt->qt_nsec % QOF_NSECS);
102 }
103 if ((qt->qt_sec >= 0) && (qt->qt_nsec < -QOF_NSECS))
104 {
105 qt->qt_sec += -(-qt->qt_nsec / QOF_NSECS);
106 qt->qt_nsec = -(-qt->qt_nsec % QOF_NSECS);
107 }
108 if (qt->qt_sec >= 0 && qt->qt_nsec < 0)
109 {
110 qt->qt_sec--;
111 qt->qt_nsec = QOF_NSECS + qt->qt_nsec;
112 }
113 return qt;
114 }
115
116 void
117 qof_time_set_secs (QofTime * qt, QofTimeSecs secs)
118 {
119 qt->qt_sec = secs;
120 qt->valid = TRUE;
121 time_normalize (qt);
122 }
123
124 void
125 qof_time_set_nanosecs (QofTime * qt, glong nano)
126 {
127 qt->qt_nsec = nano;
128 qt->valid = TRUE;
129 time_normalize (qt);
130 }
131
132 QofTimeSecs
133 qof_time_get_secs (const QofTime * qt)
134 {
135 g_return_val_if_fail (qt, 0);
136 g_return_val_if_fail (qt->valid == TRUE, 0);
137 return qt->qt_sec;
138 }
139
140 glong
141 qof_time_get_nanosecs (const QofTime * qt)
142 {
143 g_return_val_if_fail (qt->valid == TRUE, 0);
144 return qt->qt_nsec;
145 }
146
147 gboolean
148 qof_time_equal (const QofTime * ta, const QofTime * tb)
149 {
150 if (ta == tb)
151 return TRUE;
152 if (!ta)
153 return FALSE;
154 if (!tb)
155 return FALSE;
156 g_return_val_if_fail (ta->valid && tb->valid, FALSE);
157 if (ta->qt_sec != tb->qt_sec)
158 return FALSE;
159 if (ta->qt_nsec != tb->qt_nsec)
160 return FALSE;
161 return TRUE;
162 }
163
164 gint
165 qof_time_cmp (const QofTime * ta, const QofTime * tb)
166 {
167 g_return_val_if_fail (ta->valid && tb->valid, -1);
168 if (ta == tb)
169 return 0;
170 if (ta->qt_sec < tb->qt_sec)
171 return -1;
172 if (ta->qt_sec > tb->qt_sec)
173 return 1;
174 if (ta->qt_nsec < tb->qt_nsec)
175 return -1;
176 if (ta->qt_nsec > tb->qt_nsec)
177 return 1;
178 return 0;
179 }
180
181 QofTime *
182 qof_time_diff (const QofTime * ta, const QofTime * tb)
183 {
184 QofTime *retval;
185
186 g_return_val_if_fail (ta->valid && tb->valid, NULL);
187 retval = g_new0 (QofTime, 1);
188 retval->qt_sec = ta->qt_sec - tb->qt_sec;
189 retval->qt_nsec = ta->qt_nsec - tb->qt_nsec;
190 retval->valid = TRUE;
191 time_normalize (retval);
192 return retval;
193 }
194
195 QofTime *
196 qof_time_abs (QofTime * qt)
197 {
198 g_return_val_if_fail (qt, NULL);
199 return time_normalize (qt);
200 }
201
202 gboolean
203 qof_time_is_valid (const QofTime * qt)
204 {
205 g_return_val_if_fail (qt, FALSE);
206 return qt->valid;
207 }
208
209 QofTime *
210 qof_time_set (QofTimeSecs t, glong nanosecs)
211 {
212 QofTime *qt;
213
214 qt = qof_time_new ();
215 qt->qt_sec = t;
216 qt->qt_nsec = nanosecs;
217 qt->valid = TRUE;
218 time_normalize (qt);
219 return qt;
220 }
221
222 QofTime *
223 qof_time_copy (const QofTime *qt)
224 {
225 g_return_val_if_fail (qt, NULL);
226 g_return_val_if_fail (qt->valid, NULL);
227 return qof_time_set (qt->qt_sec, qt->qt_nsec);
228 }
229
230 QofTime *
231 qof_time_from_time_t (time_t t, glong nanosecs)
232 {
233 return qof_time_set (t, nanosecs);
234 }
235
236 gboolean
237 qof_time_to_time_t (QofTime * qt, time_t * t, glong * nanosecs)
238 {
239 if (!qt->valid)
240 return FALSE;
241 if (qt->qt_sec < 0)
242 return FALSE;
243 if (qt->qt_nsec > 0)
244 {
245 *nanosecs = qt->qt_nsec;
246 }
247 if ((sizeof (qt->qt_sec) > sizeof (time_t))
248 && (qt->qt_sec > G_MAXINT32))
249 {
250 PERR (" QofTime too large for time_t on this platform.");
251 return FALSE;
252 }
253 *t = qt->qt_sec;
254 return TRUE;
255 }
256
257 QofTime *
258 qof_time_from_tm (struct tm * qtm, glong nanosecs)
259 {
260 QofDate *qd;
261 QofTime *qt;
262
263 /* avoids use of gmtime_r and therefore time_t */
264 qd = qof_date_from_struct_tm (qtm);
265 qd->qd_nanosecs = nanosecs;
266 qt = qof_date_to_qtime (qd);
267 qof_date_free (qd);
268 return qt;
269 }
270
271 gboolean
272 qof_time_to_gtimeval (QofTime * qt, GTimeVal * gtv)
273 {
274 if (!qt->valid)
275 {
276 PERR (" invalid QofTime passed");
277 return FALSE;
278 }
279 if (qt->qt_sec > G_MAXLONG)
280 {
281 PERR (" QofTime out of range for GTimeVal");
282 return FALSE;
283 }
284 gtv->tv_sec = (glong) qt->qt_sec;
285 gtv->tv_usec = qt->qt_nsec;
286 return TRUE;
287 }
288
289 void
290 qof_time_from_gtimeval (QofTime * qt, GTimeVal * gtv)
291 {
292 qt->qt_sec = (QofTimeSecs) gtv->tv_sec;
293 qt->qt_nsec = gtv->tv_usec * 1000;
294 qt->valid = TRUE;
295 time_normalize (qt);
296 }
297
298 GDate *
299 qof_time_to_gdate (QofTime * qt)
300 {
301 QofDate *qd;
302 GDate *d;
303
304 qd = qof_date_from_qtime (qt);
305 d = g_date_new_dmy (qd->qd_mday, qd->qd_mon, qd->qd_year);
306 if (g_date_valid (d))
307 return d;
308 return NULL;
309 }
310
311 QofTime *
312 qof_time_from_gdate (GDate * date)
313 {
314 struct tm gtm;
315 QofTime *qt;
316 QofDate *qd;
317
318 g_return_val_if_fail (date, NULL);
319 g_date_to_struct_tm (date, &gtm);
320 qd = qof_date_from_struct_tm (&gtm);
321 qt = qof_date_to_qtime (qd);
322 qof_date_free (qd);
323 return qt;
324 }
325
326 gboolean
327 qof_time_set_day_end (QofTime * qt)
328 {
329 if (!qof_time_set_day_start (qt))
330 return FALSE;
331 qt->qt_sec += (SECS_PER_DAY - 1);
332 return TRUE;
333 }
334
335 gboolean
336 qof_time_set_day_middle (QofTime * qt)
337 {
338 if (!qof_time_set_day_start (qt))
339 return FALSE;
340 qt->qt_sec += (SECS_PER_DAY / 2);
341 return TRUE;
342 }
343
344 GTimeVal *
345 qof_time_get_current_start (void)
346 {
347 GTimeVal *current;
348 struct tm tm;
349
351 current = g_new0 (GTimeVal, 1);
352 g_get_current_time (current);
353 /* OK to use time_t for current time. */
354 tm = *gmtime_r (&current->tv_sec, &tm);
355 current->tv_sec -= tm.tm_sec;
356 current->tv_sec -= tm.tm_min * 60;
357 current->tv_sec -= tm.tm_hour * 60 * 60;
358 return current;
359 }
360
361 QofTime *
362 qof_time_get_current (void)
363 {
364 QofTime *now;
365 GTimeVal gnow;
366
367 now = qof_time_new ();
368 g_get_current_time (&gnow);
369 qof_time_from_gtimeval (now, &gnow);
370 return now;
371 }
372
373 gboolean
374 qof_time_set_day_start (QofTime * qt)
375 {
376 QofDate *qd;
377 QofTimeSecs c;
378
379 g_return_val_if_fail (qt, FALSE);
380 qd = qof_date_from_qtime (qt);
381 if (qd->qd_year < 1970)
382 {
383 c = QOF_DAYS_TO_SEC(qd->qd_yday);
384 c -= QOF_DAYS_TO_SEC(days_between (1970, qd->qd_year));
385 c -= qd->qd_gmt_off;
386 qt->qt_sec = c;
387 qt->qt_nsec = 0;
388 }
389 if (qd->qd_year >= 1970)
390 {
391 c = QOF_DAYS_TO_SEC(qd->qd_yday);
392 c += QOF_DAYS_TO_SEC(days_between (1970, qd->qd_year));
393 c -= qd->qd_gmt_off;
394 qt->qt_sec = c;
395 qt->qt_nsec = 0;
396 }
397 qof_date_free (qd);
398 return TRUE;
399 }
400
401 QofTime *
402 qof_time_get_today_start (void)
403 {
404 QofTime *qt;
405
406 qt = qof_time_get_current ();
407 if (!qof_time_set_day_start (qt))
408 return NULL;
409 return qt;
410 }
411
412 QofTime *
413 qof_time_get_today_end (void)
414 {
415 QofTime *qt;
416
417 qt = qof_time_get_today_start ();
418 qt->qt_sec += SECS_PER_DAY - 1;
419 return qt;
420 }
421
422 guint8
423 qof_time_last_mday (QofTime * qt)
424 {
425 GDate *d;
426 GDateMonth m;
427 GDateYear y;
428
429 g_return_val_if_fail (qt, 0);
430 d = qof_time_to_gdate (qt);
431 if (!d)
432 return 0;
433 m = g_date_get_month (d);
434 y = g_date_get_year (d);
435 return g_date_get_days_in_month (m, y);
436 }
437
438 gboolean
439 qof_time_to_dmy (QofTime * qt, guint8 * day, guint8 * month,
440 guint16 * year)
441 {
442 GDate *d;
443
444 d = qof_time_to_gdate (qt);
445 if (!d)
446 return FALSE;
447 if (day)
448 *day = g_date_get_day (d);
449 if (month)
450 *month = g_date_get_month (d);
451 if (year)
452 *year = g_date_get_year (d);
453 return TRUE;
454 }
455
456 QofTime *
457 qof_time_dmy_to_time (guint8 day, guint8 month, guint16 year)
458 {
459 GDate *d;
460 QofTime *qt;
461
462 g_return_val_if_fail (g_date_valid_dmy (day, month, year), NULL);
463 d = g_date_new_dmy (day, month, year);
464 qt = qof_time_from_gdate (d);
465 return qt;
466 }
467
468 gchar *
469 qof_time_stamp_now (void)
470 {
471 gint len;
472 struct tm qtm;
473 time_t t;
474 gchar test[MAX_DATE_LENGTH];
475 const gchar *fmt;
476
477 ENTER (" ");
478 t = time (NULL);
479 qtm = *gmtime_r (&t, &qtm);
480 fmt = qof_date_format_get_format (QOF_DATE_FORMAT_UTC);
481 len = strftime (test, MAX_DATE_LENGTH, fmt, &qtm);
482 if (len == 0 && test[0] != '\0')
483 {
484 LEAVE (" strftime failed.");
485 return NULL;
486 }
487 LEAVE (" ");
488 return g_strdup (test);
489 }
QofDate_s::qd_yday
gshort qd_yday
Definition: qofdate.h:189
QofDate_s::qd_year
gint64 qd_year
Extended version to cope with full range of dates.
Definition: qofdate.h:181
QOF_DATE_FORMAT_UTC
#define QOF_DATE_FORMAT_UTC
QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
Definition: qofdate.h:277
PERR
#define PERR(format, args...)
Definition: qoflog.h:183
qof_time_from_gdate
QofTime * qof_time_from_gdate(GDate *date)
Convert a GDate to a QofTime.
Definition: qoftime.c:312
qof_time_stamp_now
gchar * qof_time_stamp_now(void)
Definition: qoftime.c:469
QOF_NSECS
#define QOF_NSECS
Definition: qoftime.h:105
qof_date_free
void qof_date_free(QofDate *date)
Definition: qofdate.c:608
qof_date_from_qtime
QofDate * qof_date_from_qtime(const QofTime *qt)
Definition: qofdate.c:850
qof_time_set_day_end
gboolean qof_time_set_day_end(QofTime *qt)
set the given QofTime to the last second of that day.
Definition: qoftime.c:327
qof_time_add_secs_copy
QofTime * qof_time_add_secs_copy(QofTime *qt, QofTimeSecs secs)
Create a new QofTime, secs different to an original.
Definition: qoftime.c:73
QOF_MOD_TIME
#define QOF_MOD_TIME
Definition: qoftime.h:94
qof_time_abs
QofTime * qof_time_abs(QofTime *qt)
Definition: qoftime.c:196
qof_time_get_secs
QofTimeSecs qof_time_get_secs(const QofTime *qt)
Get the number of seconds.
Definition: qoftime.c:133
qof_time_get_today_end
QofTime * qof_time_get_today_end(void)
Definition: qoftime.c:413
qof_time_to_dmy
gboolean qof_time_to_dmy(QofTime *qt, guint8 *day, guint8 *month, guint16 *year)
Definition: qoftime.c:439
qof_time_copy
QofTime * qof_time_copy(const QofTime *qt)
Create a copy of a QofTime.
Definition: qoftime.c:223
qof_time_set_secs
void qof_time_set_secs(QofTime *qt, QofTimeSecs secs)
Set the number of seconds.
Definition: qoftime.c:117
qof_time_new
QofTime * qof_time_new(void)
create an empty QofTime
Definition: qoftime.c:46
qof_time_from_time_t
QofTime * qof_time_from_time_t(time_t t, glong nanosecs)
Definition: qoftime.c:231
qof_time_to_gdate
GDate * qof_time_to_gdate(QofTime *qt)
Convert QofTime to GDate.
Definition: qoftime.c:299
qof_time_set_day_start
gboolean qof_time_set_day_start(QofTime *qt)
set the given QofTime to the first second of that day.
Definition: qoftime.c:374
qof_time_dmy_to_time
QofTime * qof_time_dmy_to_time(guint8 day, guint8 month, guint16 year)
Definition: qoftime.c:457
qof_time_get_nanosecs
glong qof_time_get_nanosecs(const QofTime *qt)
Get the number of seconds.
Definition: qoftime.c:141
qof_date_format_get_format
const gchar * qof_date_format_get_format(QofDateFormat df)
Retrieve the strftime format string for a registered date format.
Definition: qofdate.c:310
LEAVE
#define LEAVE(format, args...)
Definition: qoflog.h:227
qof_date_to_qtime
QofTime * qof_date_to_qtime(const QofDate *qd)
Definition: qofdate.c:892
QofDate_s
Full range replacement for struct tm.
Definition: qofdate.h:138
qof_time_get_current
QofTime * qof_time_get_current(void)
Get the current QofTime.
Definition: qoftime.c:362
qof_time_set_day_middle
gboolean qof_time_set_day_middle(QofTime *qt)
set the given QofTime to midday on the same day.
Definition: qoftime.c:336
qof_time_free
void qof_time_free(QofTime *qt)
Free a QofTime when no longer required.
Definition: qoftime.c:56
qof_time_cmp
gint qof_time_cmp(const QofTime *ta, const QofTime *tb)
Definition: qoftime.c:165
QofDate_s::qd_mon
glong qd_mon
Signed replacement of struct tm.tm_mon.
Definition: qofdate.h:171
qof_time_add_secs
void qof_time_add_secs(QofTime *qt, QofTimeSecs secs)
Add (or subtract) seconds from a QofTime.
Definition: qoftime.c:65
qof_time_get_today_start
QofTime * qof_time_get_today_start(void)
Definition: qoftime.c:402
qof_time_get_current_start
GTimeVal * qof_time_get_current_start(void)
Definition: qoftime.c:345
qof_time_equal
gboolean qof_time_equal(const QofTime *ta, const QofTime *tb)
Definition: qoftime.c:148
qof_time_to_time_t
gboolean qof_time_to_time_t(QofTime *qt, time_t *t, glong *nanosecs)
Definition: qoftime.c:237
qof_time_set_nanosecs
void qof_time_set_nanosecs(QofTime *qt, glong nano)
Set the number of seconds.
Definition: qoftime.c:125
qof_time_last_mday
guint8 qof_time_last_mday(QofTime *qt)
Definition: qoftime.c:423
MAX_DATE_LENGTH
#define MAX_DATE_LENGTH
The maximum length of a string used for or created by dates.
Definition: qofdate.h:87
QofDate_s::qd_gmt_off
glong qd_gmt_off
Calculated value based on struct tm.tm_gmtoff.
Definition: qofdate.h:201
qof_time_set
QofTime * qof_time_set(QofTimeSecs t, glong nanosecs)
Definition: qoftime.c:210
QofDate_s::qd_nanosecs
glong qd_nanosecs
Definition: qofdate.h:141
SECS_PER_DAY
#define SECS_PER_DAY
Definition: qofdate.h:94
QofTimeSecs
gint64 QofTimeSecs
Replacement for time_t.
Definition: qoftime.h:129
QofTime
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:120
qof_time_from_tm
QofTime * qof_time_from_tm(struct tm *qtm, glong nanosecs)
Convert a broken-down into a QofTime.
Definition: qoftime.c:258
qof_time_from_gtimeval
void qof_time_from_gtimeval(QofTime *qt, GTimeVal *gtv)
Convert a QofTime to a GTimeVal.
Definition: qoftime.c:290
QOF_DAYS_TO_SEC
#define QOF_DAYS_TO_SEC(x)
Definition: qofdate.h:331
QofDate_s::qd_mday
glong qd_mday
Signed replacement of struct tm.tm_mday.
Definition: qofdate.h:164
qof_time_to_gtimeval
gboolean qof_time_to_gtimeval(QofTime *qt, GTimeVal *gtv)
Convert a QofTime to a GTimeVal.
Definition: qoftime.c:272
ENTER
#define ENTER(format, args...)
Definition: qoflog.h:217
qof_time_diff
QofTime * qof_time_diff(const QofTime *ta, const QofTime *tb)
difference between two QofTimes.
Definition: qoftime.c:182
QofLogModule
const gchar * QofLogModule
Definition: qofid.h:85
qof_date_from_struct_tm
QofDate * qof_date_from_struct_tm(const struct tm *stm)
Convert a struct tm to a QofDate.
Definition: qofdate.c:679