Sat Apr 26 2014 22:02:54

Asterisk developer's documentation


localtime.h File Reference

Custom localtime functions for multiple timezones. More...

#include <locale.h>
Include dependency graph for localtime.h:
This graph shows which files directly or indirectly include this file:

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).
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).
const char * ast_setlocale (const char *locale)
 Set the thread-local representation of the current locale.
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.
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.
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 1604 of file localtime.c.

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

Referenced by set_timezone_variables().

{
   int i;
   int transition1 = -1;
   int transition2 = -1;
   time_t      seconds;
   int  bounds_exceeded = 0;
   time_t  t = *timep;
   const struct state *sp;

   if (NULL == dst_enabled)
      return;
   *dst_enabled = 0;

   if (NULL == dst_start || NULL == dst_end || NULL == gmt_off)
      return;

   *gmt_off = 0;

   sp = ast_tzset(zone);
   if (NULL == sp)
      return;

   /* If the desired time exceeds the bounds of the defined time transitions
   * then give give up on determining DST info and simply look for gmt offset
   * This requires that I adjust the given time using increments of Gregorian
   * repeats to place the time within the defined time transitions in the
   * timezone structure.
   */
   if ((sp->goback && t < sp->ats[0]) ||
         (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
      time_t      tcycles;
      int_fast64_t   icycles;

      if (t < sp->ats[0])
         seconds = sp->ats[0] - t;
      else  seconds = t - sp->ats[sp->timecnt - 1];
      --seconds;
      tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
      ++tcycles;
      icycles = tcycles;
      if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
         return;
      seconds = icycles;
      seconds *= YEARSPERREPEAT;
      seconds *= AVGSECSPERYEAR;
      if (t < sp->ats[0])
         t += seconds;
      else
         t -= seconds;

      if (t < sp->ats[0] || t > sp->ats[sp->timecnt - 1])
         return;  /* "cannot happen" */

      bounds_exceeded = 1;
   }

   if (sp->timecnt == 0 || t < sp->ats[0]) {
      /* I have no transition times or I'm before time */
      *dst_enabled = 0;
      /* Find where I can get gmtoff */
      i = 0;
      while (sp->ttis[i].tt_isdst)
         if (++i >= sp->typecnt) {
         i = 0;
         break;
         }
         *gmt_off = sp->ttis[i].tt_gmtoff;
         return;
   }

   for (i = 1; i < sp->timecnt; ++i) {
      if (t < sp->ats[i]) {
         transition1 = sp->types[i - 1];
         transition2 = sp->types[i];
         break;
      }
   }
   /* if I found transition times that do not bounded the given time and these correspond to
      or the bounding zones do not reflect a changes in day light savings, then I do not have dst active */
   if (i >= sp->timecnt || 0 > transition1 || 0 > transition2 ||
         (sp->ttis[transition1].tt_isdst == sp->ttis[transition2].tt_isdst)) {
      *dst_enabled = 0;
      *gmt_off = sp->ttis[sp->types[sp->timecnt -1]].tt_gmtoff;
   } else {
      /* I have valid daylight savings information. */
      if(sp->ttis[transition2].tt_isdst)
         *gmt_off = sp->ttis[transition1].tt_gmtoff;
      else
         *gmt_off = sp->ttis[transition2].tt_gmtoff;

      /* If I adjusted the time earlier, indicate that the dst is invalid */
      if (!bounds_exceeded) {
         *dst_enabled = 1;
         /* Determine which of the bounds is the start of daylight savings and which is the end */
         if(sp->ttis[transition2].tt_isdst) {
            *dst_start = sp->ats[i];
            *dst_end = sp->ats[i -1];
         } else {
            *dst_start = sp->ats[i -1];
            *dst_end = sp->ats[i];
         }
      }
   }
   return;
}
struct ast_tm* ast_localtime ( const struct timeval *  timep,
struct ast_tm p_tm,
const char *  zone 
) [read]

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 1589 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_full(), 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_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_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(), make_logchannel(), 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(), set_timezone_variables(), 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().

{
   const struct state *sp = ast_tzset(zone);
   memset(tmp, 0, sizeof(*tmp));
   return sp ? localsub(timep, 0L, tmp, sp) : NULL;
}
void ast_localtime_wakeup_monitor ( struct ast_test *  info)

Definition at line 626 of file localtime.c.

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

{
   if (inotify_thread != AST_PTHREADT_NULL) {
      AST_LIST_LOCK(&zonelist);
#ifdef TEST_FRAMEWORK
      test = info;
#endif
      pthread_kill(inotify_thread, SIGURG);
      ast_cond_wait(&initialization, &(&zonelist)->lock);
#ifdef TEST_FRAMEWORK
      test = NULL;
#endif
      AST_LIST_UNLOCK(&zonelist);
   }
}
struct timeval ast_mktime ( struct ast_tm *const  tmp,
const char *  zone 
) [read]

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 2204 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().

{
   const struct state *sp;
   if (!(sp = ast_tzset(zone)))
      return WRONG;
   return time1(tmp, localsub, 0L, sp);
}
const char* ast_setlocale ( const char *  locale)

Set the thread-local representation of the current locale.

Definition at line 2267 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().

{
   struct locale_entry *cur;
   locale_t prevlocale = LC_GLOBAL_LOCALE;

   if (locale == NULL) {
      return store_by_locale(uselocale(LC_GLOBAL_LOCALE));
   }

   AST_LIST_LOCK(&localelist);
   if ((cur = find_by_name(locale))) {
      prevlocale = uselocale(cur->locale);
   }

   if (!cur) {
      if ((cur = ast_calloc(1, sizeof(*cur) + strlen(locale) + 1))) {
         cur->locale = newlocale(LC_ALL_MASK, locale, NULL);
         strcpy(cur->name, locale); /* SAFE */
         AST_LIST_INSERT_TAIL(&localelist, cur, list);
         prevlocale = uselocale(cur->locale);
      }
   }
   AST_LIST_UNLOCK(&localelist);
   return store_by_locale(prevlocale);
}
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 2370 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_full(), 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(), make_logchannel(), manager_log(), mstime(), odbc_log(), pgsql_log(), rt_extend_conf(), sendmail(), sendpage(), sip_show_registry(), static_callback(), timeout_write(), and write_metadata().

{
   return ast_strftime_locale(buf, len, tmp, tm, NULL);
}
int ast_strftime_locale ( char *  buf,
size_t  len,
const char *  format,
const struct ast_tm tm,
const char *  locale 
)

Definition at line 2299 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().

{
   size_t fmtlen = strlen(tmp) + 1;
   char *format = ast_calloc(1, fmtlen), *fptr = format, *newfmt;
   int decimals = -1, i, res;
   long fraction;
   const char *prevlocale;

   if (!format) {
      return -1;
   }
   for (; *tmp; tmp++) {
      if (*tmp == '%') {
         switch (tmp[1]) {
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
            if (tmp[2] != 'q') {
               goto defcase;
            }
            decimals = tmp[1] - '0';
            tmp++;
            /* Fall through */
         case 'q': /* Milliseconds */
            if (decimals == -1) {
               decimals = 3;
            }

            /* Juggle some memory to fit the item */
            newfmt = ast_realloc(format, fmtlen + decimals);
            if (!newfmt) {
               ast_free(format);
               return -1;
            }
            fptr = fptr - format + newfmt;
            format = newfmt;
            fmtlen += decimals;

            /* Reduce the fraction of time to the accuracy needed */
            for (i = 6, fraction = tm->tm_usec; i > decimals; i--) {
               fraction /= 10;
            }
            fptr += sprintf(fptr, "%0*ld", decimals, fraction);

            /* Reset, in case more than one 'q' specifier exists */
            decimals = -1;
            tmp++;
            break;
         default:
            goto defcase;
         }
      } else {
defcase: *fptr++ = *tmp;
      }
   }
   *fptr = '\0';
#undef strftime
   if (locale) {
      prevlocale = ast_setlocale(locale);
   }
   res = (int)strftime(buf, len, format, (struct tm *)tm);
   if (locale) {
      ast_setlocale(prevlocale);
   }
   ast_free(format);
   return res;
}
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 2396 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().

{
   return ast_strptime_locale(s, format, tm, NULL);
}
char* ast_strptime_locale ( const char *  s,
const char *  format,
struct ast_tm tm,
const char *  locale 
)

Definition at line 2375 of file localtime.c.

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

Referenced by ast_strptime().

{
   struct tm tm2 = { 0, };
   char *res;
   const char *prevlocale;

   prevlocale = ast_setlocale(locale);
   res = strptime(s, format, &tm2);
   ast_setlocale(prevlocale);
   /* ast_time and tm are not the same size - tm is a subset of
    * ast_time.  Hence, the size of tm needs to be used for the
    * memcpy
    */
   memcpy(tm, &tm2, sizeof(tm2));
   tm->tm_usec = 0;
   /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
    * to deal with it correctly, we set it to -1. */
   tm->tm_isdst = -1;
   return res;
}