Wed Apr 6 11:30:05 2011

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

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

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 1547 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(), rpt_localtime(), 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().

01548 {
01549    const struct state *sp = ast_tzset(zone);
01550    memset(tmp, 0, sizeof(*tmp));
01551    return sp ? localsub(timep, 0L, tmp, sp) : NULL;
01552 }

void ast_localtime_wakeup_monitor ( struct ast_test *  info  ) 

Definition at line 602 of file localtime.c.

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

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

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

02163 {
02164    const struct state *sp;
02165    if (!(sp = ast_tzset(zone)))
02166       return WRONG;
02167    return time1(tmp, localsub, 0L, sp);
02168 }

const char* ast_setlocale ( const char *  locale  ) 

Set the thread-local representation of the current locale.

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

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

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 2328 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(), manager_log(), mstime(), odbc_log(), pgsql_log(), rt_extend_conf(), sendmail(), sip_show_registry(), static_callback(), timeout_write(), and write_metadata().

02329 {
02330    return ast_strftime_locale(buf, len, tmp, tm, NULL);
02331 }

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

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

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

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

References ast_strptime_locale().

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

02351 {
02352    return ast_strptime_locale(s, format, tm, NULL);
02353 }

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

Definition at line 2333 of file localtime.c.

References ast_setlocale().

Referenced by ast_strptime().

02334 {
02335    struct tm tm2 = { 0, };
02336    char *res;
02337    const char *prevlocale;
02338 
02339    prevlocale = ast_setlocale(locale);
02340    res = strptime(s, format, &tm2);
02341    ast_setlocale(prevlocale);
02342    memcpy(tm, &tm2, sizeof(*tm));
02343    tm->tm_usec = 0;
02344    /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
02345     * to deal with it correctly, we set it to -1. */
02346    tm->tm_isdst = -1;
02347    return res;
02348 }


Generated on Wed Apr 6 11:30:05 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7