1 /***************************************************************************
2  *        qoftime.h - QofTime, 64bit UTC time handling (seconds).
3  *       Rewritten from scratch for QOF 0.7.0
4  *
5  *  Fri May  5 15:05:32 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 #ifndef _QOFTIME_H
26 #define _QOFTIME_H
27 /**	@addtogroup QOFTIME
28 
29  Universal time is the 'one true time' that is independent of
30  one's location on planet Earth. It is measured in seconds
31  from midnight January 1, 1970 in localtime-Greenwich (GMT).
32 
33  ::QofTime uses a signed 64bit integer  to count the seconds,
34  which differs from GTimeVal (32bit) and most other time
35  handling routines (which only count from the epoch).
36 
37  A QofTime where qt_sec == +1 therefore represents
38  one second after midnight on 1st January 1970 - the epoch.
39  Negative values of QofTime->qt_sec represent times before
40  one second before midnight on 31st December 1969. Support for
41  times before 1st Jan Year 1 are included.
42 
43  \note GTime is defined to always be a 32bit integer,
44  unlike time_t which may be 64bit on some systems. Therefore,
45  GTime will overflow in the year 2038. (A 32bit time_t
46  will overflow at 2038-01-19T03:14:07Z to be precise,
47  at which point it will likely wrap around to
48  20:45:52 UTC on December 13, 1901.)
49 
50  ::QofTime is defined as 64bit on all systems and will not
51  overflow until the year 292,471,208,679 (not counting leap years).
52  i.e. approx. 9223372036854775808 / (60*60*24*365).
53  This also means that some values of QofTime cannot be converted
54  to a time_t on systems where time_t is defined as 32bit.
55 
56  \note Most conversions of QofTime can cause a loss of data.
57  GDate contains no time data, time_t varies between platforms
58  and struct tm does not include fractions of a second. \b Avoid
59  converting back and forth between time formats. All
60  conversions between QofTime and time_t, struct tm or other
61  32bit time implementations \b must check the return value of
62  QofTime functions to ensure the QofTime was within the range
63  supported by the 32bit type.
64 
65  QofTime is not directly equivalent to GTimeVal - a
66  QofTime can go further into the future. However, within the
67  range supported by GTimeVal and GTime (a 32bit integer), the
68  value of QofTime->qt_sec is always identical to
69  GTimeVal->tv_sec.
70 
71  The use of signed values and the handling of times prior to the
72  epoch means that a QofTime with zero values can no longer be
73  assumed to be invalid or used alone to denote an init value.
74  QofTime is therefore an opaque type. QofTime and QofDate
75  functions set and check QofTime validity as needed.
76 
77  QofTime is always and only concerned with seconds. All date
78  or calendar handling is performed using ::QofDate.
79 
80  \since v0.7.0
81 
82  @{
83 */
84 /**
85     @file qoftime.h
86     @brief 64bit UTC Time handling routines
87     @author Copyright 2006 Neil Williams <linux@codehelp.co.uk>
88 */
89 
90 #include "config.h"
91 #include <time.h>
92 
93 /** log module name */
94 #define QOF_MOD_TIME "qof-time"
95 
96 /** number of nanoseconds per second. 10^9 */
97 #define QOF_NSECS 1000000000
98 
99 /** \name QofTime functions.
100  @{
101 */
102 /** \brief Use a 64-bit signed int QofTime
103 
104   QofTime is a lot like the unix 'struct timespec'
105   except that it uses a 64-bit signed int to store the seconds.
106   This should adequately cover dates in the distant future as
107   well as the distant past, as long as these are not more than
108   a couple of dozen times the age of the universe. Values of
109   this type can range from -9,223,372,036,854,775,808 to
110   9,223,372,036,854,775,807.
111 */
112 typedef struct QofTime64 QofTime;
113 
114 /** \brief Replacement for time_t
115 
116 Prevents overflows by making all values 64bit on all
117 platforms.
118 
119 (time_t will overflow on 32bit systems in 2038)
120 */
121 typedef gint64 QofTimeSecs;
122 
123 /** \brief Add (or subtract) seconds from a QofTime.
124 
125  \param qt A valid QofTime.
126  \param secs A 64bit number of seconds to add (or subtract
127 if secs is negative) from the QofTime.
128 
129 The QofTime is altered in place. To assign the new value
130 to a new QofTime, use ::qof_time_add_secs_copy
131 */
132 void
133 qof_time_add_secs (QofTime * qt, QofTimeSecs secs);
134 
135 /** \brief Create a new QofTime, secs different to an original.
136 
137  \param qt a valid QofTime to use as the base.
138  \param secs a 64bit number of seconds to add (or subtract
139  if secs is negative) from the original to create the copy.
140 
141  \return a new, valid, QofTime that is secs different to the
142  original.
143 */
144 QofTime *
145 qof_time_add_secs_copy (QofTime * qt, QofTimeSecs secs);
146 
147 /** \brief create an empty QofTime
148 
149 The QofTime becomes the property of the caller and needs to be
150 freed with qof_time_free when no longer required.
151 */
152 QofTime *
153 qof_time_new (void);
154 
155 /** \brief Create a copy of a QofTime.
156 
157  \param qt A valid QofTime to copy.
158 
159  \return NULL on error, otherwise a new, valid and
160  normalised QofTime set to the same time as the original.
161 */
162 QofTime *
163 qof_time_copy (const QofTime *qt);
164 
165 /** \brief Free a QofTime when no longer required. */
166 void
167 qof_time_free (QofTime * qt);
168 
169 /** \brief Set the number of seconds
170 
171  \param time pointer to a QofTime time, created with
172 qof_time_new();
173  \param secs Signed 64bit number of seconds where zero
174 represents midnight at the epoch: 00:00:00 01/01/1970.
175 */
176 void
177 qof_time_set_secs (QofTime * time, QofTimeSecs secs);
178 
179 /** \brief Set the number of seconds
180 
181  \param time pointer to a QofTime time, created with
182 qof_time_new();
183  \param nano long int number of nanoseconds.
184 */
185 void
186 qof_time_set_nanosecs (QofTime * time, glong nano);
187 
188 /** \brief Get the number of seconds
189 
190  \param time pointer to a QofTime time, created with
191 qof_time_new();
192  \return Signed 64bit number of seconds.
193 */
194 QofTimeSecs
195 qof_time_get_secs (const QofTime * time);
196 
197 /** \brief Get the number of seconds
198 
199  \param time pointer to a QofTime time, created with
200 qof_time_new();
201  \return long int number of nanoseconds.
202 */
203 glong
204 qof_time_get_nanosecs (const QofTime * time);
205 /** @} */
206 /** \name QofTime manipulation
207  @{
208 */
209 /** strict equality */
210 gboolean
211 qof_time_equal (const QofTime * ta, const QofTime * tb);
212 
213 /** comparison:  if (ta < tb) -1; else if (ta > tb) 1; else 0; */
214 gint
215 qof_time_cmp (const QofTime * ta, const QofTime * tb);
216 
217 /** \brief difference between two QofTimes.
218 
219 Results are normalised
220 ie qt_sec and qt_nsec of the result have the same size
221 abs(result.qt_nsec) <= 1000000000
222 
223  \return a new QofTime of the difference. The caller must
224  free the difference QofTime when done.
225 */
226 QofTime *
227 qof_time_diff (const QofTime * ta, const QofTime * tb);
228 
229 /** Normalise a QofTime to an absolute value.
230 
231  \param t the QofTime to normalise.
232  \return the normalised QofTime t.
233 */
234 QofTime *
235 qof_time_abs (QofTime * t);
236 
237 gboolean
238 qof_time_is_valid (const QofTime * qt);
239 
240 /** Turns a time_t into a QofTime
241 
242  \note On some platforms, time_t is only 32bit. Use
243 ::QofTimeSecs instead.
244 
245  \param t integer seconds since the epoch.
246  \param nanosecs number of nanoseconds
247  \return pointer to a newly allocated QofTime.
248 */
249 QofTime *
250 qof_time_from_time_t (time_t t, glong nanosecs);
251 
252 /** Turns a QofTimeSecs into a QofTime
253 
254 An alternative call that combines ::qof_time_set_secs
255 and ::qof_time_set_nanosecs.
256  \param t 64bit integer number of seconds (t == 0
257 at the epoch, use negative values for previous times.)
258  \param nanosecs number of nanoseconds
259  \return pointer to a newly allocated (and validated) QofTime.
260 */
261 QofTime *
262 qof_time_set (QofTimeSecs t, glong nanosecs);
263 
264 /** Tries to turn a QofTime into a time_t
265 
266 \note CARE: QofTime is 64bit, time_t might be 32bit.
267 GDate has a wider range. time_t may be defined as
268 an integer on some platforms, causing data loss.
269 
270  \param ts A 64bit QofTime.
271  \param t pointer to a time_t to store result.
272  \param nanosecs pointer to a variable to store the
273 nanoseconds, if any, from the QofTime conversion.
274  \return FALSE on error or if the QofTime is before the epoch
275 or outside the range of time_t, otherwise TRUE.
276 */
277 gboolean
278 qof_time_to_time_t (QofTime * ts, time_t * t, glong * nanosecs);
279 
280 /** \brief Convert a broken-down into a QofTime
281 
282 struct tm broken-down time does not support
283 fractions of a second.
284 
285 Conversion of a QofTime to a struct tm is
286  \b not supported because of the inherent data loss.
287 
288  \param tm broken-down time structure.
289  \param nanosecs Fractions of a second.
290  \return a newly allocated QofTime or NULL on error.
291 */
292 QofTime *
293 qof_time_from_tm (struct tm *tm, glong nanosecs);
294 
295 /** \brief Convert a QofTime to a GTimeVal
296 
297 Safe for dates between 1st January Year 1 and 31st December 2037.
298  \param qt QofTime to convert
299  \param gtv GTimeVal to set, left unchanged if an error occurs.
300  \return TRUE on success, FALSE on error.
301 */
302 gboolean
303 qof_time_to_gtimeval (QofTime * qt, GTimeVal * gtv);
304 
305 /** \brief Convert a QofTime to a GTimeVal
306 
307 Safe for all dates supported by a valid GTimeVal.
308  \param qt QofTime to set.
309  \param gtv GTimeVal to convert
310 */
311 void
312 qof_time_from_gtimeval (QofTime * qt, GTimeVal * gtv);
313 
314 /** Convert a day, month, and year to a QofTime.
315 
316 Limited to the range of a GDate.
317 
318  \param day day of month, 1 to 31.
319  \param month Decimal number of month, 1 to 12.
320  \param year signed short containing the year. This value is
321 safe for all dates within the range of a GDate.
322  \return NULL on error, otherwise the converted QofTime.
323 */
324 QofTime *
325 qof_time_dmy_to_time (guint8 day, guint8 month, guint16 year);
326 
327 /** Convert a QofTime to day, month and year.
328 
329 Usable for all QofTime values within the range of GDate.
330 
331  \todo Remove GDate limits and use QofDate.
332 
333  \param t The QofTime to use.
334  \param day Pointer to a integer to hold day of month, 1 to 31.
335  \param month Decimal number of month, 1 to 12.
336  \param year signed short containing the year. This value is
337 safe for all dates within the range of a GDate.
338  \return FALSE if the time cannot be converted, otherwise TRUE.
339 */
340 gboolean
341 qof_time_to_dmy (QofTime * t, guint8 * day, guint8 * month, guint16 * year);
342 /** \brief Convert QofTime to GDate
343 
344  \warning The GDate will lose time-related data within the
345 QofTime. i.e. converting a QofTime to a GDate and back to a
346 QofTime causes the final QofTime to be set to the start of the
347 particular day, UTC.
348 
349  @param time The QofTime to convert
350  @return a valid GDate or NULL on error.
351 */
352 GDate *
353 qof_time_to_gdate (QofTime * time);
354 
355 /** \brief Convert a GDate to a QofTime
356 
357  \warning the QofTime is set to the first second of the
358 particular day, UTC.
359 
360  @param date The GDate to convert
361  @return a valid QofTime or NULL on error.
362 */
363 QofTime *
364 qof_time_from_gdate (GDate * date);
365 
366 /** @} */
367 
368 /** \name Time Start/End Adjustment routines
369  * Given a time value, adjust it to be the beginning or end
370 of that day.
371 @{
372 */
373 
374 /** \todo move to a private header;
375 used by qofdate.c and test-date.c
376 */
377 GTimeVal *
378 qof_time_get_current_start (void);
379 
380 /** \brief Get the current QofTime.
381 
382 Current implementations can only provide a long
383 number of seconds (max: 2,147,483,647) and the
384 number of microseconds (10^-6) not nanoseconds (10^-9).
385 
386  \return a newly allocated, valid, QofTime of the
387  current time.
388  \todo use to replace qof_time_get_current_start
389 */
390 QofTime *
391 qof_time_get_current (void);
392 
393 /** \brief set the given QofTime to midday on the same day.
394 
395 This routine is limited to dates supported by GDate.
396 
397  \todo remove GDate limits.
398 
399  \return FALSE on error, otherwise TRUE
400 */
401 gboolean
402 qof_time_set_day_middle (QofTime * t);
403 
404 /** \brief set the given QofTime to the first second of that day.
405 
406 This routine is limited to dates supported by GDate.
407 
408  \todo remove GDate limits.
409 
410 \return FALSE on error, otherwise TRUE.
411 */
412 gboolean
413 qof_time_set_day_start (QofTime * time);
414 
415 /** \brief set the given QofTime to the last second of that day.
416 
417 This routine is limited to dates supported by GDate.
418 
419  \todo remove GDate limits.
420 
421  \return FALSE on error, otherwise TRUE.
422 */
423 gboolean
424 qof_time_set_day_end (QofTime * time);
425 
426 /** Return the number of the last day of the month
427 for the value contained in the QofTime.
428 
429  \todo remove GDate limits.
430 
431 Only usable within the range of dates supported by GDate.
432  \return zero on error.
433 */
434 guint8
435 qof_time_last_mday (QofTime * ts);
436 
437 /** @} */
438 
439 /** \name Today's Date
440 @{
441 */
442 /** return a QofTime of the first second of today. */
443 QofTime *
444 qof_time_get_today_start (void);
445 
446 /** returns a QofTime of the last second of today. */
447 QofTime *
448 qof_time_get_today_end (void);
449 
450 /** Return the current time in UTC textual format.
451  @return A pointer to the generated string.
452  @note The caller owns this buffer and must free it when
453 done.
454 */
455 gchar *
456 qof_time_stamp_now (void);
457 
458 /** @} */
459 /** @} */
460 /** @} */
461 #endif /* _QOFTIME_H */
462