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

Custom localtime functions for multiple timezones. More...

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(), 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_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(), rt_extend_conf(), say_date_generic(), send_date_time(), send_date_time2(), send_date_time3(), sendmail(), set_header(), set_timezone_variables(), sip_show_registry(), sms_compose2(), sms_handleincoming_proto2(), static_callback(), transmit_definetimedate(), transmit_notify_request_with_callerid(), 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);
806  ast_cond_timedwait(&initialization, &(&zonelist)->lock, &wait_time);
807 #ifdef TEST_FRAMEWORK
808  test = NULL;
809 #endif
811  }
812 }
ast_mutex_t lock
Definition: app_meetme.c:1093
#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:204
def info(msg)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150

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 2091 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 result, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_usec, and ast_tm::tm_year.

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

◆ 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:204
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
static const char * store_by_locale(locale_t prevlocale)
Definition: localtime.c:2388
static struct locale_entry * find_by_name(const char *name)
Definition: localtime.c:2377
void * locale_t
Definition: localtime.h:32
Definition: localtime.c:242
locale_t locale
Definition: localtime.c:244
struct locale_entry::@403 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(), and ast_strptime_locale().

◆ 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(), 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_minivm_show_stats(), handle_show_settings(), http_callback(), isodate(), leave_voicemail(), make_email_file(), make_logchannel(), manager_log(), mstime(), odbc_log(), pgsql_log(), rt_extend_conf(), sendmail(), sendpage(), set_header(), sip_show_registry(), static_callback(), 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 {
2508 defcase: *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:182
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:228
static snd_pcm_format_t format
Definition: chan_alsa.c:106
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, format, 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(), format, and NULL.

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

◆ 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(), format, locale, ast_tm::tm_isdst, and ast_tm::tm_usec.

Referenced by ast_strptime().