Asterisk - The Open Source Telephony Project GIT-master-67613d1
Data Structures | Macros | Typedefs | Functions
localtime.h File Reference

Custom localtime functions for multiple timezones. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_tm
 

Macros

#define AST_ISO8601_FORMAT   "%FT%T.%q%z"
 ast_strftime for ISO8601 formatting timestamps. More...
 
#define AST_ISO8601_LEN   29
 Max length of an null terminated, millisecond resolution, ISO8601 timestamp string. More...
 

Typedefs

typedef void * locale_t
 

Functions

void ast_get_dst_info (const time_t *const timep, int *dst_enabled, time_t *dst_start, time_t *dst_end, int *gmt_off, const char *const zone)
 
struct ast_tmast_localtime (const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
 Timezone-independent version of localtime_r(3). More...
 
void ast_localtime_wakeup_monitor (struct ast_test *info)
 
struct timeval ast_mktime (struct ast_tm *const tmp, const char *zone)
 Timezone-independent version of mktime(3). More...
 
const char * ast_setlocale (const char *locale)
 Set the thread-local representation of the current locale. More...
 
int ast_strftime (char *buf, size_t len, const char *format, const struct ast_tm *tm)
 Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strftime(3), with the addition of q, which specifies microseconds. More...
 
int ast_strftime_locale (char *buf, size_t len, const char *format, const struct ast_tm *tm, const char *locale)
 
char * ast_strptime (const char *s, const char *format, struct ast_tm *tm)
 Special version of strptime(3) which places the answer in the common structure ast_tm. Also, unlike strptime(3), ast_strptime() initializes its memory prior to use. More...
 
char * ast_strptime_locale (const char *s, const char *format, struct ast_tm *tm, const char *locale)
 

Detailed Description

Custom localtime functions for multiple timezones.

Definition in file localtime.h.

Macro Definition Documentation

◆ AST_ISO8601_FORMAT

#define AST_ISO8601_FORMAT   "%FT%T.%q%z"

ast_strftime for ISO8601 formatting timestamps.

Definition at line 103 of file localtime.h.

◆ AST_ISO8601_LEN

#define AST_ISO8601_LEN   29

Max length of an null terminated, millisecond resolution, ISO8601 timestamp string.

Definition at line 105 of file localtime.h.

Typedef Documentation

◆ locale_t

typedef void* locale_t

Definition at line 32 of file localtime.h.

Function Documentation

◆ ast_get_dst_info()

void ast_get_dst_info ( const time_t *const  timep,
int *  dst_enabled,
time_t *  dst_start,
time_t *  dst_end,
int *  gmt_off,
const char *const  zone 
)

Definition at line 1754 of file localtime.c.

1755{
1756 int i;
1757 int transition1 = -1;
1758 int transition2 = -1;
1759 time_t seconds;
1760 int bounds_exceeded = 0;
1761 time_t t = *timep;
1762 const struct state *sp;
1763
1764 if (NULL == dst_enabled)
1765 return;
1766 *dst_enabled = 0;
1767
1768 if (NULL == dst_start || NULL == dst_end || NULL == gmt_off)
1769 return;
1770
1771 *gmt_off = 0;
1772
1773 sp = ast_tzset(zone);
1774 if (NULL == sp)
1775 return;
1776
1777 /* If the desired time exceeds the bounds of the defined time transitions
1778 * then give up on determining DST info and simply look for gmt offset
1779 * This requires that I adjust the given time using increments of Gregorian
1780 * repeats to place the time within the defined time transitions in the
1781 * timezone structure.
1782 */
1783 if ((sp->goback && t < sp->ats[0]) ||
1784 (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1785 time_t tcycles;
1786 int_fast64_t icycles;
1787
1788 if (t < sp->ats[0])
1789 seconds = sp->ats[0] - t;
1790 else seconds = t - sp->ats[sp->timecnt - 1];
1791 --seconds;
1792 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1793 ++tcycles;
1794 icycles = tcycles;
1795 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1796 return;
1797 seconds = icycles;
1798 seconds *= YEARSPERREPEAT;
1799 seconds *= AVGSECSPERYEAR;
1800 if (t < sp->ats[0])
1801 t += seconds;
1802 else
1803 t -= seconds;
1804
1805 if (t < sp->ats[0] || t > sp->ats[sp->timecnt - 1])
1806 return; /* "cannot happen" */
1807
1808 bounds_exceeded = 1;
1809 }
1810
1811 if (sp->timecnt == 0 || t < sp->ats[0]) {
1812 /* I have no transition times or I'm before time */
1813 *dst_enabled = 0;
1814 /* Find where I can get gmtoff */
1815 i = 0;
1816 while (sp->ttis[i].tt_isdst) {
1817 if (++i >= sp->typecnt) {
1818 i = 0;
1819 break;
1820 }
1821 }
1822 *gmt_off = sp->ttis[i].tt_gmtoff;
1823 return;
1824 }
1825
1826 for (i = 1; i < sp->timecnt; ++i) {
1827 if (t < sp->ats[i]) {
1828 transition1 = sp->types[i - 1];
1829 transition2 = sp->types[i];
1830 break;
1831 }
1832 }
1833 /* if I found transition times that do not bounded the given time and these correspond to
1834 or the bounding zones do not reflect a changes in day light savings, then I do not have dst active */
1835 if (i >= sp->timecnt || 0 > transition1 || 0 > transition2 ||
1836 (sp->ttis[transition1].tt_isdst == sp->ttis[transition2].tt_isdst)) {
1837 *dst_enabled = 0;
1838 *gmt_off = sp->ttis[sp->types[sp->timecnt -1]].tt_gmtoff;
1839 } else {
1840 /* I have valid daylight savings information. */
1841 if(sp->ttis[transition2].tt_isdst)
1842 *gmt_off = sp->ttis[transition1].tt_gmtoff;
1843 else
1844 *gmt_off = sp->ttis[transition2].tt_gmtoff;
1845
1846 /* If I adjusted the time earlier, indicate that the dst is invalid */
1847 if (!bounds_exceeded) {
1848 *dst_enabled = 1;
1849 /* Determine which of the bounds is the start of daylight savings and which is the end */
1850 if(sp->ttis[transition2].tt_isdst) {
1851 *dst_start = sp->ats[i];
1852 *dst_end = sp->ats[i -1];
1853 } else {
1854 *dst_start = sp->ats[i -1];
1855 *dst_end = sp->ats[i];
1856 }
1857 }
1858 }
1859 return;
1860}
static const struct state * ast_tzset(const char *zone)
Definition: localtime.c:1601
#define AVGSECSPERYEAR
you may need to compile with DHAVE_STDINT_H typedef long int_fast64_t
#define YEARSPERREPEAT
#define NULL
Definition: resample.c:96
int typecnt
Definition: localtime.c:163
int goback
Definition: localtime.c:165
time_t ats[TZ_MAX_TIMES]
Definition: localtime.c:167
int timecnt
Definition: localtime.c:162
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: localtime.c:169
unsigned char types[TZ_MAX_TIMES]
Definition: localtime.c:168
int goahead
Definition: localtime.c:166
int tt_isdst
Definition: localtime.c:134
long tt_gmtoff
Definition: localtime.c:133

References ast_tzset(), state::ats, AVGSECSPERYEAR, state::goahead, state::goback, int_fast64_t, NULL, state::timecnt, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::typecnt, state::types, and YEARSPERREPEAT.

Referenced by set_timezone_variables().

◆ ast_localtime()

struct ast_tm * ast_localtime ( const struct timeval *  timep,
struct ast_tm p_tm,
const char *  zone 
)

Timezone-independent version of localtime_r(3).

Parameters
timepCurrent time, including microseconds
p_tmPointer to memory where the broken-out time will be stored
zoneText string of a standard system zoneinfo file. If NULL, the system localtime will be used.
Return values
p_tmis returned for convenience

Definition at line 1739 of file localtime.c.

1740{
1741 const struct state *sp = ast_tzset(zone);
1742 memset(tmp, 0, sizeof(*tmp));
1743 return sp ? localsub(timep, 0L, tmp, sp) : NULL;
1744}
static int tmp()
Definition: bt_open.c:389
static struct ast_tm * localsub(const struct timeval *timep, const long offset, struct ast_tm *tmp, const struct state *sp)
Definition: localtime.c:1648

References ast_tzset(), localsub(), NULL, and tmp().

Referenced by acf_strftime(), action_corestatus(), append_date(), ast_cel_fabricate_channel_from_event(), ast_check_timing2(), ast_http_send(), ast_json_timeval(), ast_queue_log(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_is(), ast_say_date_ja(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_pt(), ast_say_date_th(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_gr(), ast_say_date_with_format_he(), ast_say_date_with_format_is(), ast_say_date_with_format_it(), ast_say_date_with_format_ja(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), ast_say_date_with_format_zh(), ast_say_datetime_de(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_from_now_pt(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_hu(), ast_say_datetime_ja(), ast_say_datetime_ka(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_pt_BR(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_ja(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_th(), ast_say_time_zh(), AST_TEST_DEFINE(), beanstalk_put(), build_device(), build_radius_record(), callerid_genmsg(), cdr_get_tv(), cdr_read_callback(), cel_bs_put(), cli_prompt(), cli_show_tasks(), conf_run(), epoch_to_string(), exchangecal_get_events_between(), execute_cb(), find_conf_realtime(), format_log_message_ap(), get_date(), get_ewscal_ids_for(), handle_cli_odbc_show(), handle_cli_test_locales(), handle_minivm_show_stats(), handle_show_settings(), http_callback(), iax2_datetime(), isodate(), leave_voicemail(), main(), make_email_file(), make_logchannel(), manager_log(), mstime(), odbc_log(), packdate(), pgsql_log(), play_message_datetime(), prep_email_sub_vars(), prometheus_show_status(), rt_extend_conf(), say_date_generic(), send_date_time(), send_date_time2(), send_date_time3(), sendmail(), set_header(), set_timezone_variables(), sms_compose2(), sms_handleincoming_proto2(), static_callback(), timeout_write(), vmu_tm(), write_history(), and write_metadata().

◆ ast_localtime_wakeup_monitor()

void ast_localtime_wakeup_monitor ( struct ast_test *  info)

Definition at line 795 of file localtime.c.

796{
797 struct timeval wait_now = ast_tvnow();
798 struct timespec wait_time = { .tv_sec = wait_now.tv_sec + 2, .tv_nsec = wait_now.tv_usec * 1000 };
799
802#ifdef TEST_FRAMEWORK
803 test = info;
804#endif
805 pthread_kill(inotify_thread, SIGURG);
807#ifdef TEST_FRAMEWORK
808 test = NULL;
809#endif
811 }
812}
ast_mutex_t lock
Definition: app_sla.c:331
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
static ast_cond_t initialization
Definition: localtime.c:322
static pthread_t inotify_thread
Definition: localtime.c:321
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
def info(msg)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ast_cond_timedwait, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_tvnow(), sip_to_pjsip::info(), initialization, inotify_thread, lock, and NULL.

Referenced by AST_TEST_DEFINE().

◆ ast_mktime()

struct timeval ast_mktime ( struct ast_tm *const  tmp,
const char *  zone 
)

Timezone-independent version of mktime(3).

Parameters
tmpCurrent broken-out time, including microseconds
zoneText string of a standard system zoneinfo file. If NULL, the system localtime will be used.
Return values
Astructure containing both seconds and fractional thereof since January 1st, 1970 UTC

Definition at line 2357 of file localtime.c.

2358{
2359 const struct state *sp;
2360 if (!(sp = ast_tzset(zone)))
2361 return WRONG;
2362 return time1(tmp, localsub, 0L, sp);
2363}
static const struct timeval WRONG
Definition: localtime.c:111
static struct timeval time1(struct ast_tm *tmp, struct ast_tm *(*const funcp)(const struct timeval *, long, struct ast_tm *, const struct state *), const long offset, const struct state *sp)
Definition: localtime.c:2292

References ast_tzset(), localsub(), time1(), tmp(), and WRONG.

Referenced by acf_strptime(), add_cert_expiration_to_astdb(), check_date_header(), conf_run(), find_conf_realtime(), icalfloat_to_timet(), mstime_to_time_t(), rt_extend_conf(), sms_handleincoming_proto2(), sms_readfile(), testtime_write(), and unpackdate().

◆ ast_setlocale()

const char * ast_setlocale ( const char *  locale)

Set the thread-local representation of the current locale.

Definition at line 2420 of file localtime.c.

2421{
2422 struct locale_entry *cur;
2423 locale_t prevlocale = LC_GLOBAL_LOCALE;
2424
2425 if (locale == NULL) {
2426 return store_by_locale(uselocale(LC_GLOBAL_LOCALE));
2427 }
2428
2430 if ((cur = find_by_name(locale))) {
2431 prevlocale = uselocale(cur->locale);
2432 }
2433
2434 if (!cur) {
2435 if ((cur = ast_calloc(1, sizeof(*cur) + strlen(locale) + 1))) {
2436 cur->locale = newlocale(LC_ALL_MASK, locale, NULL);
2437 strcpy(cur->name, locale); /* SAFE */
2439 prevlocale = uselocale(cur->locale);
2440 }
2441 }
2443 return store_by_locale(prevlocale);
2444}
static char locale[20]
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
static struct locale_entry * find_by_name(const char *name)
Definition: localtime.c:2377
static const char * store_by_locale(locale_t prevlocale)
Definition: localtime.c:2388
void * locale_t
Definition: localtime.h:32
Definition: localtime.c:242
locale_t locale
Definition: localtime.c:244
struct locale_entry::@401 list
char name[0]
Definition: localtime.c:245

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, find_by_name(), locale_entry::list, locale, locale_entry::locale, locale_entry::name, NULL, and store_by_locale().

Referenced by ast_strftime_locale(), ast_strptime_locale(), and handle_cli_test_locales().

◆ ast_strftime()

int ast_strftime ( char *  buf,
size_t  len,
const char *  format,
const struct ast_tm tm 
)

Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strftime(3), with the addition of q, which specifies microseconds.

Parameters
bufAddress in memory where the resulting string will be stored.
lenSize of the chunk of memory buf.
formatA string specifying the format of time to be placed into buf.
tmPointer to the broken out time to be used for the format.
Return values
Aninteger value specifying the number of bytes placed into buf or -1 on error.

Definition at line 2524 of file localtime.c.

2525{
2526 return ast_strftime_locale(buf, len, tmp, tm, NULL);
2527}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_strftime_locale(char *buf, size_t len, const char *tmp, const struct ast_tm *tm, const char *locale)
Definition: localtime.c:2452

References ast_strftime_locale(), buf, len(), NULL, and tmp().

Referenced by acf_strftime(), action_corestatus(), append_date(), ast_cel_fabricate_channel_from_event(), ast_http_send(), ast_json_timeval(), ast_queue_log(), beanstalk_put(), build_radius_record(), cdr_get_tv(), cdr_read_callback(), cel_bs_put(), cli_prompt(), cli_show_tasks(), conf_run(), dump_datetime(), epoch_to_string(), exchangecal_get_events_between(), execute_cb(), find_conf_realtime(), format_log_message_ap(), get_date(), get_ewscal_ids_for(), handle_cli_odbc_show(), handle_cli_test_locales(), handle_minivm_show_stats(), handle_show_settings(), http_callback(), isodate(), leave_voicemail(), make_email_file(), make_logchannel(), manager_log(), mstime(), odbc_log(), pgsql_log(), prometheus_show_status(), rt_extend_conf(), sendmail(), sendpage(), set_header(), static_callback(), timeout_write(), and write_metadata().

◆ ast_strftime_locale()

int ast_strftime_locale ( char *  buf,
size_t  len,
const char *  format,
const struct ast_tm tm,
const char *  locale 
)

Definition at line 2452 of file localtime.c.

2453{
2454 size_t fmtlen = strlen(tmp) + 1;
2455 char *format = ast_calloc(1, fmtlen), *fptr = format, *newfmt;
2456 int decimals = -1, i, res;
2457 long fraction;
2458 const char *prevlocale;
2459
2460 buf[0] = '\0';/* Ensure the buffer is initialized. */
2461 if (!format) {
2462 return -1;
2463 }
2464 for (; *tmp; tmp++) {
2465 if (*tmp == '%') {
2466 switch (tmp[1]) {
2467 case '1':
2468 case '2':
2469 case '3':
2470 case '4':
2471 case '5':
2472 case '6':
2473 if (tmp[2] != 'q') {
2474 goto defcase;
2475 }
2476 decimals = tmp[1] - '0';
2477 tmp++;
2478 /* Fall through */
2479 case 'q': /* Milliseconds */
2480 if (decimals == -1) {
2481 decimals = 3;
2482 }
2483
2484 /* Juggle some memory to fit the item */
2485 newfmt = ast_realloc(format, fmtlen + decimals);
2486 if (!newfmt) {
2487 ast_free(format);
2488 return -1;
2489 }
2490 fptr = fptr - format + newfmt;
2491 format = newfmt;
2492 fmtlen += decimals;
2493
2494 /* Reduce the fraction of time to the accuracy needed */
2495 for (i = 6, fraction = tm->tm_usec; i > decimals; i--) {
2496 fraction /= 10;
2497 }
2498 fptr += sprintf(fptr, "%0*ld", decimals, fraction);
2499
2500 /* Reset, in case more than one 'q' specifier exists */
2501 decimals = -1;
2502 tmp++;
2503 break;
2504 default:
2505 goto defcase;
2506 }
2507 } else {
2508defcase: *fptr++ = *tmp;
2509 }
2510 }
2511 *fptr = '\0';
2512#undef strftime
2513 if (locale) {
2514 prevlocale = ast_setlocale(locale);
2515 }
2516 res = (int)strftime(buf, len, format, (struct tm *)tm);
2517 if (locale) {
2518 ast_setlocale(prevlocale);
2519 }
2520 ast_free(format);
2521 return res;
2522}
#define ast_free(a)
Definition: astmm.h:180
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226
const char * ast_setlocale(const char *locale)
Set the thread-local representation of the current locale.
Definition: localtime.c:2420
int tm_usec
Definition: localtime.h:48

References ast_calloc, ast_free, ast_realloc, ast_setlocale(), buf, len(), locale, ast_tm::tm_usec, and tmp().

Referenced by ast_strftime(), make_email_file(), prep_email_sub_vars(), and sendpage().

◆ ast_strptime()

char * ast_strptime ( const char *  s,
const char *  format,
struct ast_tm tm 
)

Special version of strptime(3) which places the answer in the common structure ast_tm. Also, unlike strptime(3), ast_strptime() initializes its memory prior to use.

Parameters
sA string specifying some portion of a date and time.
formatThe format in which the string, s, is expected.
tmThe broken-out time structure into which the parsed data is expected.
Return values
Apointer to the first character within s not used to parse the date and time.

Definition at line 2550 of file localtime.c.

2551{
2552 return ast_strptime_locale(s, format, tm, NULL);
2553}
char * ast_strptime_locale(const char *s, const char *format, struct ast_tm *tm, const char *locale)
Definition: localtime.c:2529

References ast_strptime_locale(), and NULL.

Referenced by acf_strptime(), add_cert_expiration_to_astdb(), check_date_header(), conf_run(), find_conf_realtime(), mstime_to_time_t(), rt_extend_conf(), and testtime_write().

◆ ast_strptime_locale()

char * ast_strptime_locale ( const char *  s,
const char *  format,
struct ast_tm tm,
const char *  locale 
)

Definition at line 2529 of file localtime.c.

2530{
2531 struct tm tm2 = { 0, };
2532 char *res;
2533 const char *prevlocale;
2534
2535 prevlocale = ast_setlocale(locale);
2536 res = strptime(s, format, &tm2);
2537 ast_setlocale(prevlocale);
2538 /* ast_time and tm are not the same size - tm is a subset of
2539 * ast_time. Hence, the size of tm needs to be used for the
2540 * memcpy
2541 */
2542 memcpy(tm, &tm2, sizeof(tm2));
2543 tm->tm_usec = 0;
2544 /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
2545 * to deal with it correctly, we set it to -1. */
2546 tm->tm_isdst = -1;
2547 return res;
2548}
int tm_isdst
Definition: localtime.h:44

References ast_setlocale(), locale, ast_tm::tm_isdst, and ast_tm::tm_usec.

Referenced by ast_strptime().