Wed Jan 8 2020 09:50:14

Asterisk developer's documentation


localtime.h File Reference

Custom localtime functions for multiple timezones. More...

#include <locale.h>

Go to the source code of this file.

Data Structures

struct  ast_tm
 

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.

Typedef Documentation

typedef void* locale_t

Definition at line 32 of file localtime.h.

Function Documentation

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 1585 of file localtime.c.

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

1586 {
1587  int i;
1588  int transition1 = -1;
1589  int transition2 = -1;
1590  time_t seconds;
1591  int bounds_exceeded = 0;
1592  time_t t = *timep;
1593  const struct state *sp;
1594 
1595  if (NULL == dst_enabled)
1596  return;
1597  *dst_enabled = 0;
1598 
1599  if (NULL == dst_start || NULL == dst_end || NULL == gmt_off)
1600  return;
1601 
1602  *gmt_off = 0;
1603 
1604  sp = ast_tzset(zone);
1605  if (NULL == sp)
1606  return;
1607 
1608  /* If the desired time exceeds the bounds of the defined time transitions
1609  * then give give up on determining DST info and simply look for gmt offset
1610  * This requires that I adjust the given time using increments of Gregorian
1611  * repeats to place the time within the defined time transitions in the
1612  * timezone structure.
1613  */
1614  if ((sp->goback && t < sp->ats[0]) ||
1615  (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1616  time_t tcycles;
1617  int_fast64_t icycles;
1618 
1619  if (t < sp->ats[0])
1620  seconds = sp->ats[0] - t;
1621  else seconds = t - sp->ats[sp->timecnt - 1];
1622  --seconds;
1623  tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1624  ++tcycles;
1625  icycles = tcycles;
1626  if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1627  return;
1628  seconds = icycles;
1629  seconds *= YEARSPERREPEAT;
1630  seconds *= AVGSECSPERYEAR;
1631  if (t < sp->ats[0])
1632  t += seconds;
1633  else
1634  t -= seconds;
1635 
1636  if (t < sp->ats[0] || t > sp->ats[sp->timecnt - 1])
1637  return; /* "cannot happen" */
1638 
1639  bounds_exceeded = 1;
1640  }
1641 
1642  if (sp->timecnt == 0 || t < sp->ats[0]) {
1643  /* I have no transition times or I'm before time */
1644  *dst_enabled = 0;
1645  /* Find where I can get gmtoff */
1646  i = 0;
1647  while (sp->ttis[i].tt_isdst)
1648  if (++i >= sp->typecnt) {
1649  i = 0;
1650  break;
1651  }
1652  *gmt_off = sp->ttis[i].tt_gmtoff;
1653  return;
1654  }
1655 
1656  for (i = 1; i < sp->timecnt; ++i) {
1657  if (t < sp->ats[i]) {
1658  transition1 = sp->types[i - 1];
1659  transition2 = sp->types[i];
1660  break;
1661  }
1662  }
1663  /* if I found transition times that do not bounded the given time and these correspond to
1664  or the bounding zones do not reflect a changes in day light savings, then I do not have dst active */
1665  if (i >= sp->timecnt || 0 > transition1 || 0 > transition2 ||
1666  (sp->ttis[transition1].tt_isdst == sp->ttis[transition2].tt_isdst)) {
1667  *dst_enabled = 0;
1668  *gmt_off = sp->ttis[sp->types[sp->timecnt -1]].tt_gmtoff;
1669  } else {
1670  /* I have valid daylight savings information. */
1671  if(sp->ttis[transition2].tt_isdst)
1672  *gmt_off = sp->ttis[transition1].tt_gmtoff;
1673  else
1674  *gmt_off = sp->ttis[transition2].tt_gmtoff;
1675 
1676  /* If I adjusted the time earlier, indicate that the dst is invalid */
1677  if (!bounds_exceeded) {
1678  *dst_enabled = 1;
1679  /* Determine which of the bounds is the start of daylight savings and which is the end */
1680  if(sp->ttis[transition2].tt_isdst) {
1681  *dst_start = sp->ats[i];
1682  *dst_end = sp->ats[i -1];
1683  } else {
1684  *dst_start = sp->ats[i -1];
1685  *dst_end = sp->ats[i];
1686  }
1687  }
1688  }
1689  return;
1690 }
#define AVGSECSPERYEAR
Definition: private.h:343
static struct state * ast_tzset(const char *zone)
Definition: localtime.c:1432
int typecnt
Definition: localtime.c:165
long tt_gmtoff
Definition: localtime.c:135
int goahead
Definition: localtime.c:168
int goback
Definition: localtime.c:167
int tt_isdst
Definition: localtime.c:136
#define YEARSPERREPEAT
Definition: private.h:335
time_t ats[TZ_MAX_TIMES]
Definition: localtime.c:169
you may need to compile with DHAVE_STDINT_H typedef long int_fast64_t
Definition: private.h:152
unsigned char types[TZ_MAX_TIMES]
Definition: localtime.c:170
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: localtime.c:171
int timecnt
Definition: localtime.c:164
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 1570 of file localtime.c.

References ast_tzset(), and localsub().

Referenced by __ast_verbose_ap(), acf_strftime(), action_corestatus(), append_date(), ast_cel_fabricate_channel_from_event(), ast_check_timing2(), ast_http_send(), ast_log(), ast_queue_log(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_es(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), 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_it(), 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_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_es(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), 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(), build_device(), build_radius_record(), callerid_genmsg(), cdr_get_tv(), cli_prompt(), conf_run(), enc_ie_date(), epoch_to_string(), exchangecal_get_events_between(), execute_cb(), find_conf_realtime(), format_date(), get_date(), get_ewscal_ids_for(), handle_cli_odbc_show(), handle_minivm_show_stats(), handle_show_settings(), iax2_datetime(), isodate(), leave_voicemail(), main(), make_email_file(), manager_log(), mstime(), odbc_log(), packdate(), pgsql_log(), phone_call(), play_message_datetime(), prep_email_sub_vars(), rt_extend_conf(), say_date_generic(), send_date_time(), send_date_time2(), send_date_time3(), sendmail(), sip_show_registry(), sms_compose2(), sms_handleincoming_proto2(), static_callback(), timeout_write(), transmit_definetimedate(), transmit_notify_request_with_callerid(), vmu_tm(), write_history(), and write_metadata().

1571 {
1572  const struct state *sp = ast_tzset(zone);
1573  memset(tmp, 0, sizeof(*tmp));
1574  return sp ? localsub(timep, 0L, tmp, sp) : NULL;
1575 }
static struct ast_tm * localsub(const struct timeval *timep, const long offset, struct ast_tm *tmp, const struct state *sp)
Definition: localtime.c:1479
static struct state * ast_tzset(const char *zone)
Definition: localtime.c:1432
void ast_localtime_wakeup_monitor ( struct ast_test *  info)

Definition at line 607 of file localtime.c.

References ast_cond_wait, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, and lock.

608 {
611 #ifdef TEST_FRAMEWORK
612  test = info;
613 #endif
614  pthread_kill(inotify_thread, SIGURG);
616 #ifdef TEST_FRAMEWORK
617  test = NULL;
618 #endif
620  }
621 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static ast_cond_t initialization
Definition: localtime.c:267
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
#define AST_PTHREADT_NULL
Definition: lock.h:65
ast_mutex_t lock
Definition: app_meetme.c:964
static pthread_t inotify_thread
Definition: localtime.c:266
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 2185 of file localtime.c.

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

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

2186 {
2187  const struct state *sp;
2188  if (!(sp = ast_tzset(zone)))
2189  return WRONG;
2190  return time1(tmp, localsub, 0L, sp);
2191 }
static struct ast_tm * localsub(const struct timeval *timep, const long offset, struct ast_tm *tmp, const struct state *sp)
Definition: localtime.c:1479
static struct state * ast_tzset(const char *zone)
Definition: localtime.c:1432
static struct timeval WRONG
Definition: localtime.c:113
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:2120
const char* ast_setlocale ( const char *  locale)

Set the thread-local representation of the current locale.

Definition at line 2248 of file localtime.c.

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

Referenced by ast_strftime_locale(), and ast_strptime_locale().

2249 {
2250  struct locale_entry *cur;
2251  locale_t prevlocale = LC_GLOBAL_LOCALE;
2252 
2253  if (locale == NULL) {
2254  return store_by_locale(uselocale(LC_GLOBAL_LOCALE));
2255  }
2256 
2258  if ((cur = find_by_name(locale))) {
2259  prevlocale = uselocale(cur->locale);
2260  }
2261 
2262  if (!cur) {
2263  if ((cur = ast_calloc(1, sizeof(*cur) + strlen(locale) + 1))) {
2264  cur->locale = newlocale(LC_ALL_MASK, locale, NULL);
2265  strcpy(cur->name, locale); /* SAFE */
2267  prevlocale = uselocale(cur->locale);
2268  }
2269  }
2271  return store_by_locale(prevlocale);
2272 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char name[0]
Definition: localtime.c:193
void * locale_t
Definition: localtime.h:32
static char locale[20]
struct locale_entry::@307 list
static struct locale_entry * find_by_name(const char *name)
Definition: localtime.c:2205
Definition: localtime.c:190
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
locale_t locale
Definition: localtime.c:192
#define ast_calloc(a, b)
Definition: astmm.h:82
static const char * store_by_locale(locale_t prevlocale)
Definition: localtime.c:2216
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.
localeText string specifying the locale to be used for language strings.
Return values
Aninteger value specifying the number of bytes placed into buf or -1 on error.

Definition at line 2351 of file localtime.c.

References ast_strftime_locale().

Referenced by __ast_verbose_ap(), acf_strftime(), action_corestatus(), append_date(), ast_cel_fabricate_channel_from_event(), ast_http_send(), ast_log(), ast_queue_log(), build_radius_record(), cdr_get_tv(), cli_prompt(), conf_run(), dump_datetime(), epoch_to_string(), exchangecal_get_events_between(), execute_cb(), find_conf_realtime(), format_date(), get_date(), get_ewscal_ids_for(), handle_cli_odbc_show(), handle_minivm_show_stats(), handle_show_settings(), isodate(), leave_voicemail(), make_email_file(), manager_log(), mstime(), odbc_log(), pgsql_log(), rt_extend_conf(), sendmail(), sendpage(), sip_show_registry(), static_callback(), timeout_write(), and write_metadata().

2352 {
2353  return ast_strftime_locale(buf, len, tmp, tm, NULL);
2354 }
int ast_strftime_locale(char *buf, size_t len, const char *format, const struct ast_tm *tm, const char *locale)
Definition: localtime.c:2280
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 *  format,
const struct ast_tm tm,
const char *  locale 
)

Definition at line 2280 of file localtime.c.

References ast_calloc, ast_free, ast_realloc, ast_setlocale(), format, and ast_tm::tm_usec.

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

2281 {
2282  size_t fmtlen = strlen(tmp) + 1;
2283  char *format = ast_calloc(1, fmtlen), *fptr = format, *newfmt;
2284  int decimals = -1, i, res;
2285  long fraction;
2286  const char *prevlocale;
2287 
2288  if (!format) {
2289  return -1;
2290  }
2291  for (; *tmp; tmp++) {
2292  if (*tmp == '%') {
2293  switch (tmp[1]) {
2294  case '1':
2295  case '2':
2296  case '3':
2297  case '4':
2298  case '5':
2299  case '6':
2300  if (tmp[2] != 'q') {
2301  goto defcase;
2302  }
2303  decimals = tmp[1] - '0';
2304  tmp++;
2305  /* Fall through */
2306  case 'q': /* Milliseconds */
2307  if (decimals == -1) {
2308  decimals = 3;
2309  }
2310 
2311  /* Juggle some memory to fit the item */
2312  newfmt = ast_realloc(format, fmtlen + decimals);
2313  if (!newfmt) {
2314  ast_free(format);
2315  return -1;
2316  }
2317  fptr = fptr - format + newfmt;
2318  format = newfmt;
2319  fmtlen += decimals;
2320 
2321  /* Reduce the fraction of time to the accuracy needed */
2322  for (i = 6, fraction = tm->tm_usec; i > decimals; i--) {
2323  fraction /= 10;
2324  }
2325  fptr += sprintf(fptr, "%0*ld", decimals, fraction);
2326 
2327  /* Reset, in case more than one 'q' specifier exists */
2328  decimals = -1;
2329  tmp++;
2330  break;
2331  default:
2332  goto defcase;
2333  }
2334  } else {
2335 defcase: *fptr++ = *tmp;
2336  }
2337  }
2338  *fptr = '\0';
2339 #undef strftime
2340  if (locale) {
2341  prevlocale = ast_setlocale(locale);
2342  }
2343  res = (int)strftime(buf, len, format, (struct tm *)tm);
2344  if (locale) {
2345  ast_setlocale(prevlocale);
2346  }
2347  ast_free(format);
2348  return res;
2349 }
int tm_usec
Definition: localtime.h:48
static char locale[20]
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:97
const char * ast_setlocale(const char *locale)
Set the thread-local representation of the current locale.
Definition: localtime.c:2248
#define ast_calloc(a, b)
Definition: astmm.h:82
#define ast_realloc(a, b)
Definition: astmm.h:103
static snd_pcm_format_t format
Definition: chan_alsa.c:93
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.
localeText string specifying the locale to be used for language strings.
Return values
Apointer to the first character within s not used to parse the date and time.

Definition at line 2377 of file localtime.c.

References ast_strptime_locale().

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

2378 {
2379  return ast_strptime_locale(s, format, tm, NULL);
2380 }
char * ast_strptime_locale(const char *s, const char *format, struct ast_tm *tm, const char *locale)
Definition: localtime.c:2356
static snd_pcm_format_t format
Definition: chan_alsa.c:93
char* ast_strptime_locale ( const char *  s,
const char *  format,
struct ast_tm tm,
const char *  locale 
)

Definition at line 2356 of file localtime.c.

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

Referenced by ast_strptime().

2357 {
2358  struct tm tm2 = { 0, };
2359  char *res;
2360  const char *prevlocale;
2361 
2362  prevlocale = ast_setlocale(locale);
2363  res = strptime(s, format, &tm2);
2364  ast_setlocale(prevlocale);
2365  /* ast_time and tm are not the same size - tm is a subset of
2366  * ast_time. Hence, the size of tm needs to be used for the
2367  * memcpy
2368  */
2369  memcpy(tm, &tm2, sizeof(tm2));
2370  tm->tm_usec = 0;
2371  /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
2372  * to deal with it correctly, we set it to -1. */
2373  tm->tm_isdst = -1;
2374  return res;
2375 }
int tm_usec
Definition: localtime.h:48
static char locale[20]
const char * ast_setlocale(const char *locale)
Set the thread-local representation of the current locale.
Definition: localtime.c:2248
int tm_isdst
Definition: localtime.h:44
static snd_pcm_format_t format
Definition: chan_alsa.c:93