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