Thu Sep 7 01:03:31 2017

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

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.


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.

Referenced by set_timezone_variables().

01586 {
01587    int i;   
01588    int transition1 = -1;
01589    int transition2 = -1;
01590    time_t      seconds;
01591    int  bounds_exceeded = 0;
01592    time_t  t = *timep;
01593    const struct state *sp;
01594    
01595    if (NULL == dst_enabled)
01596       return;
01597    *dst_enabled = 0;
01598 
01599    if (NULL == dst_start || NULL == dst_end || NULL == gmt_off)
01600       return;
01601 
01602    *gmt_off = 0; 
01603    
01604    sp = ast_tzset(zone);
01605    if (NULL == sp) 
01606       return;
01607    
01608    /* If the desired time exceeds the bounds of the defined time transitions  
01609    * then give give up on determining DST info and simply look for gmt offset 
01610    * This requires that I adjust the given time using increments of Gregorian 
01611    * repeats to place the time within the defined time transitions in the 
01612    * timezone structure.  
01613    */
01614    if ((sp->goback && t < sp->ats[0]) ||
01615          (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
01616       time_t      tcycles;
01617       int_fast64_t   icycles;
01618 
01619       if (t < sp->ats[0])
01620          seconds = sp->ats[0] - t;
01621       else  seconds = t - sp->ats[sp->timecnt - 1];
01622       --seconds;
01623       tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
01624       ++tcycles;
01625       icycles = tcycles;
01626       if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
01627          return;
01628       seconds = icycles;
01629       seconds *= YEARSPERREPEAT;
01630       seconds *= AVGSECSPERYEAR;
01631       if (t < sp->ats[0])
01632          t += seconds;
01633       else
01634          t -= seconds;
01635       
01636       if (t < sp->ats[0] || t > sp->ats[sp->timecnt - 1])
01637          return;  /* "cannot happen" */
01638 
01639       bounds_exceeded = 1;
01640    }
01641 
01642    if (sp->timecnt == 0 || t < sp->ats[0]) {
01643       /* I have no transition times or I'm before time */
01644       *dst_enabled = 0;
01645       /* Find where I can get gmtoff */
01646       i = 0;
01647       while (sp->ttis[i].tt_isdst)
01648          if (++i >= sp->typecnt) {
01649          i = 0;
01650          break;
01651          }
01652          *gmt_off = sp->ttis[i].tt_gmtoff;
01653          return;
01654    } 
01655 
01656    for (i = 1; i < sp->timecnt; ++i) {
01657       if (t < sp->ats[i]) {
01658          transition1 = sp->types[i - 1];
01659          transition2 = sp->types[i];
01660          break;
01661       } 
01662    }
01663    /* if I found transition times that do not bounded the given time and these correspond to 
01664       or the bounding zones do not reflect a changes in day light savings, then I do not have dst active */
01665    if (i >= sp->timecnt || 0 > transition1 || 0 > transition2 ||
01666          (sp->ttis[transition1].tt_isdst == sp->ttis[transition2].tt_isdst)) {
01667       *dst_enabled = 0;
01668       *gmt_off     = sp->ttis[sp->types[sp->timecnt -1]].tt_gmtoff;
01669    } else {
01670       /* I have valid daylight savings information. */
01671       if(sp->ttis[transition2].tt_isdst) 
01672          *gmt_off = sp->ttis[transition1].tt_gmtoff;
01673       else 
01674          *gmt_off = sp->ttis[transition2].tt_gmtoff;
01675 
01676       /* If I adjusted the time earlier, indicate that the dst is invalid */
01677       if (!bounds_exceeded) {
01678          *dst_enabled = 1;
01679          /* Determine which of the bounds is the start of daylight savings and which is the end */
01680          if(sp->ttis[transition2].tt_isdst) {
01681             *dst_start = sp->ats[i];
01682             *dst_end = sp->ats[i -1];
01683          } else {
01684             *dst_start = sp->ats[i -1];
01685             *dst_end = sp->ats[i];
01686          }
01687       }
01688    }  
01689    return;
01690 }

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:
timep Current time, including microseconds
p_tm Pointer to memory where the broken-out time will be stored
zone Text string of a standard system zoneinfo file. If NULL, the system localtime will be used.
Return values:
p_tm is 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_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(), 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().

01571 {
01572    const struct state *sp = ast_tzset(zone);
01573    memset(tmp, 0, sizeof(*tmp));
01574    return sp ? localsub(timep, 0L, tmp, sp) : NULL;
01575 }

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.

00608 {
00609    if (inotify_thread != AST_PTHREADT_NULL) {
00610       AST_LIST_LOCK(&zonelist);
00611 #ifdef TEST_FRAMEWORK
00612       test = info;
00613 #endif
00614       pthread_kill(inotify_thread, SIGURG);
00615       ast_cond_wait(&initialization, &(&zonelist)->lock);
00616 #ifdef TEST_FRAMEWORK
00617       test = NULL;
00618 #endif
00619       AST_LIST_UNLOCK(&zonelist);
00620    }
00621 }

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

Timezone-independent version of mktime(3).

Parameters:
tmp Current broken-out time, including microseconds
zone Text string of a standard system zoneinfo file. If NULL, the system localtime will be used.
Return values:
A structure 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().

02186 {
02187    const struct state *sp;
02188    if (!(sp = ast_tzset(zone)))
02189       return WRONG;
02190    return time1(tmp, localsub, 0L, sp);
02191 }

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

02249 {
02250    struct locale_entry *cur;
02251    locale_t prevlocale = LC_GLOBAL_LOCALE;
02252 
02253    if (locale == NULL) {
02254       return store_by_locale(uselocale(LC_GLOBAL_LOCALE));
02255    }
02256 
02257    AST_LIST_LOCK(&localelist);
02258    if ((cur = find_by_name(locale))) {
02259       prevlocale = uselocale(cur->locale);
02260    }
02261 
02262    if (!cur) {
02263       if ((cur = ast_calloc(1, sizeof(*cur) + strlen(locale) + 1))) {
02264          cur->locale = newlocale(LC_ALL_MASK, locale, NULL);
02265          strcpy(cur->name, locale); /* SAFE */
02266          AST_LIST_INSERT_TAIL(&localelist, cur, list);
02267          prevlocale = uselocale(cur->locale);
02268       }
02269    }
02270    AST_LIST_UNLOCK(&localelist);
02271    return store_by_locale(prevlocale);
02272 }

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:
buf Address in memory where the resulting string will be stored.
len Size of the chunk of memory buf.
format A string specifying the format of time to be placed into buf.
tm Pointer to the broken out time to be used for the format.
locale Text string specifying the locale to be used for language strings.
Return values:
An integer 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().

02352 {
02353    return ast_strftime_locale(buf, len, tmp, tm, NULL);
02354 }

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

02281 {
02282    size_t fmtlen = strlen(tmp) + 1;
02283    char *format = ast_calloc(1, fmtlen), *fptr = format, *newfmt;
02284    int decimals = -1, i, res;
02285    long fraction;
02286    const char *prevlocale;
02287 
02288    if (!format) {
02289       return -1;
02290    }
02291    for (; *tmp; tmp++) {
02292       if (*tmp == '%') {
02293          switch (tmp[1]) {
02294          case '1':
02295          case '2':
02296          case '3':
02297          case '4':
02298          case '5':
02299          case '6':
02300             if (tmp[2] != 'q') {
02301                goto defcase;
02302             }
02303             decimals = tmp[1] - '0';
02304             tmp++;
02305             /* Fall through */
02306          case 'q': /* Milliseconds */
02307             if (decimals == -1) {
02308                decimals = 3;
02309             }
02310 
02311             /* Juggle some memory to fit the item */
02312             newfmt = ast_realloc(format, fmtlen + decimals);
02313             if (!newfmt) {
02314                ast_free(format);
02315                return -1;
02316             }
02317             fptr = fptr - format + newfmt;
02318             format = newfmt;
02319             fmtlen += decimals;
02320 
02321             /* Reduce the fraction of time to the accuracy needed */
02322             for (i = 6, fraction = tm->tm_usec; i > decimals; i--) {
02323                fraction /= 10;
02324             }
02325             fptr += sprintf(fptr, "%0*ld", decimals, fraction);
02326 
02327             /* Reset, in case more than one 'q' specifier exists */
02328             decimals = -1;
02329             tmp++;
02330             break;
02331          default:
02332             goto defcase;
02333          }
02334       } else {
02335 defcase: *fptr++ = *tmp;
02336       }
02337    }
02338    *fptr = '\0';
02339 #undef strftime
02340    if (locale) {
02341       prevlocale = ast_setlocale(locale);
02342    }
02343    res = (int)strftime(buf, len, format, (struct tm *)tm);
02344    if (locale) {
02345       ast_setlocale(prevlocale);
02346    }
02347    ast_free(format);
02348    return res;
02349 }

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:
s A string specifying some portion of a date and time.
format The format in which the string, s, is expected.
tm The broken-out time structure into which the parsed data is expected.
locale Text string specifying the locale to be used for language strings.
Return values:
A pointer 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().

02378 {
02379    return ast_strptime_locale(s, format, tm, NULL);
02380 }

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

02357 {
02358    struct tm tm2 = { 0, };
02359    char *res;
02360    const char *prevlocale;
02361 
02362    prevlocale = ast_setlocale(locale);
02363    res = strptime(s, format, &tm2);
02364    ast_setlocale(prevlocale);
02365    /* ast_time and tm are not the same size - tm is a subset of
02366     * ast_time.  Hence, the size of tm needs to be used for the
02367     * memcpy
02368     */
02369    memcpy(tm, &tm2, sizeof(tm2));
02370    tm->tm_usec = 0;
02371    /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
02372     * to deal with it correctly, we set it to -1. */
02373    tm->tm_isdst = -1;
02374    return res;
02375 }


Generated on 7 Sep 2017 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1