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