Mstdlib-1.24.0
m_time.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_TIME_H__
25#define __M_TIME_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31
32/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
33
34__BEGIN_DECLS
35
36/*! \addtogroup m_time Time
37 * \ingroup mstdlib_base
38 *
39 * Time handling functions.
40 *
41 * Features
42 * ========
43 *
44 * Covers:
45 * - Local
46 * - GMT
47 * - Normalization
48 * - Conversion
49 * - Diff
50 * - Elapsed
51 * - Time zone
52 * - string reading
53 * - string writing
54 *
55 *
56 * Key data types
57 * ==============
58 *
59 * M_time_t is provided as a platform agnostic replacement for time_t. M_time_t a signed 64 bit data type.
60 * This allows systems which provide a 32 bit time_t to handle times above the 32 bit boundary. However,
61 * any functions (such as M_time) that use underlying system time functions will only operate using the
62 * bit max/min provided by the system time_t.
63 *
64 * M_timeval_t (struct M_timeval) is also provided for the same reasons as M_time_t. In addition, not all
65 * platforms support struct timval in an obvious way. Windows in particular can have header conflict issues when
66 * dealing with struct timeval. Specifically, struct timeval is defined in Winsock2.h which much be included
67 * before Windows.h. Either this header would have to include, which can lead to problems is this header is
68 * included after Windows.h is declared. Or an application using mstdlib would have to include Winsock2.h,
69 * which is nonobvious.
70 *
71 *
72 * Timezone
73 * ========
74 *
75 * Time zone data is stored in a timezone database object. Data can be loaded in two ways.
76 * - Loading a timezone database (Olson files, Windows registry).
77 * - Loading individual timezone data.
78 *
79 * Lazy loading is available when using a timezone database. Lazy loading has the data read into
80 * the db on demand instead of reading the data immediately. Only one timezone data source
81 * can be used for lazy loading.
82 *
83 * When using lazy loading in a multi threaded environment all calls to M_time_tzs_get_tz
84 * need to be protected by a mutex or other access broker.
85 *
86 * The tz (timezone) object should not be used directly. Instead it should be passed to
87 * M_time_tolocal or M_time_fromlocal.
88 *
89 *
90 * Examples
91 * ========
92 *
93 * Timezone
94 * --------
95 *
96 * \code{.c}
97 * M_time_tzs_t *tzs;
98 * const M_time_tz_t *tz;
99 * M_time_t ts = 1375277153;
100 * M_time_t cs;
101 * M_time_localtm_t ltime;
102 *
103 * M_mem_set(&ltime, 0, sizeof(ltime));
104 *
105 * tzs = M_time_tzs_load_zoneinfo(NULL, M_TIME_TZ_ZONE_AMERICA, M_TIME_TZ_ALIAS_OLSON_MAIN, M_TIME_TZ_LOAD_LAZY);
106 * tz = M_time_tzs_get_tz(tzs, "America/New_York");
107 *
108 * M_time_tolocal(ts, &ltime, tz);
109 *
110 * M_printf("isdst='%s'\n", ltime.isdst?"YES":"NO");
111 *
112 * cs = M_time_fromlocal(&ltime, tz);
113 * if (ts != cs) {
114 * M_printf("time conversion failed\n");
115 * } else {
116 * M_printf("time conversion success\n");
117 * }
118 *
119 * M_time_tzs_destroy(tzs);
120 * \endcode
121 *
122 * System
123 * ------
124 *
125 * \code{.c}
126 * M_time_localtm_t ltime;
127 * M_time_t ts;
128 *
129 * M_mem_set(&ltime, 0, sizeof(ltime));
130 *
131 * M_time_tolocal(0, &ltime, NULL);
132 * t = M_time_fromlocal(&ltime, NULL);
133 *
134 * if (t != 0) {
135 * M_printf("time conversion failed\n");
136 * } else {
137 * M_printf("time conversion success\n");
138 * }
139 * \endcode
140 *
141 * Time Strings
142 * ------------
143 *
144 * \code{.c}
145 * M_time_t ts;
146 * char *out;
147 * M_time_localtm_t ltime;
148 *
149 * M_mem_set(&ltime, 0, sizeof(ltime));
150 *
151 * ts = M_time_from_str("1998/11/31 10:02:50", NULL, M_FALSE);
152 * M_time_tolocal(ts, &ltime, NULL);
153 * out = M_time_to_str("%Y-%m-%d %H:%M:%S %p", &tm);
154 * M_printf("out='%s'\n", out);
155 * M_free(out);
156 * \endcode
157 *
158 * @{
159 */
160
161typedef M_int64 M_time_t;
162typedef M_int64 M_suseconds_t;
163
164/*! Broken down time stored as individual components. */
165struct M_time_tm {
166 M_int64 month; /*!< Month. 1-12*/
167 M_int64 day; /*!< Day of month. 1-X */
168 M_int64 year; /*!< Year. Full year. E.g. 2013. */
169 M_int64 year2; /*!< 2digit Year. E.g. 13. */
170 M_int64 hour; /*!< hour. 0=Midnight ... 23=11PM. */
171 M_int64 min; /*!< minute. 0-59. */
172 M_int64 sec; /*!< second. 0-59. */
173 M_int64 wday; /*!< day of week. 0=Sun ... 6=Sat */
174 M_int64 yday; /*!< day of year. 0-364 (or 365 on leap years) */
175 /* Local time data */
176 M_int64 isdst; /*!< -1=DST unknown, 0=not DST, 1=is DST */
177 M_time_t gmtoff; /*!< Seconds west of Greenwich. */
178 char abbr[32]; /*!< Abbreviation for use with printing. This will only be filled if a M_time_tz_t is passed
179 in with the time. If abbr is filled by a M_time_tz_t then the M_time_tz_t must remain
180 valid for the life of the struct. */
181};
182typedef struct M_time_tm M_time_localtm_t;
183typedef struct M_time_tm M_time_gmtm_t;
184
185
186/*! Number of seconds and microseconds since the Epoch. */
187typedef struct M_timeval {
188 M_time_t tv_sec; /*!< Seconds. */
189 M_suseconds_t tv_usec; /*!< Microseconds. */
191
192
193/*! Timezone data. */
194struct M_time_tz;
195typedef struct M_time_tz M_time_tz_t;
196
197
198/*! Timezone database. */
199struct M_time_tzs;
200typedef struct M_time_tzs M_time_tzs_t;
201
202
203/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
204
205/*! Olson/TZ/Zoneinfo locations that can be loaded. */
206typedef enum {
207 M_TIME_TZ_ZONE_ALL = 0, /*!< Load all zones. This cannot be combined with individual zones. */
208 M_TIME_TZ_ZONE_AFRICA = 1 << 1, /*!< Load data form Africa. */
209 M_TIME_TZ_ZONE_AMERICA = 1 << 2, /*!< Load data form the Americas. */
210 M_TIME_TZ_ZONE_ANTARCTICA = 1 << 3, /*!< Load data form Antarctica. */
211 M_TIME_TZ_ZONE_ARCTIC = 1 << 4, /*!< Load data form the artic. */
212 M_TIME_TZ_ZONE_ASIA = 1 << 5, /*!< Load data form Asia. */
213 M_TIME_TZ_ZONE_ATLANTIC = 1 << 6, /*!< Load data form the Atlantic. */
214 M_TIME_TZ_ZONE_AUSTRALIA = 1 << 7, /*!< Load data form Australia. */
215 M_TIME_TZ_ZONE_EUROPE = 1 << 8, /*!< Load data form Europe. */
216 M_TIME_TZ_ZONE_INDIAN = 1 << 9, /*!< Load data form the Indian ocean region. */
217 M_TIME_TZ_ZONE_PACIFIC = 1 << 10, /*!< Load data form the Pacific. */
218 M_TIME_TZ_ZONE_ETC = 1 << 11 /*!< Load data form Etc (fixed offset) zones. */
220
221
222/*! Flags to control loading behavior of Olson/TZ/Zoneinfo data. */
223typedef enum {
224 M_TIME_TZ_LOAD_NORMAL = 0, /*!< Load all data. */
225 M_TIME_TZ_LOAD_LAZY = 1 << 1 /*!< Lazy load data. This is really only useful for memory constrained
226 environments where only a few zones will be in use but the overhead
227 of loading all zones may be too much for the system. */
229
230
231/*! Handle alias loading.
232 * Not all alias options will be avalaible for all zone data sources.
233 */
234typedef enum {
235 M_TIME_TZ_ALIAS_ALL = 0, /*!< Include all names and aliases. */
236 M_TIME_TZ_ALIAS_OLSON_MAIN = 1 << 1, /*!< Include main Olson alias. */
237 M_TIME_TZ_ALIAS_OLSON_ALL = 1 << 2, /*!< Include all Olson aliases. */
238 M_TIME_TZ_ALIAS_WINDOWS_MAIN = 1 << 3, /*!< Include Windows zone names. */
239 M_TIME_TZ_ALIAS_WINDOWS_ALL = 1 << 4 /*!< Include Windows zone names. */
241
242
243/*! Result codes specific to time operations. */
244typedef enum {
245 M_TIME_RESULT_SUCCESS = 0, /*!< Success. */
246 M_TIME_RESULT_INVALID, /*!< Invalid argument. */
247 M_TIME_RESULT_ERROR, /*!< General error. */
248 M_TIME_RESULT_DUP, /*!< Duplicate. */
249 M_TIME_RESULT_INI, /*!< ini failed to parse. */
250 M_TIME_RESULT_ABBR, /*!< Std abbreviation failed to parse. */
251 M_TIME_RESULT_OFFSET, /*!< Std offset failed to parse. */
252 M_TIME_RESULT_DATE, /*!< Date failed to parse. */
253 M_TIME_RESULT_TIME, /*!< Time failed to parse. */
254 M_TIME_RESULT_DATETIME, /*!< Date/time failed to parse. */
255 M_TIME_RESULT_YEAR, /*!< Year failed to parse. */
256 M_TIME_RESULT_DSTABBR, /*!< DST abbreviation failed to parse. */
257 M_TIME_RESULT_DSTOFFSET /*!< DST offset failed to parse. */
259
260
261/*! Source timezone data was loaded form.
262 * \see M_time_tzs_load */
263typedef enum {
264 M_TIME_LOAD_SOURCE_FAIL = 0, /*!< Timezone data failed to load. This
265 can happen if no timezone data was
266 loaded. For example, a specific
267 M_time_tz_zones_t was requested but
268 not available. */
269 M_TIME_LOAD_SOURCE_SYSTEM, /*!< The system timezone data was loaded. */
270 M_TIME_LOAD_SOURCE_FALLBACK /*!< Main four US timezones were loaded as
271 a fallback because system data could
272 not be loaded. */
274
275/*! @} */
276
277
278/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
279
280/*! \addtogroup m_time_time Date Time
281 * \ingroup m_time
282 *
283 * @{
284 */
285
286/*! Get the system time.
287 *
288 * While M_time_t is guaranteed to be 64 bit the time returned is not.
289 * Time is dependent on the platform and some only support 32 bit time
290 * values. On these systems M_time will only return a value up to
291 * Jan 19, 2038 03:14:07 UTC.
292 *
293 * \return Number of seconds since Epoch (Jan 1, 1970 00:00:00 UTC).
294 */
295M_API M_time_t M_time(void);
296
297
298/*! Get the number of seconds and milliseconds since Epoch.
299 *
300 * \param[out] tv The time as seconds and milliseconds since Epoch.
301 *
302 * \return M_TRUE on success, otherwise M_FALSE.
303 */
304M_API M_bool M_time_gettimeofday(M_timeval_t *tv) M_WARN_NONNULL(1);
305
306
307/*! Get the number of days in a given month for a given year.
308 *
309 * Accounts for leap years.
310 *
311 * \param[in] year The year.
312 * \param[in] month The month. 1-12.
313 *
314 * \return The number of days in the month.
315 */
316M_API int M_time_days_in_month(M_int64 year, M_int64 month);
317
318
319/*! Determine if a give day of month valid for the given month for a given year.
320 *
321 * \param[in] year The year.
322 * \param[in] month The month.
323 * \param[in] day The day of month.
324 *
325 * \return M_TRUE if the day is valid. Otherwise M_FALSE.
326 */
327M_API M_bool M_time_is_valid_day(M_int64 year, M_int64 month, M_int64 day);
328
329
330/*! Normalize a struct tm.
331 *
332 * If adjustments are made to a struct tm this will bring the adjustments back
333 * to a real date/time.
334 *
335 * This does not modify the isdst, gmtoff or abbr fields of the struct. These may be
336 * wrong if the adjust time crosses a DST boundary for example. Use M_time_fromlocal
337 * with the appropriate time zone data (or NULL if using the systems current info)
338 * to normalize a time taking into account these fields. Or use M_time_fromgm if dealing
339 * with a gm time (isdst, gmtoff and abbr will be cleared).
340 *
341 * \param[in,out] tm The tm to normalize.
342 */
343M_API void M_time_normalize_tm(struct M_time_tm *tm);
344
345
346/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
347
348/*! Convert a local time to a UTC time.
349 *
350 * \param[in,out] ltime The local time structure to convert. This will be normalized.
351 * \param[in] tz The time zone the local time is in.
352 *
353 * \return UTC time.
354 */
355M_API M_time_t M_time_fromlocal(M_time_localtm_t *ltime, const M_time_tz_t *tz) M_WARN_NONNULL(1);
356
357
358/*! Convert a UTC time to a local time struct.
359 *
360 * \param[in] t The UTC time.
361 * \param[out] ltime The local time struct.
362 * \param[in] tz The time zone the local time is in.
363 */
364M_API void M_time_tolocal(M_time_t t, M_time_localtm_t *ltime, const M_time_tz_t *tz) M_WARN_NONNULL(2);
365
366
367/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
368
369/*! Convert a UTC time to a broken out time struct.
370 *
371 * \param[in] t UTC time.
372 * \param[out] tm Time struct.
373 */
374M_API void M_time_togm(M_time_t t, M_time_gmtm_t *tm) M_WARN_NONNULL(2);
375
376
377/*! Convert a broken out time struct to a unix timestamp.
378 *
379 * \param[in,out] tm The time struct. This will be normalized.
380 *
381 * \return Time stamp.
382 */
383M_API M_time_t M_time_fromgm(M_time_gmtm_t *tm) M_WARN_NONNULL(1);
384
385/*! @} */
386
387
388/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
389
390/*! \addtogroup m_time_calc Time Calculations
391 * \ingroup m_time
392 *
393 * @{
394 */
395
396/*! Calculate the number of milliseconds between two timevals.
397 *
398 * \param[in] start_time The start time.
399 * \param[in] end_time The end time.
400 *
401 * \return The number of milliseconds between the two times.
402 */
403M_API M_int64 M_time_timeval_diff(const M_timeval_t *start_time, const M_timeval_t *end_time) M_WARN_NONNULL(1) M_WARN_NONNULL(2);
404
405
406/*! Start time to use for elapsed time operations.
407 *
408 * \param[out] start_tv The current time to use as the start time.
409 */
410M_API void M_time_elapsed_start(M_timeval_t *start_tv) M_WARN_NONNULL(1);
411
412
413/*! The amount of time that has elapsed since start in milliseconds.
414 *
415 * \param[in] start_tv The time to calculate from. This should be the value from M_time_elapsed_start.
416 *
417 * \return The number of milliseconds that have elapsed since start until now.
418 */
419M_API M_uint64 M_time_elapsed(const M_timeval_t *start_tv) M_WARN_NONNULL(1);
420
421/*! @} */
422
423
424/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
425
426/*! \addtogroup m_time_parse Parsing
427 * \ingroup m_time
428 *
429 * @{
430 */
431
432/*! Parse a time string.
433 *
434 * Supports offsets and fixed formats.
435 *
436 * Offsets:
437 *
438 * - Support:
439 * - 'now'
440 * - 'epoch'
441 * - 'yesterday' (at same time as current day)
442 * - 'today' (same as 'now'),
443 * - 'tomorrow' (at same time as current day),
444 * - 'BOD' (beginning of current day)
445 * - 'EOD' (end of current day)
446 * - +/-N magnitude', where magnitude is:
447 * - year, month, day, hour, min, sec
448 * - where long names and plural are supported
449 *
450 * Ex: +6 Months or -7 hours
451 *
452 * Offsets use the current time.
453 *
454 * Fixed:
455 *
456 * - \%m/\%d/\%Y \%H
457 * - \%m/\%d/\%Y \%H \%P
458 * - \%m/\%d/\%Y \%H \%p
459 * - \%m/\%d/\%Y \%I \%P
460 * - \%m/\%d/\%Y \%I \%p
461 * - \%m/\%d/\%Y \%H\%M
462 * - \%m/\%d/\%Y \%H\%M \%P
463 * - \%m/\%d/\%Y \%H\%M \%p
464 * - \%m/\%d/\%Y \%I\%M \%P
465 * - \%m/\%d/\%Y \%I\%M \%p
466 * - \%m/\%d/\%Y \%H\%M\%S
467 * - \%m/\%d/\%Y \%H\%M\%S \%P
468 * - \%m/\%d/\%Y \%H\%M\%S \%p
469 * - \%m/\%d/\%Y \%H\%M\%S \%z
470 * - \%m/\%d/\%Y \%I\%M\%S \%P
471 * - \%m/\%d/\%Y \%I\%M\%S \%p
472 * - \%m/\%d/\%Y \%H\%M\%S \%z
473 * - \%m/\%d/\%Y \%H:\%M
474 * - \%m/\%d/\%Y \%H:\%M \%P
475 * - \%m/\%d/\%Y \%H:\%M \%p
476 * - \%m/\%d/\%Y \%I:\%M \%P
477 * - \%m/\%d/\%Y \%I:\%M \%p
478 * - \%m/\%d/\%Y \%H:\%M:\%S
479 * - \%m/\%d/\%Y \%H:\%M:\%S \%P
480 * - \%m/\%d/\%Y \%H:\%M:\%S \%p
481 * - \%m/\%d/\%Y \%I:\%M:\%S \%P
482 * - \%m/\%d/\%Y \%I:\%M:\%S \%p
483 * - \%m/\%d/\%Y \%H:\%M:\%S \%z
484 * - \%m/\%d/\%Y \%H-\%M
485 * - \%m/\%d/\%Y \%H-\%M \%P
486 * - \%m/\%d/\%Y \%H-\%M \%p
487 * - \%m/\%d/\%Y \%I-\%M \%P
488 * - \%m/\%d/\%Y \%I-\%M \%p
489 * - \%m/\%d/\%Y \%H-\%M-\%S
490 * - \%m/\%d/\%Y \%H-\%M-\%S \%P
491 * - \%m/\%d/\%Y \%H-\%M-\%S \%p
492 * - \%m/\%d/\%Y \%I-\%M-\%S \%P
493 * - \%m/\%d/\%Y \%I-\%M-\%S \%p
494 * - \%m/\%d/\%Y \%H-\%M-\%S \%z
495 * - \%m/\%d/\%Y T \%H
496 * - \%m/\%d/\%Y T \%H \%P
497 * - \%m/\%d/\%Y T \%H \%p
498 * - \%m/\%d/\%Y T \%I \%P
499 * - \%m/\%d/\%Y T \%I \%p
500 * - \%m/\%d/\%Y T \%H\%M
501 * - \%m/\%d/\%Y T \%H\%M \%P
502 * - \%m/\%d/\%Y T \%H\%M \%p
503 * - \%m/\%d/\%Y T \%I\%M \%P
504 * - \%m/\%d/\%Y T \%I\%M \%p
505 * - \%m/\%d/\%Y T \%H\%M\%S
506 * - \%m/\%d/\%Y T \%H\%M\%S \%P
507 * - \%m/\%d/\%Y T \%H\%M\%S \%p
508 * - \%m/\%d/\%Y T \%I\%M\%S \%P
509 * - \%m/\%d/\%Y T \%I\%M\%S \%p
510 * - \%m/\%d/\%Y T \%H\%M\%S \%z
511 * - \%m/\%d/\%Y T \%H:\%M
512 * - \%m/\%d/\%Y T \%H:\%M \%P
513 * - \%m/\%d/\%Y T \%H:\%M \%p
514 * - \%m/\%d/\%Y T \%I:\%M \%P
515 * - \%m/\%d/\%Y T \%I:\%M \%p
516 * - \%m/\%d/\%Y T \%H:\%M:\%S
517 * - \%m/\%d/\%Y T \%H:\%M:\%S \%P
518 * - \%m/\%d/\%Y T \%H:\%M:\%S \%p
519 * - \%m/\%d/\%Y T \%I:\%M:\%S \%P
520 * - \%m/\%d/\%Y T \%I:\%M:\%S \%p
521 * - \%m/\%d/\%Y T \%H:\%M:\%S \%z
522 * - \%m/\%d/\%Y T \%H-\%M
523 * - \%m/\%d/\%Y T \%H-\%M \%P
524 * - \%m/\%d/\%Y T \%H-\%M \%p
525 * - \%m/\%d/\%Y T \%I-\%M \%P
526 * - \%m/\%d/\%Y T \%I-\%M \%p
527 * - \%m/\%d/\%Y T \%H-\%M-\%S
528 * - \%m/\%d/\%Y T \%H-\%M-\%S \%P
529 * - \%m/\%d/\%Y T \%H-\%M-\%S \%p
530 * - \%m/\%d/\%Y T \%I-\%M-\%S \%P
531 * - \%m/\%d/\%Y T \%I-\%M-\%S \%p
532 * - \%m/\%d/\%Y T \%H-\%M-\%S \%z
533 * - \%m-\%d-\%Y \%H
534 * - \%m-\%d-\%Y \%H \%P
535 * - \%m-\%d-\%Y \%H \%p
536 * - \%m-\%d-\%Y \%I \%P
537 * - \%m-\%d-\%Y \%I \%p
538 * - \%m-\%d-\%Y \%H\%M
539 * - \%m-\%d-\%Y \%H\%M \%P
540 * - \%m-\%d-\%Y \%H\%M \%p
541 * - \%m-\%d-\%Y \%I\%M \%P
542 * - \%m-\%d-\%Y \%I\%M \%p
543 * - \%m-\%d-\%Y \%H\%M\%S
544 * - \%m-\%d-\%Y \%H\%M\%S \%P
545 * - \%m-\%d-\%Y \%H\%M\%S \%p
546 * - \%m-\%d-\%Y \%I\%M\%S \%P
547 * - \%m-\%d-\%Y \%I\%M\%S \%p
548 * - \%m-\%d-\%Y \%H\%M\%S \%z
549 * - \%m-\%d-\%Y \%H:\%M
550 * - \%m-\%d-\%Y \%H:\%M \%P
551 * - \%m-\%d-\%Y \%H:\%M \%p
552 * - \%m-\%d-\%Y \%I:\%M \%P
553 * - \%m-\%d-\%Y \%I:\%M \%p
554 * - \%m-\%d-\%Y \%H:\%M:\%S
555 * - \%m-\%d-\%Y \%H:\%M:\%S \%P
556 * - \%m-\%d-\%Y \%H:\%M:\%S \%p
557 * - \%m-\%d-\%Y \%I:\%M:\%S \%P
558 * - \%m-\%d-\%Y \%I:\%M:\%S \%p
559 * - \%m-\%d-\%Y \%H:\%M:\%S \%z
560 * - \%m-\%d-\%Y \%H-\%M
561 * - \%m-\%d-\%Y \%H-\%M \%P
562 * - \%m-\%d-\%Y \%H-\%M \%p
563 * - \%m-\%d-\%Y \%I-\%M \%P
564 * - \%m-\%d-\%Y \%I-\%M \%p
565 * - \%m-\%d-\%Y \%H-\%M-\%S
566 * - \%m-\%d-\%Y \%H-\%M-\%S \%P
567 * - \%m-\%d-\%Y \%H-\%M-\%S \%p
568 * - \%m-\%d-\%Y \%I-\%M-\%S \%P
569 * - \%m-\%d-\%Y \%I-\%M-\%S \%p
570 * - \%m-\%d-\%Y \%H-\%M-\%S \%z
571 * - \%m-\%d-\%Y T \%H
572 * - \%m-\%d-\%Y T \%H \%P
573 * - \%m-\%d-\%Y T \%H \%p
574 * - \%m-\%d-\%Y T \%I \%P
575 * - \%m-\%d-\%Y T \%I \%p
576 * - \%m-\%d-\%Y T \%H\%M
577 * - \%m-\%d-\%Y T \%H\%M \%P
578 * - \%m-\%d-\%Y T \%H\%M \%p
579 * - \%m-\%d-\%Y T \%I\%M \%P
580 * - \%m-\%d-\%Y T \%I\%M \%p
581 * - \%m-\%d-\%Y T \%H\%M\%S
582 * - \%m-\%d-\%Y T \%H\%M\%S \%P
583 * - \%m-\%d-\%Y T \%H\%M\%S \%p
584 * - \%m-\%d-\%Y T \%H\%M\%S \%z
585 * - \%m-\%d-\%Y T \%I\%M\%S \%P
586 * - \%m-\%d-\%Y T \%I\%M\%S \%p
587 * - \%m-\%d-\%Y T \%H:\%M
588 * - \%m-\%d-\%Y T \%H:\%M \%P
589 * - \%m-\%d-\%Y T \%H:\%M \%p
590 * - \%m-\%d-\%Y T \%I:\%M \%P
591 * - \%m-\%d-\%Y T \%I:\%M \%p
592 * - \%m-\%d-\%Y T \%H:\%M:\%S
593 * - \%m-\%d-\%Y T \%H:\%M:\%S \%P
594 * - \%m-\%d-\%Y T \%H:\%M:\%S \%p
595 * - \%m-\%d-\%Y T \%I:\%M:\%S \%P
596 * - \%m-\%d-\%Y T \%I:\%M:\%S \%p
597 * - \%m-\%d-\%Y T \%H:\%M:\%S \%z
598 * - \%m-\%d-\%Y T \%H-\%M
599 * - \%m-\%d-\%Y T \%H-\%M \%P
600 * - \%m-\%d-\%Y T \%H-\%M \%p
601 * - \%m-\%d-\%Y T \%I-\%M \%P
602 * - \%m-\%d-\%Y T \%I-\%M \%p
603 * - \%m-\%d-\%Y T \%H-\%M-\%S
604 * - \%m-\%d-\%Y T \%H-\%M-\%S \%P
605 * - \%m-\%d-\%Y T \%H-\%M-\%S \%p
606 * - \%m-\%d-\%Y T \%I-\%M-\%S \%P
607 * - \%m-\%d-\%Y T \%I-\%M-\%S \%p
608 * - \%m-\%d-\%Y T \%H-\%M-\%S \%z
609 * - \%m/\%d/\%y \%H
610 * - \%m/\%d/\%y \%H \%P
611 * - \%m/\%d/\%y \%H \%p
612 * - \%m/\%d/\%y \%I \%P
613 * - \%m/\%d/\%y \%I \%p
614 * - \%m/\%d/\%y \%H\%M
615 * - \%m/\%d/\%y \%H\%M \%P
616 * - \%m/\%d/\%y \%H\%M \%p
617 * - \%m/\%d/\%y \%I\%M \%P
618 * - \%m/\%d/\%y \%I\%M \%p
619 * - \%m/\%d/\%y \%H\%M\%S
620 * - \%m/\%d/\%y \%H\%M\%S \%P
621 * - \%m/\%d/\%y \%H\%M\%S \%p
622 * - \%m/\%d/\%y \%I\%M\%S \%P
623 * - \%m/\%d/\%y \%I\%M\%S \%p
624 * - \%m/\%d/\%y \%H\%M\%S \%z
625 * - \%m/\%d/\%y \%H:\%M
626 * - \%m/\%d/\%y \%H:\%M \%P
627 * - \%m/\%d/\%y \%H:\%M \%p
628 * - \%m/\%d/\%y \%I:\%M \%P
629 * - \%m/\%d/\%y \%I:\%M \%p
630 * - \%m/\%d/\%y \%H:\%M:\%S
631 * - \%m/\%d/\%y \%H:\%M:\%S \%P
632 * - \%m/\%d/\%y \%H:\%M:\%S \%p
633 * - \%m/\%d/\%y \%I:\%M:\%S \%P
634 * - \%m/\%d/\%y \%I:\%M:\%S \%p
635 * - \%m/\%d/\%y \%H:\%M:\%S \%z
636 * - \%m/\%d/\%y \%H-\%M
637 * - \%m/\%d/\%y \%H-\%M \%P
638 * - \%m/\%d/\%y \%H-\%M \%p
639 * - \%m/\%d/\%y \%I-\%M \%P
640 * - \%m/\%d/\%y \%I-\%M \%p
641 * - \%m/\%d/\%y \%H-\%M-\%S
642 * - \%m/\%d/\%y \%H-\%M-\%S \%P
643 * - \%m/\%d/\%y \%H-\%M-\%S \%p
644 * - \%m/\%d/\%y \%I-\%M-\%S \%P
645 * - \%m/\%d/\%y \%I-\%M-\%S \%p
646 * - \%m/\%d/\%y \%H-\%M-\%S \%z
647 * - \%m/\%d/\%y T \%H
648 * - \%m/\%d/\%y T \%H \%P
649 * - \%m/\%d/\%y T \%H \%p
650 * - \%m/\%d/\%y T \%I \%P
651 * - \%m/\%d/\%y T \%I \%p
652 * - \%m/\%d/\%y T \%H\%M
653 * - \%m/\%d/\%y T \%H\%M \%P
654 * - \%m/\%d/\%y T \%H\%M \%p
655 * - \%m/\%d/\%y T \%I\%M \%P
656 * - \%m/\%d/\%y T \%I\%M \%p
657 * - \%m/\%d/\%y T \%H\%M\%S
658 * - \%m/\%d/\%y T \%H\%M\%S \%P
659 * - \%m/\%d/\%y T \%H\%M\%S \%p
660 * - \%m/\%d/\%y T \%I\%M\%S \%P
661 * - \%m/\%d/\%y T \%I\%M\%S \%p
662 * - \%m/\%d/\%y T \%H\%M\%S \%z
663 * - \%m/\%d/\%y T \%H:\%M
664 * - \%m/\%d/\%y T \%H:\%M \%P
665 * - \%m/\%d/\%y T \%H:\%M \%p
666 * - \%m/\%d/\%y T \%I:\%M \%P
667 * - \%m/\%d/\%y T \%I:\%M \%p
668 * - \%m/\%d/\%y T \%H:\%M:\%S
669 * - \%m/\%d/\%y T \%H:\%M:\%S \%P
670 * - \%m/\%d/\%y T \%H:\%M:\%S \%p
671 * - \%m/\%d/\%y T \%I:\%M:\%S \%P
672 * - \%m/\%d/\%y T \%I:\%M:\%S \%p
673 * - \%m/\%d/\%y T \%H:\%M:\%S \%z
674 * - \%m/\%d/\%y T \%H-\%M
675 * - \%m/\%d/\%y T \%H-\%M \%P
676 * - \%m/\%d/\%y T \%H-\%M \%p
677 * - \%m/\%d/\%y T \%I-\%M \%P
678 * - \%m/\%d/\%y T \%I-\%M \%p
679 * - \%m/\%d/\%y T \%H-\%M-\%S
680 * - \%m/\%d/\%y T \%H-\%M-\%S \%P
681 * - \%m/\%d/\%y T \%H-\%M-\%S \%p
682 * - \%m/\%d/\%y T \%I-\%M-\%S \%P
683 * - \%m/\%d/\%y T \%I-\%M-\%S \%p
684 * - \%m/\%d/\%y T \%H-\%M-\%S \%z
685 * - \%Y/\%m/\%d \%H
686 * - \%Y/\%m/\%d \%H \%P
687 * - \%Y/\%m/\%d \%H \%p
688 * - \%Y/\%m/\%d \%I \%P
689 * - \%Y/\%m/\%d \%I \%p
690 * - \%Y/\%m/\%d \%H\%M
691 * - \%Y/\%m/\%d \%H\%M \%P
692 * - \%Y/\%m/\%d \%H\%M \%p
693 * - \%Y/\%m/\%d \%I\%M \%P
694 * - \%Y/\%m/\%d \%I\%M \%p
695 * - \%Y/\%m/\%d \%H\%M\%S
696 * - \%Y/\%m/\%d \%H\%M\%S \%P
697 * - \%Y/\%m/\%d \%H\%M\%S \%p
698 * - \%Y/\%m/\%d \%I\%M\%S \%P
699 * - \%Y/\%m/\%d \%I\%M\%S \%p
700 * - \%Y/\%m/\%d \%H\%M\%S \%z
701 * - \%Y/\%m/\%d \%H:\%M
702 * - \%Y/\%m/\%d \%H:\%M \%P
703 * - \%Y/\%m/\%d \%H:\%M \%p
704 * - \%Y/\%m/\%d \%I:\%M \%P
705 * - \%Y/\%m/\%d \%I:\%M \%p
706 * - \%Y/\%m/\%d \%H:\%M:\%S
707 * - \%Y/\%m/\%d \%H:\%M:\%S \%P
708 * - \%Y/\%m/\%d \%H:\%M:\%S \%p
709 * - \%Y/\%m/\%d \%I:\%M:\%S \%P
710 * - \%Y/\%m/\%d \%I:\%M:\%S \%p
711 * - \%Y/\%m/\%d \%H:\%M:\%S \%z
712 * - \%Y/\%m/\%d \%H-\%M
713 * - \%Y/\%m/\%d \%H-\%M \%P
714 * - \%Y/\%m/\%d \%H-\%M \%p
715 * - \%Y/\%m/\%d \%I-\%M \%P
716 * - \%Y/\%m/\%d \%I-\%M \%p
717 * - \%Y/\%m/\%d \%H-\%M-\%S
718 * - \%Y/\%m/\%d \%H-\%M-\%S \%P
719 * - \%Y/\%m/\%d \%H-\%M-\%S \%p
720 * - \%Y/\%m/\%d \%I-\%M-\%S \%P
721 * - \%Y/\%m/\%d \%I-\%M-\%S \%p
722 * - \%Y/\%m/\%d \%H-\%M-\%S \%z
723 * - \%Y/\%m/\%d T \%H
724 * - \%Y/\%m/\%d T \%H \%P
725 * - \%Y/\%m/\%d T \%H \%p
726 * - \%Y/\%m/\%d T \%I \%P
727 * - \%Y/\%m/\%d T \%I \%p
728 * - \%Y/\%m/\%d T \%H\%M
729 * - \%Y/\%m/\%d T \%H\%M \%P
730 * - \%Y/\%m/\%d T \%H\%M \%p
731 * - \%Y/\%m/\%d T \%I\%M \%P
732 * - \%Y/\%m/\%d T \%I\%M \%p
733 * - \%Y/\%m/\%d T \%H\%M\%S
734 * - \%Y/\%m/\%d T \%H\%M\%S \%P
735 * - \%Y/\%m/\%d T \%H\%M\%S \%p
736 * - \%Y/\%m/\%d T \%I\%M\%S \%P
737 * - \%Y/\%m/\%d T \%I\%M\%S \%p
738 * - \%Y/\%m/\%d T \%H\%M\%S \%z
739 * - \%Y/\%m/\%d T \%H:\%M
740 * - \%Y/\%m/\%d T \%H:\%M \%P
741 * - \%Y/\%m/\%d T \%H:\%M \%p
742 * - \%Y/\%m/\%d T \%I:\%M \%P
743 * - \%Y/\%m/\%d T \%I:\%M \%p
744 * - \%Y/\%m/\%d T \%H:\%M:\%S
745 * - \%Y/\%m/\%d T \%H:\%M:\%S \%P
746 * - \%Y/\%m/\%d T \%H:\%M:\%S \%p
747 * - \%Y/\%m/\%d T \%I:\%M:\%S \%P
748 * - \%Y/\%m/\%d T \%I:\%M:\%S \%p
749 * - \%Y/\%m/\%d T \%H:\%M:\%S \%z
750 * - \%Y/\%m/\%d T \%H-\%M
751 * - \%Y/\%m/\%d T \%H-\%M \%P
752 * - \%Y/\%m/\%d T \%H-\%M \%p
753 * - \%Y/\%m/\%d T \%I-\%M \%P
754 * - \%Y/\%m/\%d T \%I-\%M \%p
755 * - \%Y/\%m/\%d T \%H-\%M-\%S
756 * - \%Y/\%m/\%d T \%H-\%M-\%S \%P
757 * - \%Y/\%m/\%d T \%H-\%M-\%S \%p
758 * - \%Y/\%m/\%d T \%I-\%M-\%S \%P
759 * - \%Y/\%m/\%d T \%I-\%M-\%S \%p
760 * - \%Y/\%m/\%d T \%H-\%M-\%S \%z
761 * - \%Y-\%m-\%d \%H
762 * - \%Y-\%m-\%d \%H \%P
763 * - \%Y-\%m-\%d \%H \%p
764 * - \%Y-\%m-\%d \%I \%P
765 * - \%Y-\%m-\%d \%I \%p
766 * - \%Y-\%m-\%d \%H\%M
767 * - \%Y-\%m-\%d \%H\%M \%P
768 * - \%Y-\%m-\%d \%H\%M \%p
769 * - \%Y-\%m-\%d \%I\%M \%P
770 * - \%Y-\%m-\%d \%I\%M \%p
771 * - \%Y-\%m-\%d \%H\%M\%S
772 * - \%Y-\%m-\%d \%H\%M\%S \%P
773 * - \%Y-\%m-\%d \%H\%M\%S \%p
774 * - \%Y-\%m-\%d \%I\%M\%S \%P
775 * - \%Y-\%m-\%d \%I\%M\%S \%p
776 * - \%Y-\%m-\%d \%H\%M\%S \%z
777 * - \%Y-\%m-\%d \%H:\%M
778 * - \%Y-\%m-\%d \%H:\%M \%P
779 * - \%Y-\%m-\%d \%H:\%M \%p
780 * - \%Y-\%m-\%d \%I:\%M \%P
781 * - \%Y-\%m-\%d \%I:\%M \%p
782 * - \%Y-\%m-\%d \%H:\%M:\%S
783 * - \%Y-\%m-\%d \%H:\%M:\%S \%P
784 * - \%Y-\%m-\%d \%H:\%M:\%S \%p
785 * - \%Y-\%m-\%d \%I:\%M:\%S \%P
786 * - \%Y-\%m-\%d \%I:\%M:\%S \%p
787 * - \%Y-\%m-\%d \%H:\%M:\%S \%z
788 * - \%Y-\%m-\%d \%H-\%M
789 * - \%Y-\%m-\%d \%H-\%M \%P
790 * - \%Y-\%m-\%d \%H-\%M \%p
791 * - \%Y-\%m-\%d \%I-\%M \%P
792 * - \%Y-\%m-\%d \%I-\%M \%p
793 * - \%Y-\%m-\%d \%H-\%M-\%S
794 * - \%Y-\%m-\%d \%H-\%M-\%S \%P
795 * - \%Y-\%m-\%d \%H-\%M-\%S \%p
796 * - \%Y-\%m-\%d \%I-\%M-\%S \%P
797 * - \%Y-\%m-\%d \%I-\%M-\%S \%p
798 * - \%Y-\%m-\%d \%H-\%M-\%S \%z
799 * - \%Y-\%m-\%d T \%H
800 * - \%Y-\%m-\%d T \%H \%P
801 * - \%Y-\%m-\%d T \%H \%p
802 * - \%Y-\%m-\%d T \%I \%P
803 * - \%Y-\%m-\%d T \%I \%p
804 * - \%Y-\%m-\%d T \%H\%M
805 * - \%Y-\%m-\%d T \%H\%M \%P
806 * - \%Y-\%m-\%d T \%H\%M \%p
807 * - \%Y-\%m-\%d T \%I\%M \%P
808 * - \%Y-\%m-\%d T \%I\%M \%p
809 * - \%Y-\%m-\%d T \%H\%M\%S
810 * - \%Y-\%m-\%d T \%H\%M\%S \%P
811 * - \%Y-\%m-\%d T \%H\%M\%S \%p
812 * - \%Y-\%m-\%d T \%I\%M\%S \%P
813 * - \%Y-\%m-\%d T \%I\%M\%S \%p
814 * - \%Y-\%m-\%d T \%H\%M\%S \%z
815 * - \%Y-\%m-\%d T \%H:\%M
816 * - \%Y-\%m-\%d T \%H:\%M \%P
817 * - \%Y-\%m-\%d T \%H:\%M \%p
818 * - \%Y-\%m-\%d T \%I:\%M \%P
819 * - \%Y-\%m-\%d T \%I:\%M \%p
820 * - \%Y-\%m-\%d T \%H:\%M:\%S
821 * - \%Y-\%m-\%d T \%H:\%M:\%S \%P
822 * - \%Y-\%m-\%d T \%H:\%M:\%S \%p
823 * - \%Y-\%m-\%d T \%I:\%M:\%S \%P
824 * - \%Y-\%m-\%d T \%I:\%M:\%S \%p
825 * - \%Y-\%m-\%d T \%H:\%M:\%S \%z
826 * - \%Y-\%m-\%d T \%H-\%M
827 * - \%Y-\%m-\%d T \%H-\%M \%P
828 * - \%Y-\%m-\%d T \%H-\%M \%p
829 * - \%Y-\%m-\%d T \%I-\%M \%P
830 * - \%Y-\%m-\%d T \%I-\%M \%p
831 * - \%Y-\%m-\%d T \%H-\%M-\%S
832 * - \%Y-\%m-\%d T \%H-\%M-\%S \%P
833 * - \%Y-\%m-\%d T \%H-\%M-\%S \%p
834 * - \%Y-\%m-\%d T \%I-\%M-\%S \%P
835 * - \%Y-\%m-\%d T \%I-\%M-\%S \%p
836 * - \%Y-\%m-\%d T \%H-\%M-\%S \%z
837 * - \%m/\%d/\%Y
838 * - \%m-\%d-\%Y
839 * - \%m-\%d-\%y
840 * - \%m/\%d/\%y
841 * - \%m\%d\%Y
842 * - \%m\%d\%y
843 * - \%Y/\%m/\%d
844 * - \%Y-\%m-\%d
845 *
846 * \param[in] timestr The time string to parse.
847 * \param[in] tz The time zone to use. If NULL the local system time zone will be used.
848 * This will only be used if the parsed time does not include a fixed
849 * time zone offset.
850 * \param[in] default_end_of_day M_TRUE when the returned time be at the end of the day if a time is not explictly
851 * present in the string.
852 *
853 * \return M_time_t of the parsed time. -1 on error.
854 *
855 * \see M_time_parsefmt
856 */
857M_API M_time_t M_time_from_str(const char *timestr, const M_time_tz_t *tz, M_bool default_end_of_day);
858
859
860/*! Format a date and time as a string.
861 *
862 * \param[in] fmt The format of the string.
863 * \param[in] tm The tm strcut to read from.
864 *
865 * Supports the following format options
866 * - %% - The % character.
867 * - \%a - Weekday abbreviation (ex: Wed) - English only. Output only.
868 * - \%b - Month abbreviation (ex: Jan) - English only. Output only.
869 * - \%m - month in 2 digit format.
870 * - \%d - day in 2 digit format.
871 * - \%y - year in 2 digit format.
872 * - \%Y - year in 4 digit format.
873 * - \%H - hour in 2 digit (24 hour) format.
874 * - \%I - hour in 2 digit (12 hour) format. Should be paired with am/pm descriptors.
875 * - \%M - minutes in 2 digit format.
876 * - \%S - seconds in 2 digit format.
877 * - \%T - shortcut for "%H:%M:%S".
878 * - \%P, \%p - AM/PM, am/pm.
879 * - \%z - timezone [+-]hhmm
880 * - \%Z - timezone abbreviation (ex EST, EDT)
881 * \return NULL if failed to format string. Otherwise returns a NULL terminated string.
882 *
883 * \see M_time_parsefmt
884 */
885M_API char *M_time_to_str(const char *fmt, const M_time_localtm_t *tm) M_WARN_NONNULL(1) M_WARN_NONNULL(2);
886
887/*! Parse a formatted time string into a tm structure.
888 *
889 * Supports the following input descriptors:
890 *
891 * - %% - The % character.
892 * - \%m - month in 2 digit format.
893 * - \%d - day in 2 digit format.
894 * - \%y - year in 2 digit format.
895 * - \%Y - year in 4 digit format.
896 * - \%H - hour in 2 digit (24 hour) format.
897 * - \%I - hour in 2 digit (12 hour) format. Should be paired with am/pm descriptors.
898 * - \%M - minutes in 2 digit format.
899 * - \%S - seconds in 2 digit format.
900 * - \%z - offset from gmt. RFC-822 Character(s) identifier or ISO 8601 [+-]hh[[:]mm] numeric offset.
901 * - \%P, \%p - AM/PM, am/pm (can parse A.M./P.M./a.m./p.m.).
902 *
903 * Notes on format:
904 *
905 * - Whitespace between descriptors is ignored but non-whitespace characters are not.
906 * - E.G: "%m%d" is equivalent to "%m %d" but not equivalent to "%m 7 %d".
907 * - YY is calculated as current year -80 to +20.
908 * - E.g. YY = 30. Current year is 2013. Parsed year will be 2030.
909 * YY = 50. Current year is 2013. Parsed year will be 1950.
910 * - z supports multiple representations of the zone information based on RFC-822 and ISO 8601:
911 * - +/- Digit:
912 * - [+-]hh[[:]mm]
913 * Named:
914 * - UTC/GMT/UT/Z = 0
915 * - EST/EDT = -5/-4
916 * - CST/CDT = -6/-5
917 * - MST/MDT = -7/-6
918 * - PST/PDT = -8/-7
919 * 1ALPHA:
920 * - A: -1 (J not used) to M: -12
921 * - N: +1 to Y: +12
922 *
923 * \param[in] s The string to parse.
924 * \param[in] fmt The format of the string.
925 * \param[out] tm The tm strcut to fill.
926 *
927 * \return NULL if failed to match format otherwise returns pointer
928 * to where it stopped processing in the buffer. If successfully
929 * processed entire buffer then returns pointer to NULL byte in buffer.
930 *
931 * \see M_time_from_str
932 */
933M_API char *M_time_parsefmt(const char *s, const char *fmt, M_time_localtm_t *tm) M_WARN_NONNULL(2) M_WARN_NONNULL(3);
934
935/*! @} */
936
937
938/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
939
940/*! \addtogroup m_time_zone Timezone
941 * \ingroup m_time
942 *
943 * @{
944 */
945
946/*! Create an empty timezone db.
947 *
948 * \return Time zone db.
949 */
951
952
953/*! Destroy a time zone db.
954 *
955 * \param[in] tzs Time zone db.
956 */
958
959
960/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
961
962/*! Load default timezones from system available source.
963 *
964 * This will attempt to load system timezone data. If that fails, it will fall
965 * back to loading the four main US timezones with DST times and without
966 * historic data.
967 *
968 * - ET: Eastern
969 * - CT: Central
970 * - MT: Mountain
971 * - PT: Pacific
972 *
973 * \param[out] tzs Time zone db.
974 * \param[in] zones M_time_tz_zones_t zones. What zones from the db should be loaded.
975 * \param[in] alias_f M_time_tz_alias_t to handle alias loading.
976 * \param[in] flags M_time_tz_load_t flags. How should the data be loaded. Specifically should lazy loading be used.
977 * When lazying loading data is read from disk (and cached) on
978 * demand. If lazy loading is not used all day is read from disk immediately.
979 *
980 * \return Source timezone data was loaded from.
981 */
982M_API M_time_load_source_t M_time_tzs_load(M_time_tzs_t **tzs, M_uint32 zones, M_uint32 alias_f, M_uint32 flags);
983
984
985/*! Load a tzs with data from a precomputed Olson/TZ/Zoneinfo db.
986 *
987 * To prevent possible issues the zoneinfo path cannot be a symlink. If it is a symlink the symlink needs to
988 * be resolved before passing into this function. Further, symlinks within the zoneinfo base dir cannot
989 * point to locations outside of the base dir.
990 *
991 * \param[in] path The path to the data to load. On Unix systems this is typically "/usr/share/zoneinfo" or
992 * "/usr/lib/zoneinfo". If NULL those two default locations will be checked for zoneinfo.
993 * \param[in] zones M_time_tz_zones_t zones. What zones from the db should be loaded.
994 * \param[in] alias_f M_time_tz_alias_t to handle alias loading.
995 * \param[in] flags M_time_tz_load_t flags. How should the data be loaded. Specifically should lazy loading be used.
996 * When lazying loading data is read from disk (and cached) on
997 * demand. If lazy loading is not used all day is read from disk immediately.
998 *
999 * \return Time zone db.
1000 */
1001M_API M_time_tzs_t *M_time_tzs_load_zoneinfo(const char *path, M_uint32 zones, M_uint32 alias_f, M_uint32 flags);
1002
1003
1004/*! Load a tzs with data from the Windows time zone database.
1005 *
1006 * Windows only.
1007 *
1008 * \param[in] zones M_time_tz_zones_t zones. What zones from the db should be loaded.
1009 * \param[in] alias_f M_time_tz_alias_t to handle alias loading.
1010 * \param[in] flags M_time_tz_load_t flags. How should the data be loaded. Specifically should lazy loading be used.
1011 * When lazying loading data is read from disk (and cached) on
1012 * demand. If lazy loading is not used all day is read from disk immediately.
1013 *
1014 * \return Time zone db.
1015 */
1016M_API M_time_tzs_t *M_time_tzs_load_win_zones(M_uint32 zones, M_uint32 alias_f, M_uint32 flags);
1017
1018
1019/*! Add data from the Windows time zone database.
1020 *
1021 * Windows only.
1022 *
1023 * \param[in,out] tzs The tz db.
1024 * \param[in] name The info to load. Only the Windows name is supported.
1025 *
1026 * \return Success on success. Otherwise error condition.
1027 */
1029
1030
1031/*! Add the timezone data from a Posix TZ string.
1032 *
1033 * Only the M day of week format is supported for specifying transition day.
1034 * Example: EST5EDT,M3.2.0/02:00:00,M11.1.0/02:00:00
1035 *
1036 * \param[in,out] tzs The tz db.
1037 * \param[in] str The string to parse.
1038 *
1039 * \return Success on success. Otherwise error condition.
1040 */
1042
1043
1044/*! Add data from a specific TZif file.
1045 *
1046 * \param[in,out] tzs The tz db.
1047 * \param[in] path The file to load.
1048 * \param[in] name The name to associate with the file.
1049 *
1050 * \return Success on success. Otherwise error condition.
1051 */
1052M_API M_time_result_t M_time_tzs_add_tzfile(M_time_tzs_t *tzs, const char *path, const char *name);
1053
1054
1055/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1056
1057/*! Get a list of loaded timezones.
1058 *
1059 * The names are stored case preserving but a lookup is case insensitive.
1060 *
1061 * \param[in] tzs The tz db.
1062 *
1063 * \return A list of names in the db.
1064 */
1066
1067
1068/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1069
1070/*! Get a specific tz from the db.
1071 *
1072 * The time zone will be loaded if lazy loading is in use.
1073 *
1074 * \param[in,out] tzs The tz db.
1075 * \param[in] name The name of the tz. The names are looked up case insensitive.
1076 *
1077 * \return The tz on success. Otherwise NULL if a tz for the given name was not found.
1078 */
1079M_API const M_time_tz_t *M_time_tzs_get_tz(M_time_tzs_t *tzs, const char *name);
1080
1081/*! @} */
1082
1083__END_DECLS
1084
1085/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1086
1087#endif /* __M_TIME_H__ */
struct M_list_str M_list_str_t
Definition: m_list_str.h:80
M_int64 M_time_timeval_diff(const M_timeval_t *start_time, const M_timeval_t *end_time)
void M_time_elapsed_start(M_timeval_t *start_tv)
M_uint64 M_time_elapsed(const M_timeval_t *start_tv)
char * M_time_parsefmt(const char *s, const char *fmt, M_time_localtm_t *tm)
char * M_time_to_str(const char *fmt, const M_time_localtm_t *tm)
M_time_t M_time_from_str(const char *timestr, const M_time_tz_t *tz, M_bool default_end_of_day)
M_bool M_time_gettimeofday(M_timeval_t *tv)
int M_time_days_in_month(M_int64 year, M_int64 month)
M_time_t M_time_fromgm(M_time_gmtm_t *tm)
M_time_t M_time(void)
void M_time_tolocal(M_time_t t, M_time_localtm_t *ltime, const M_time_tz_t *tz)
M_bool M_time_is_valid_day(M_int64 year, M_int64 month, M_int64 day)
void M_time_normalize_tm(struct M_time_tm *tm)
void M_time_togm(M_time_t t, M_time_gmtm_t *tm)
M_time_t M_time_fromlocal(M_time_localtm_t *ltime, const M_time_tz_t *tz)
M_time_result_t M_time_tzs_add_win_zone(M_time_tzs_t *tzs, const char *name)
M_time_tzs_t * M_time_tzs_load_win_zones(M_uint32 zones, M_uint32 alias_f, M_uint32 flags)
M_time_result_t M_time_tzs_add_tzfile(M_time_tzs_t *tzs, const char *path, const char *name)
M_time_load_source_t M_time_tzs_load(M_time_tzs_t **tzs, M_uint32 zones, M_uint32 alias_f, M_uint32 flags)
const M_time_tz_t * M_time_tzs_get_tz(M_time_tzs_t *tzs, const char *name)
void M_time_tzs_destroy(M_time_tzs_t *tzs)
M_list_str_t * M_time_tzs_get_loaded_zones(const M_time_tzs_t *tzs)
M_time_tzs_t * M_time_tzs_create(void)
M_time_tzs_t * M_time_tzs_load_zoneinfo(const char *path, M_uint32 zones, M_uint32 alias_f, M_uint32 flags)
M_time_result_t M_time_tzs_add_posix_str(M_time_tzs_t *tzs, const char *str)
M_int64 isdst
Definition: m_time.h:176
M_int64 day
Definition: m_time.h:167
M_int64 month
Definition: m_time.h:166
M_int64 sec
Definition: m_time.h:172
M_int64 year
Definition: m_time.h:168
M_int64 hour
Definition: m_time.h:170
M_int64 min
Definition: m_time.h:171
char abbr[32]
Definition: m_time.h:178
M_suseconds_t tv_usec
Definition: m_time.h:189
M_time_t gmtoff
Definition: m_time.h:177
M_int64 wday
Definition: m_time.h:173
M_time_t tv_sec
Definition: m_time.h:188
M_int64 year2
Definition: m_time.h:169
M_int64 yday
Definition: m_time.h:174
M_time_tz_load_t
Definition: m_time.h:223
M_int64 M_time_t
Definition: m_time.h:161
struct M_time_tzs M_time_tzs_t
Definition: m_time.h:200
M_int64 M_suseconds_t
Definition: m_time.h:162
M_time_load_source_t
Definition: m_time.h:263
struct M_time_tz M_time_tz_t
Definition: m_time.h:195
M_time_tz_zones_t
Definition: m_time.h:206
M_time_result_t
Definition: m_time.h:244
M_time_tz_alias_t
Definition: m_time.h:234
@ M_TIME_TZ_LOAD_NORMAL
Definition: m_time.h:224
@ M_TIME_TZ_LOAD_LAZY
Definition: m_time.h:225
@ M_TIME_LOAD_SOURCE_FAIL
Definition: m_time.h:264
@ M_TIME_LOAD_SOURCE_SYSTEM
Definition: m_time.h:269
@ M_TIME_LOAD_SOURCE_FALLBACK
Definition: m_time.h:270
@ M_TIME_TZ_ZONE_ALL
Definition: m_time.h:207
@ M_TIME_TZ_ZONE_ANTARCTICA
Definition: m_time.h:210
@ M_TIME_TZ_ZONE_ASIA
Definition: m_time.h:212
@ M_TIME_TZ_ZONE_PACIFIC
Definition: m_time.h:217
@ M_TIME_TZ_ZONE_EUROPE
Definition: m_time.h:215
@ M_TIME_TZ_ZONE_ARCTIC
Definition: m_time.h:211
@ M_TIME_TZ_ZONE_ATLANTIC
Definition: m_time.h:213
@ M_TIME_TZ_ZONE_AMERICA
Definition: m_time.h:209
@ M_TIME_TZ_ZONE_ETC
Definition: m_time.h:218
@ M_TIME_TZ_ZONE_AUSTRALIA
Definition: m_time.h:214
@ M_TIME_TZ_ZONE_INDIAN
Definition: m_time.h:216
@ M_TIME_TZ_ZONE_AFRICA
Definition: m_time.h:208
@ M_TIME_RESULT_DATE
Definition: m_time.h:252
@ M_TIME_RESULT_YEAR
Definition: m_time.h:255
@ M_TIME_RESULT_SUCCESS
Definition: m_time.h:245
@ M_TIME_RESULT_TIME
Definition: m_time.h:253
@ M_TIME_RESULT_OFFSET
Definition: m_time.h:251
@ M_TIME_RESULT_INI
Definition: m_time.h:249
@ M_TIME_RESULT_DUP
Definition: m_time.h:248
@ M_TIME_RESULT_INVALID
Definition: m_time.h:246
@ M_TIME_RESULT_ABBR
Definition: m_time.h:250
@ M_TIME_RESULT_ERROR
Definition: m_time.h:247
@ M_TIME_RESULT_DSTABBR
Definition: m_time.h:256
@ M_TIME_RESULT_DATETIME
Definition: m_time.h:254
@ M_TIME_RESULT_DSTOFFSET
Definition: m_time.h:257
@ M_TIME_TZ_ALIAS_ALL
Definition: m_time.h:235
@ M_TIME_TZ_ALIAS_WINDOWS_MAIN
Definition: m_time.h:238
@ M_TIME_TZ_ALIAS_OLSON_ALL
Definition: m_time.h:237
@ M_TIME_TZ_ALIAS_WINDOWS_ALL
Definition: m_time.h:239
@ M_TIME_TZ_ALIAS_OLSON_MAIN
Definition: m_time.h:236
Definition: m_time.h:165
Definition: m_time.h:187