Mon Oct 8 12:39:24 2012

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

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

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

01552 {
01553    const struct state *sp = ast_tzset(zone);
01554    memset(tmp, 0, sizeof(*tmp));
01555    return sp ? localsub(timep, 0L, tmp, sp) : NULL;
01556 }

void ast_localtime_wakeup_monitor ( struct ast_test *  info  ) 

Definition at line 606 of file localtime.c.

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

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

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

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

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

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

02167 {
02168    const struct state *sp;
02169    if (!(sp = ast_tzset(zone)))
02170       return WRONG;
02171    return time1(tmp, localsub, 0L, sp);
02172 }

const char* ast_setlocale ( const char *  locale  ) 

Set the thread-local representation of the current locale.

Definition at line 2229 of file localtime.c.

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

Referenced by ast_strftime_locale(), and ast_strptime_locale().

02230 {
02231    struct locale_entry *cur;
02232    locale_t prevlocale = LC_GLOBAL_LOCALE;
02233 
02234    if (locale == NULL) {
02235       return store_by_locale(uselocale(LC_GLOBAL_LOCALE));
02236    }
02237 
02238    AST_LIST_LOCK(&localelist);
02239    if ((cur = find_by_name(locale))) {
02240       prevlocale = uselocale(cur->locale);
02241    }
02242 
02243    if (!cur) {
02244       if ((cur = ast_calloc(1, sizeof(*cur) + strlen(locale) + 1))) {
02245          cur->locale = newlocale(LC_ALL_MASK, locale, NULL);
02246          strcpy(cur->name, locale); /* SAFE */
02247          AST_LIST_INSERT_TAIL(&localelist, cur, list);
02248          prevlocale = uselocale(cur->locale);
02249       }
02250    }
02251    AST_LIST_UNLOCK(&localelist);
02252    return store_by_locale(prevlocale);
02253 }

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

02333 {
02334    return ast_strftime_locale(buf, len, tmp, tm, NULL);
02335 }

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

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

02262 {
02263    size_t fmtlen = strlen(tmp) + 1;
02264    char *format = ast_calloc(1, fmtlen), *fptr = format, *newfmt;
02265    int decimals = -1, i, res;
02266    long fraction;
02267    const char *prevlocale;
02268 
02269    if (!format) {
02270       return -1;
02271    }
02272    for (; *tmp; tmp++) {
02273       if (*tmp == '%') {
02274          switch (tmp[1]) {
02275          case '1':
02276          case '2':
02277          case '3':
02278          case '4':
02279          case '5':
02280          case '6':
02281             if (tmp[2] != 'q') {
02282                goto defcase;
02283             }
02284             decimals = tmp[1] - '0';
02285             tmp++;
02286             /* Fall through */
02287          case 'q': /* Milliseconds */
02288             if (decimals == -1) {
02289                decimals = 3;
02290             }
02291 
02292             /* Juggle some memory to fit the item */
02293             newfmt = ast_realloc(format, fmtlen + decimals);
02294             if (!newfmt) {
02295                ast_free(format);
02296                return -1;
02297             }
02298             fptr = fptr - format + newfmt;
02299             format = newfmt;
02300             fmtlen += decimals;
02301 
02302             /* Reduce the fraction of time to the accuracy needed */
02303             for (i = 6, fraction = tm->tm_usec; i > decimals; i--) {
02304                fraction /= 10;
02305             }
02306             fptr += sprintf(fptr, "%0*ld", decimals, fraction);
02307 
02308             /* Reset, in case more than one 'q' specifier exists */
02309             decimals = -1;
02310             tmp++;
02311             break;
02312          default:
02313             goto defcase;
02314          }
02315       } else {
02316 defcase: *fptr++ = *tmp;
02317       }
02318    }
02319    *fptr = '\0';
02320 #undef strftime
02321    if (locale) {
02322       prevlocale = ast_setlocale(locale);
02323    }
02324    res = (int)strftime(buf, len, format, (struct tm *)tm);
02325    if (locale) {
02326       ast_setlocale(prevlocale);
02327    }
02328    ast_free(format);
02329    return res;
02330 }

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

References ast_strptime_locale().

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

02359 {
02360    return ast_strptime_locale(s, format, tm, NULL);
02361 }

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

Definition at line 2337 of file localtime.c.

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

Referenced by ast_strptime().

02338 {
02339    struct tm tm2 = { 0, };
02340    char *res;
02341    const char *prevlocale;
02342 
02343    prevlocale = ast_setlocale(locale);
02344    res = strptime(s, format, &tm2);
02345    ast_setlocale(prevlocale);
02346    /* ast_time and tm are not the same size - tm is a subset of
02347     * ast_time.  Hence, the size of tm needs to be used for the
02348     * memcpy
02349     */
02350    memcpy(tm, &tm2, sizeof(tm2));
02351    tm->tm_usec = 0;
02352    /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
02353     * to deal with it correctly, we set it to -1. */
02354    tm->tm_isdst = -1;
02355    return res;
02356 }


Generated on Mon Oct 8 12:39:24 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7