1 /* 2 * The MIT License (MIT) 3 * 4 * Copyright (c) 2015 Derick Rethans 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #ifndef __TIMELIB_H__ 26 #define __TIMELIB_H__ 27 28 #ifdef HAVE_TIMELIB_CONFIG_H 29 # include "timelib_config.h" 30 #endif 31 32 #include <stdlib.h> 33 #include <limits.h> 34 #include <inttypes.h> 35 36 # ifndef HAVE_INT32_T 37 # if SIZEOF_INT == 4 38 typedef int int32_t; 39 # elif SIZEOF_LONG == 4 40 typedef long int int32_t; 41 # endif 42 # endif 43 44 # ifndef HAVE_UINT32_T 45 # if SIZEOF_INT == 4 46 typedef unsigned int uint32_t; 47 # elif SIZEOF_LONG == 4 48 typedef unsigned long int uint32_t; 49 # endif 50 # endif 51 52 #ifdef _WIN32 53 # if _MSC_VER >= 1600 54 # include <stdint.h> 55 # endif 56 # ifndef SIZEOF_INT 57 # define SIZEOF_INT 4 58 # endif 59 # ifndef SIZEOF_LONG 60 # define SIZEOF_LONG 4 61 # endif 62 # ifndef int32_t 63 typedef __int32 int32_t; 64 # endif 65 # ifndef uint32_t 66 typedef unsigned __int32 uint32_t; 67 # endif 68 # ifndef int64_t 69 typedef __int64 int64_t; 70 # endif 71 # ifndef uint64_t 72 typedef unsigned __int64 uint64_t; 73 # endif 74 # ifndef PRId32 75 # define PRId32 "I32d" 76 # endif 77 # ifndef PRIu32 78 # define PRIu32 "I32u" 79 # endif 80 # ifndef PRId64 81 # define PRId64 "I64d" 82 # endif 83 # ifndef PRIu64 84 # define PRIu64 "I64u" 85 # endif 86 # ifndef INT32_MAX 87 #define INT32_MAX _I32_MAX 88 # endif 89 # ifndef INT32_MIN 90 #define INT32_MIN ((int32_t)_I32_MIN) 91 # endif 92 # ifndef UINT32_MAX 93 #define UINT32_MAX _UI32_MAX 94 # endif 95 # ifndef INT64_MIN 96 #define INT64_MIN ((int64_t)_I64_MIN) 97 # endif 98 # ifndef INT64_MAX 99 #define INT64_MAX _I64_MAX 100 # endif 101 # ifndef UINT64_MAX 102 #define UINT64_MAX _UI64_MAX 103 # endif 104 #endif 105 106 #if (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)) && !defined(TIMELIB_FORCE_LONG32) 107 typedef int64_t timelib_long; 108 typedef uint64_t timelib_ulong; 109 # define TIMELIB_LONG_MAX INT64_MAX 110 # define TIMELIB_LONG_MIN INT64_MIN 111 # define TIMELIB_ULONG_MAX UINT64_MAX 112 # define TIMELIB_LONG_FMT "%" PRId64 113 # define TIMELIB_ULONG_FMT "%" PRIu64 114 #else 115 typedef int32_t timelib_long; 116 typedef uint32_t timelib_ulong; 117 # define TIMELIB_LONG_MAX INT32_MAX 118 # define TIMELIB_LONG_MIN INT32_MIN 119 # define TIMELIB_ULONG_MAX UINT32_MAX 120 # define TIMELIB_LONG_FMT "%" PRId32 121 # define TIMELIB_ULONG_FMT "%" PRIu32 122 #endif 123 124 #if defined(_MSC_VER) 125 typedef uint64_t timelib_ull; 126 typedef int64_t timelib_sll; 127 # define TIMELIB_LL_CONST(n) n ## i64 128 #else 129 typedef unsigned long long timelib_ull; 130 typedef signed long long timelib_sll; 131 # define TIMELIB_LL_CONST(n) n ## ll 132 #endif 133 134 typedef struct _ttinfo ttinfo; 135 typedef struct _tlinfo tlinfo; 136 137 typedef struct _tlocinfo 138 { 139 char country_code[3]; 140 double latitude; 141 double longitude; 142 char *comments; 143 } tlocinfo; 144 145 typedef struct _timelib_tzinfo 146 { 147 char *name; 148 struct { 149 uint32_t ttisgmtcnt; 150 uint32_t ttisstdcnt; 151 uint32_t leapcnt; 152 uint32_t timecnt; 153 uint32_t typecnt; 154 uint32_t charcnt; 155 } bit32; 156 struct { 157 uint64_t ttisgmtcnt; 158 uint64_t ttisstdcnt; 159 uint64_t leapcnt; 160 uint64_t timecnt; 161 uint64_t typecnt; 162 uint64_t charcnt; 163 } bit64; 164 165 int32_t *trans; 166 unsigned char *trans_idx; 167 168 ttinfo *type; 169 char *timezone_abbr; 170 171 tlinfo *leap_times; 172 unsigned char bc; 173 tlocinfo location; 174 } timelib_tzinfo; 175 176 typedef struct _timelib_rel_time { 177 timelib_sll y, m, d; /* Years, Months and Days */ 178 timelib_sll h, i, s; /* Hours, mInutes and Seconds */ 179 timelib_sll us; /* Microseconds */ 180 181 int weekday; /* Stores the day in 'next monday' */ 182 int weekday_behavior; /* 0: the current day should *not* be counted when advancing forwards; 1: the current day *should* be counted */ 183 184 int first_last_day_of; 185 int invert; /* Whether the difference should be inverted */ 186 timelib_sll days; /* Contains the number of *days*, instead of Y-M-D differences */ 187 188 struct { 189 unsigned int type; 190 timelib_sll amount; 191 } special; 192 193 unsigned int have_weekday_relative, have_special_relative; 194 } timelib_rel_time; 195 196 typedef struct _timelib_time_offset { 197 int32_t offset; 198 unsigned int leap_secs; 199 unsigned int is_dst; 200 char *abbr; 201 timelib_sll transition_time; 202 } timelib_time_offset; 203 204 typedef struct _timelib_time { 205 timelib_sll y, m, d; /* Year, Month, Day */ 206 timelib_sll h, i, s; /* Hour, mInute, Second */ 207 timelib_sll us; /* Microseconds */ 208 int z; /* UTC offset in seconds */ 209 char *tz_abbr; /* Timezone abbreviation (display only) */ 210 timelib_tzinfo *tz_info; /* Timezone structure */ 211 signed int dst; /* Flag if we were parsing a DST zone */ 212 timelib_rel_time relative; 213 214 timelib_sll sse; /* Seconds since epoch */ 215 216 unsigned int have_time, have_date, have_zone, have_relative, have_weeknr_day; 217 218 unsigned int sse_uptodate; /* !0 if the sse member is up to date with the date/time members */ 219 unsigned int tim_uptodate; /* !0 if the date/time members are up to date with the sse member */ 220 unsigned int is_localtime; /* 1 if the current struct represents localtime, 0 if it is in GMT */ 221 unsigned int zone_type; /* 1 time offset, 222 * 3 TimeZone identifier, 223 * 2 TimeZone abbreviation */ 224 } timelib_time; 225 226 typedef struct _timelib_abbr_info { 227 timelib_sll utc_offset; 228 char *abbr; 229 int dst; 230 } timelib_abbr_info; 231 232 #define TIMELIB_WARN_MASK 0x1ff 233 #define TIMELIB_ERR_MASK 0x2ff 234 235 #define TIMELIB_WARN_DOUBLE_TZ 0x101 236 #define TIMELIB_WARN_INVALID_TIME 0x102 237 #define TIMELIB_WARN_INVALID_DATE 0x103 238 #define TIMELIB_WARN_TRAILING_DATA 0x11a 239 240 #define TIMELIB_ERR_DOUBLE_TZ 0x201 241 #define TIMELIB_ERR_TZID_NOT_FOUND 0x202 242 #define TIMELIB_ERR_DOUBLE_TIME 0x203 243 #define TIMELIB_ERR_DOUBLE_DATE 0x204 244 #define TIMELIB_ERR_UNEXPECTED_CHARACTER 0x205 245 #define TIMELIB_ERR_EMPTY_STRING 0x206 246 #define TIMELIB_ERR_UNEXPECTED_DATA 0x207 247 #define TIMELIB_ERR_NO_TEXTUAL_DAY 0x208 248 #define TIMELIB_ERR_NO_TWO_DIGIT_DAY 0x209 249 #define TIMELIB_ERR_NO_THREE_DIGIT_DAY_OF_YEAR 0x20a 250 #define TIMELIB_ERR_NO_TWO_DIGIT_MONTH 0x20b 251 #define TIMELIB_ERR_NO_TEXTUAL_MONTH 0x20c 252 #define TIMELIB_ERR_NO_TWO_DIGIT_YEAR 0x20d 253 #define TIMELIB_ERR_NO_FOUR_DIGIT_YEAR 0x20e 254 #define TIMELIB_ERR_NO_TWO_DIGIT_HOUR 0x20f 255 #define TIMELIB_ERR_HOUR_LARGER_THAN_12 0x210 256 #define TIMELIB_ERR_MERIDIAN_BEFORE_HOUR 0x211 257 #define TIMELIB_ERR_NO_MERIDIAN 0x212 258 #define TIMELIB_ERR_NO_TWO_DIGIT_MINUTE 0x213 259 #define TIMELIB_ERR_NO_TWO_DIGIT_SECOND 0x214 260 #define TIMELIB_ERR_NO_SIX_DIGIT_MICROSECOND 0x215 261 #define TIMELIB_ERR_NO_SEP_SYMBOL 0x216 262 #define TIMELIB_ERR_EXPECTED_ESCAPE_CHAR 0x217 263 #define TIMELIB_ERR_NO_ESCAPED_CHAR 0x218 264 #define TIMELIB_ERR_WRONG_FORMAT_SEP 0x219 265 #define TIMELIB_ERR_TRAILING_DATA 0x21a 266 #define TIMELIB_ERR_DATA_MISSING 0x21b 267 268 #define TIMELIB_ZONETYPE_OFFSET 1 269 #define TIMELIB_ZONETYPE_ABBR 2 270 #define TIMELIB_ZONETYPE_ID 3 271 272 typedef struct _timelib_error_message { 273 int error_code; 274 int position; 275 char character; 276 char *message; 277 } timelib_error_message; 278 279 typedef struct _timelib_error_container { 280 timelib_error_message *error_messages; 281 timelib_error_message *warning_messages; 282 int error_count; 283 int warning_count; 284 } timelib_error_container; 285 286 typedef struct _timelib_tz_lookup_table { 287 char *name; 288 int type; 289 float gmtoffset; 290 char *full_tz_name; 291 } timelib_tz_lookup_table; 292 293 typedef struct _timelib_tzdb_index_entry { 294 char *id; 295 unsigned int pos; 296 } timelib_tzdb_index_entry; 297 298 typedef struct _timelib_tzdb { 299 char *version; 300 int index_size; 301 const timelib_tzdb_index_entry *index; 302 const unsigned char *data; 303 } timelib_tzdb; 304 305 #ifndef timelib_malloc 306 # define timelib_malloc malloc 307 # define timelib_realloc realloc 308 # define timelib_calloc calloc 309 # define timelib_strdup strdup 310 # define timelib_free free 311 #endif 312 313 #define TIMELIB_VERSION 201709 314 #define TIMELIB_EXTENDED_VERSION 20170900 315 #define TIMELIB_ASCII_VERSION "2017.09" 316 317 #define TIMELIB_NONE 0x00 318 #define TIMELIB_OVERRIDE_TIME 0x01 319 #define TIMELIB_NO_CLONE 0x02 320 321 #define TIMELIB_UNSET -99999 322 323 /* An entry for each of these error codes is also in the 324 * timelib_error_messages array in timelib.c */ 325 #define TIMELIB_ERROR_NO_ERROR 0x00 326 #define TIMELIB_ERROR_CANNOT_ALLOCATE 0x01 327 #define TIMELIB_ERROR_CORRUPT_TRANSITIONS_DONT_INCREASE 0x02 328 #define TIMELIB_ERROR_CORRUPT_NO_64BIT_PREAMBLE 0x03 329 #define TIMELIB_ERROR_CORRUPT_NO_ABBREVIATION 0x04 330 #define TIMELIB_ERROR_UNSUPPORTED_VERSION 0x05 331 #define TIMELIB_ERROR_NO_SUCH_TIMEZONE 0x06 332 333 #ifdef __cplusplus 334 extern "C" { 335 #endif 336 337 /* Function pointers */ 338 typedef timelib_tzinfo* (*timelib_tz_get_wrapper)(char *tzname, const timelib_tzdb *tzdb, int *error_code); 339 340 /* From dow.c */ 341 /* Calculates the day of the week from y, m, and d. 0=Sunday..6=Saturday */ 342 timelib_sll timelib_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d); 343 344 /* Calculates the day of the ISO week from y, m, and d. 1=Monday, 7=Sunday */ 345 timelib_sll timelib_iso_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d); 346 347 /* Calculates the day of the year according to y-m-d. 0=Jan 1st..364/365=Dec 348 * 31st */ 349 timelib_sll timelib_day_of_year(timelib_sll y, timelib_sll m, timelib_sll d); 350 351 /* Calculates the day of the year according to y-w-dow. 0..364/365 */ 352 timelib_sll timelib_daynr_from_weeknr(timelib_sll iy, timelib_sll iw, timelib_sll id); 353 354 /* Calculates the number of days in month m for year y. 28..31 */ 355 timelib_sll timelib_days_in_month(timelib_sll y, timelib_sll m); 356 357 /* Calculates the ISO year and week from y, m, and d, into iw and iy */ 358 void timelib_isoweek_from_date(timelib_sll y, timelib_sll m, timelib_sll d, timelib_sll *iw, timelib_sll *iy); 359 360 /* Calculates the ISO year, week, and day of week from y, m, and d, into iy, 361 * iw, and id */ 362 void timelib_isodate_from_date(timelib_sll y, timelib_sll m, timelib_sll d, timelib_sll *iy, timelib_sll *iw, timelib_sll *id); 363 364 /* Calculates the year, month, and day from iy, iw, and iw, into y, m, and d */ 365 void timelib_date_from_isodate(timelib_sll iy, timelib_sll iw, timelib_sll id, timelib_sll *y, timelib_sll *m, timelib_sll *d); 366 367 /* Returns true if h, i and s fit in the range 00:00:00..23:59:59, false 368 * otherwise */ 369 int timelib_valid_time(timelib_sll h, timelib_sll i, timelib_sll s); 370 371 /* Returns true if m fits in the range 1..12, and d fits in the range 372 * 1..<days-in-month> for year y */ 373 int timelib_valid_date(timelib_sll y, timelib_sll m, timelib_sll d); 374 375 /* From parse_date.re */ 376 377 /* Parses the date/time string in 's' with length 'len' into the constituent 378 * parts of timelib_time*. 379 * 380 * Depending on the contents of the string 's', not all elements might be 381 * filled. You can check whether a specific element has been parsed by 382 * comparing with the TIMELIB_UNSET define. 383 * 384 * If errors occur, this function keeps already parsed elements in the 385 * returned timelib_time* value. 386 * 387 * If the **errors points to a timelib_error_container variable, warnings 388 * and errors will be recorded. You are responsible for freeing the stored 389 * information with timelib_error_container_dtor(). To see whether errors have 390 * occured, inspect errors->errors_count. To see whether warnings have occured, 391 * inspect errors->warnings_count. 392 * 393 * The returned timelib_time* value is dynamically allocated and should be 394 * freed with timelib_time_dtor(). 395 */ 396 timelib_time *timelib_strtotime(char *s, size_t len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper); 397 398 /* Parses the date/time string in 's' with length 'len' into the constituent 399 * parts of timelib_time* according to the format in 'format'. 400 * 401 * Depending on the contents of the string 's', not all elements might be 402 * filled. You can check whether a specific element has been parsed by 403 * comparing with the TIMELIB_UNSET define. 404 * 405 * If errors occur, this function keeps already parsed elements in the 406 * returned timelib_time* value. 407 * 408 * If the **errors points to a timelib_error_container variable, warnings 409 * and errors will be recorded. You are responsible for freeing the stored 410 * information with timelib_error_container_dtor(). To see whether errors have 411 * occured, inspect errors->errors_count. To see whether warnings have occured, 412 * inspect errors->warnings_count. 413 * 414 * The returned timelib_time* value is dynamically allocated and should be 415 * freed with timelib_time_dtor(). 416 */ 417 timelib_time *timelib_parse_from_format(char *format, char *s, size_t len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper); 418 419 /* Fills the gaps in the parsed timelib_time with information from the reference date/time in 'now' 420 * 421 * If any of the 'parsed' y, m, d, h, i or s parameters is unset (TIMELIB_UNSET): 422 * - if microtime (us) is unset, then the us of the parsed time is set to 0. 423 * - else if microtime (us) is unset and 'now'->'us' is set, use it, otherwise use 0. 424 * 425 * For either of the 'parsed' y, m, d, h, i, s, z (utc offset in seconds) or 426 * dst is unset, set it to the corresponding value in 'now' if set, otherwise 427 * set it to 0. 428 * 429 * It duplicates tz_abbr if unset in 'parsed' but set in 'now'. 430 * 431 * It duplicates tz_info if unset in 'parsed', but set in 'now' unless 432 * TIMELIB_NO_CLONE is passed, in which case only the pointer in 'parsed' is 433 * set to 'now'. 434 * 435 * If the option TIMELIB_OVERRIDE_TIME is passed and the parsed date/time has 436 * no time portion, the function will ignore the time aspect in 'now' and 437 * instead fill it with zeros. 438 */ 439 void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options); 440 441 /* Tries to convert a time zone abbreviation, gmtoffset and/or isdst flag 442 * combination to a time zone identifier. 443 * 444 * If 'abbr' is either 'utc' or 'gmt' (case insensitve) then "UTC" is 445 * returned. 446 * 447 * It first uses the data in the timezonemap.h file to find a matching 448 * abbreviation/GMT offset combination. If not found, it uses the data in 449 * fallbackmap.h to match only the GMT offset/isdst flag to try to find a 450 * match. If nothing is found, NULL is returned. 451 * 452 * The returned char* is not duplicated, and should not be freed. 453 */ 454 char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst); 455 456 /* Returns an array of known time zone abbreviations 457 * 458 * This file is generated from the time zone database through the 459 * gettzmapping.php scripts, which requires that an up-to-date time zone 460 * database is used with the PHP binary that runs the script. 461 * 462 * Each item in the returned list contains the abbreviation, a flag whether 463 * it's an abbreviation used with DST, the UTC offset in seconds, and the name 464 * of the time zone identifier that this abbreviation belongs to. 465 * 466 * The order for each specific abbreviation is controlled through the 467 * preference list in the gettzmapping.php script. Time zones that match the 468 * pattern ±\d{2,4} are excluded 469 */ 470 const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void); 471 472 /** 473 * DEPRECATED, but still used by PHP. 474 */ 475 timelib_long timelib_parse_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_wrapper); 476 477 /* From parse_iso_intervals.re */ 478 479 /** 480 * Parses a subset of an ISO 8601 intervals specification string into its 481 * constituent parts. 482 * 483 * If the **errors points to a timelib_error_container variable, warnings 484 * and errors will be recorded. You are responsible for freeing the stored 485 * information with timelib_error_container_dtor(). To see whether errors have 486 * occured, inspect errors->errors_count. To see whether warnings have occured, 487 * inspect errors->warnings_count. 488 */ 489 void timelib_strtointerval(char *s, size_t len, 490 timelib_time **begin, timelib_time **end, 491 timelib_rel_time **period, int *recurrences, 492 timelib_error_container **errors); 493 494 495 /* From tm2unixtime.c */ 496 497 /** 498 * Uses the y/m/d/h/i/s fields to calculate and store the equivalent timestamp 499 * in the sse field. 500 * 501 * It uses the time zone information associated with 'time' to account for the 502 * right UTC offset and/or DST rules. You can associate time zone information 503 * with the timelib_set_timezone_* functions (see below). 504 * 505 * If the type is 'TIMELIB_ZONETYPE_ID' and there is no associated tzinfo, it 506 * will use the second argument 'tzi' to provide the rules necessary to 507 * calculate the right timestamp. 508 */ 509 void timelib_update_ts(timelib_time* time, timelib_tzinfo* tzi); 510 511 /** 512 * Takes the information from the y/m/d/h/i/s fields and makes sure their 513 * values are in the right range. 514 * 515 * If a value under- or overflows it will adjust the larger measure up (or 516 * down). It also takes into account leap days. 517 */ 518 void timelib_do_normalize(timelib_time *base); 519 520 /** 521 * Takes the information from the y/m/d/h/i/s fields of 'rt' and makes sure 522 * their values are in the right range. 523 * 524 * If a value under- or overflows it will adjust the larger measure up (or 525 * down). As this function operates on a *relative date/time*, it also takes 526 * into account leap days and correctly accounts for the difference depending 527 * on the base date/time in 'base'. 528 */ 529 void timelib_do_rel_normalize(timelib_time *base, timelib_rel_time *rt); 530 531 /* From unixtime2tm.c */ 532 533 /** 534 * Takes the unix timestamp in seconds from 'ts' and populates the y/m/d/h/i/s 535 * fields of 'tm' without taking time zones into account 536 */ 537 void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts); 538 539 /** 540 * Takes the Unix timestamp from 'ts', and calculates the y/m/d/h/i/s fields 541 * according to the time zone information attached to 'tm'. 542 */ 543 void timelib_unixtime2local(timelib_time *tm, timelib_sll ts); 544 545 /** 546 * Takes the Unix timestamp stored in 'tm', and calculates the y/m/d/h/i/s 547 * fields according to the time zone information attached to 'tm'. 548 */ 549 void timelib_update_from_sse(timelib_time *tm); 550 551 /** 552 * Attaches the UTC offset as time zone information to 't'. 553 * 554 * 'utc_offset' is in seconds East of UTC. 555 */ 556 void timelib_set_timezone_from_offset(timelib_time *t, timelib_sll utc_offset); 557 558 /** 559 * Attaches the information from 'abbr_info' as time zone information to 't'. 560 * 561 * The timelib_abbr_info struct contains an abbreviation ('abbr') which string 562 * value is duplicated, as well as a 'utc_offset' and 'dst' flag. It only 563 * supports a 'dst' change over of 1 hour. 564 */ 565 void timelib_set_timezone_from_abbr(timelib_time *t, timelib_abbr_info abbr_info); 566 567 /** 568 * Attaches the time zone information in 'tz' to to 't'. 569 * 570 * It fetches the right UTC offset that is currently stored in the time 571 * stamp field in 't' ('sse'), and assigns that to the 'z' field and 'dst' 572 * field (whether DST is in effect at the time). It also sets the current 573 * abbrevation to the 'tz_addr' field, making sure that if a value was already 574 * set it was freed. 575 * 576 * The time zone information in 'tz' is *not* duplicated into the 't' field so 577 * it should not be freed until all timelib_time* variables have been freed as 578 * well. 579 */ 580 void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz); 581 582 /* From parse_tz.c */ 583 584 /** 585 * Returns whether the time zone ID 'timezone' is available in the time zone 586 * database as pointed to be 'tzdb'. 587 */ 588 int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb); 589 590 /** 591 * Converts the binary stored time zone information from 'tzdb' for the time 592 * zone 'timeozne' into a structure the library can use for calculations. 593 * 594 * The function can be used on both timelib_builtin_db as well as a time zone 595 * db as opened by timelib_zoneinfo. 596 * The function will return null upon failure, and also set an error code 597 * through 'error_code'. 'error_code' must not be a null pointer. The error 598 * code is one of the TIMELIB_ERROR_* constants as listed above. These error 599 * constants can be converted into a string by timelib_get_error_message. 600 * 601 * This function allocates memory for the new time zone structure, which must 602 * be freed after use. Although it is recommended that a cache of each used 603 * time zone is kept. 604 */ 605 timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, int *error_code); 606 607 /** 608 * Frees up the resources allocated by 'timelib_parse_tzfile'. 609 */ 610 void timelib_tzinfo_dtor(timelib_tzinfo *tz); 611 612 /** 613 * Deep-clones a timelib_tzinfo structure. 614 * 615 * This allocates resources that need to be freed with 'timelib_tzinfo_dtor' 616 */ 617 timelib_tzinfo* timelib_tzinfo_clone(timelib_tzinfo *tz); 618 619 /** 620 * Returns whether DST is active with time zone 'tz' for the time stamp 'ts'. 621 * 622 * Returns 0 if DST is not active, 1 if DST is active, or -1 if no transitions 623 * were available through 'tz'. 624 */ 625 int timelib_timestamp_is_in_dst(timelib_sll ts, timelib_tzinfo *tz); 626 627 /** 628 * Returns offset information with time zone 'tz' for the time stamp 'ts'. 629 * 630 * The returned information contains: the offset in seconds East of UTC (in 631 * 'offset'), whether DST is active ('is_dst'), what the current time zone 632 * abbreviation is ('abbr') and the transition time that got to this state (in 633 * 'transistion_time'); 634 */ 635 timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *tz); 636 637 /** 638 * Returns the UTC offset currently applicable for the information stored in 't'. 639 * 640 * The value returned is the UTC offset in seconds East. 641 */ 642 timelib_sll timelib_get_current_offset(timelib_time *t); 643 644 /** 645 * Displays debugging information about the time zone information in 'tz'. 646 */ 647 void timelib_dump_tzinfo(timelib_tzinfo *tz); 648 649 /** 650 * Returns a pointer to the built-in time zone database. 651 * 652 * You must *not* free the returned pointer as it is part of the text segment. 653 */ 654 const timelib_tzdb *timelib_builtin_db(void); 655 656 /** 657 * Returns a pointer to the start of an array containing a list of timezone identifiers. 658 * 659 * The amount of entries in the array is returned through the 'count' OUT parameter. 660 * 661 * Each entry contains the time zone ID ('id' field), and the position within the time zone 662 * information ('pos' field). The pos field should not be used. 663 */ 664 const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count); 665 666 /* From parse_zoneinfo.c */ 667 668 /** 669 * Scans the directory and subdirectories of 'directory' for valid time zone files and builds 670 * a time zone database out of these files. 671 * 672 * Typically, the directory should point to '/usr/share/zoneinfo'. 673 * 674 * Unlike 'timelib_builtin_db', the return value of this function must be freed 675 * with the 'timelib_zoneinfo_dtor' function. 676 */ 677 timelib_tzdb *timelib_zoneinfo(char *directory); 678 679 /** 680 * Frees up the resources as created through 'timelib_zoneinfo'. 681 * 682 * This function must be used to free up all the resources that have been 683 * allocated while calling 'timelib_zoneinfo'. 684 */ 685 void timelib_zoneinfo_dtor(timelib_tzdb *tzdb); 686 687 /* From timelib.c */ 688 689 /** 690 * Returns a static string containing an error message belonging to a specific 691 * error code. 692 */ 693 const char *timelib_get_error_message(int error_code); 694 695 /** 696 * Allocates resources for the relative time structure. 697 * 698 * Must be freed with 'timelib_rel_time_dtor'. 699 */ 700 timelib_rel_time* timelib_rel_time_ctor(void); 701 702 /** 703 * Frees up the resources as allocated through 'timelib_rel_time_ctor'. 704 */ 705 void timelib_rel_time_dtor(timelib_rel_time* t); 706 707 /** 708 * Creates a new timelib_rel_time resource and copies over the information 709 * from 'tz'. 710 * 711 * Must be freed with 'timelib_rel_time_dtor'. 712 */ 713 timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *tz); 714 715 /** 716 * Allocates resources for the time structure. 717 * 718 * Must be freed with 'timelib_time_dtor'. 719 */ 720 timelib_time* timelib_time_ctor(void); 721 722 /** 723 * Frees up the resources as allocated through 'timelib_time_ctor'. 724 */ 725 void timelib_time_dtor(timelib_time* t); 726 727 /** 728 * Creates a new timelib_time resource and copies over the information 729 * from 'orig'. 730 * 731 * Must be freed with 'timelib_time_dtor'. 732 */ 733 timelib_time* timelib_time_clone(timelib_time* orig); 734 735 /** 736 * Compares two timelib_time structures and returns which one is earlier in 737 * time. 738 * 739 * To decide which comes earlier it uses the 'sse' (Seconds Since Epoch) and 740 * 'us' (microseconds) fields. 741 * 742 * Returns -1 if t1 < t2, 0 if t1 == t2, and -1 if t1 > t2. 743 */ 744 int timelib_time_compare(timelib_time *t1, timelib_time *t2); 745 746 /** 747 * Allocates resources for the time offset structure. 748 * 749 * Must be freed with 'timelib_time_offset_dtor'. 750 */ 751 timelib_time_offset* timelib_time_offset_ctor(void); 752 753 /** 754 * Frees up the resources as allocated through 'timelib_time_offset_ctor'. 755 */ 756 void timelib_time_offset_dtor(timelib_time_offset* t); 757 758 /** 759 * Frees up the resources allocated while converting strings to timelib_time 760 * structures with the timelib_strtotime and timelib_strtointerval functions. 761 */ 762 void timelib_error_container_dtor(timelib_error_container *errors); 763 764 /** 765 * Converts the 'sse' value of 'd' to a timelib_long type. 766 * 767 * If the value fits in the TIMELIB_LONG_MIN and TIMELIB_LONG_MAX range, the 768 * value is cast to (timelib_long) and returned. If *error is not a NULL 769 * pointer, it will be set to 0. 770 * 771 * If the value does *not* fit in the range, the function returns 0 and if 772 * *error is not a NULL pointer, it will be set to 1. 773 * 774 * timelib_long is a 32 bit signed long integer on 32 bit platforms, and a 64 775 * bit signed long long integer on 64 bit platforms. In other words, it makes 776 * sure that the value in 'sse' (which is always a signed long long 64 bit 777 * integer) can be used safely outside of the library. 778 */ 779 timelib_long timelib_date_to_int(timelib_time *d, int *error); 780 781 /** 782 * Displays debugging information about the date/time information stored in 'd'. 783 * 784 * 'options' is a bit field, where: 785 * - 1 controls whether the relative time portion is shown. 786 * - 2 controls whether the zone type is shown. 787 */ 788 void timelib_dump_date(timelib_time *d, int options); 789 790 /** 791 * Displays debugging information about the relative time information stored 792 * in 'd'. 793 */ 794 void timelib_dump_rel_time(timelib_rel_time *d); 795 796 /** 797 * Converts a decimal hour into hour/min/sec components 798 */ 799 void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec); 800 801 /** 802 * Converts hour/min/sec values into a decimal hour 803 */ 804 void timelib_hms_to_decimal_hour(int hour, int min, int sec, double *h); 805 806 /* from astro.c */ 807 808 /** 809 * Converts the Unix Epoch time stamp 'ts' to a Julian Day 810 * 811 * The value returned is the number of whole days since -4714-11-24T12:00:00 UTC 812 * (in the proleptic Gregorian calendar): 813 * https://en.wikipedia.org/wiki/Julian_day 814 */ 815 double timelib_ts_to_julianday(timelib_sll ts); 816 817 /** 818 * Converts the Unix Epoch time stamp 'ts' to the J2000 epoch 819 * 820 * The value returned is the number of whole days since 2000-01-01T12:00:00 821 * UTC: https://en.wikipedia.org/wiki/Epoch_(astronomy)#Julian_years_and_J2000 822 */ 823 double timelib_ts_to_j2000(timelib_sll ts); 824 825 /** 826 * Calculates when the Sun is above a certain latitude. 827 * 828 * Parameters: 829 * - time: A timelib_time time describing that needs to specific midnight for a 830 * specific day. 831 * - lon: The longitude of the observer (East positive, West negative). 832 * - lat: The latitude of the observer (North positive, South negative). 833 * - altit: The altitude. Set to -35/60 for rise/set, -6 for civil twilight, 834 * -12 for nautical, and -18 for astronomical twilight. 835 * - upper_limb: set to non-zero for rise/set calculations, and 0 for twilight 836 * calculations. 837 * 838 * Out Parameters: 839 * - h_rise: The decimal hour when the Sun rises 840 * - h_set: The decimal hour when the Sun sets 841 * - ts_rise: The Unix timestamp of the Sun rising 842 * - ts_set: The Unix timestamp of the Sun setting 843 * - ts_transit: The Unix timestmap of the Sun transitting through South 844 * 845 * Return Values: 846 * - 0: The Sun rises and sets. 847 * - +1: The Sun is always above the horizon. (ts_rise is set to ts_transit - 848 * (12 * 3600); ts_set is set to ts_transit + (12 * 3600). 849 * - -1: The Sun is awlays below the horizon. (ts_rise and ts_set are set 850 * to ts_transit) 851 */ 852 int timelib_astro_rise_set_altitude(timelib_time *time, double lon, double lat, double altit, int upper_limb, double *h_rise, double *h_set, timelib_sll *ts_rise, timelib_sll *ts_set, timelib_sll *ts_transit); 853 854 /* from interval.c */ 855 856 /** 857 * Calculates the difference between two times 858 * 859 * The result is a timelib_rel_time structure that describes how you can 860 * convert from 'one' to 'two' with 'timelib_add'. This does *not* necessarily 861 * mean that you can go from 'two' to 'one' by using 'timelib_sub' due to the 862 * way months and days are calculated. 863 */ 864 timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two); 865 866 /** 867 * Adds the relative time information 'interval' to the base time 't'. 868 * 869 * This can be a relative time as created by 'timelib_diff', but also by more 870 * complex statements such as "next workday". 871 */ 872 timelib_time *timelib_add(timelib_time *t, timelib_rel_time *interval); 873 874 /** 875 * Subtracts the relative time information 'interval' to the base time 't'. 876 * 877 * This can be a relative time as created by 'timelib_diff'. Unlike with 878 * 'timelib_add', this does not support more complex statements such as "next 879 * workday". 880 */ 881 timelib_time *timelib_sub(timelib_time *t, timelib_rel_time *interval); 882 883 #ifdef __cplusplus 884 } /* extern "C" */ 885 #endif 886 887 #endif 888