xref: /PHP-8.0/ext/date/lib/timelib.h (revision 4aeff60f)
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