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