Thu Oct 11 06:49:17 2012

Asterisk developer's documentation


localtime.h File Reference

Custom localtime functions for multiple timezones. More...

This graph shows which files directly or indirectly include this file:

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).
struct timeval ast_mktime (struct ast_tm *const tmp, const char *zone)
 Timezone-independent version of mktime(3).
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.
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.


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

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

Referenced by set_timezone_variables().

01322 {
01323    int i;   
01324    int transition1 = -1;
01325    int transition2 = -1;
01326    time_t      seconds;
01327    int  bounds_exceeded = 0;
01328    time_t  t = *timep;
01329    const struct state *sp;
01330    
01331    if (NULL == dst_enabled)
01332       return;
01333    *dst_enabled = 0;
01334 
01335    if (NULL == dst_start || NULL == dst_end || NULL == gmt_off)
01336       return;
01337 
01338    *gmt_off = 0; 
01339    
01340    sp = ast_tzset(zone);
01341    if (NULL == sp) 
01342       return;
01343    
01344    /* If the desired time exceeds the bounds of the defined time transitions  
01345    * then give give up on determining DST info and simply look for gmt offset 
01346    * This requires that I adjust the given time using increments of Gregorian 
01347    * repeats to place the time within the defined time transitions in the 
01348    * timezone structure.  
01349    */
01350    if ((sp->goback && t < sp->ats[0]) ||
01351          (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
01352       time_t      tcycles;
01353       int_fast64_t   icycles;
01354 
01355       if (t < sp->ats[0])
01356          seconds = sp->ats[0] - t;
01357       else  seconds = t - sp->ats[sp->timecnt - 1];
01358       --seconds;
01359       tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
01360       ++tcycles;
01361       icycles = tcycles;
01362       if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
01363          return;
01364       seconds = icycles;
01365       seconds *= YEARSPERREPEAT;
01366       seconds *= AVGSECSPERYEAR;
01367       if (t < sp->ats[0])
01368          t += seconds;
01369       else
01370          t -= seconds;
01371       
01372       if (t < sp->ats[0] || t > sp->ats[sp->timecnt - 1])
01373          return;  /* "cannot happen" */
01374 
01375       bounds_exceeded = 1;
01376    }
01377 
01378    if (sp->timecnt == 0 || t < sp->ats[0]) {
01379       /* I have no transition times or I'm before time */
01380       *dst_enabled = 0;
01381       /* Find where I can get gmtoff */
01382       i = 0;
01383       while (sp->ttis[i].tt_isdst)
01384          if (++i >= sp->typecnt) {
01385          i = 0;
01386          break;
01387          }
01388          *gmt_off = sp->ttis[i].tt_gmtoff;
01389          return;
01390    } 
01391 
01392    for (i = 1; i < sp->timecnt; ++i) {
01393       if (t < sp->ats[i]) {
01394          transition1 = sp->types[i - 1];
01395          transition2 = sp->types[i];
01396          break;
01397       } 
01398    }
01399    /* if I found transition times that do not bounded the given time and these correspond to 
01400       or the bounding zones do not reflect a changes in day light savings, then I do not have dst active */
01401    if (i >= sp->timecnt || 0 > transition1 || 0 > transition2 ||
01402          (sp->ttis[transition1].tt_isdst == sp->ttis[transition2].tt_isdst)) {
01403       *dst_enabled = 0;
01404       *gmt_off     = sp->ttis[sp->types[sp->timecnt -1]].tt_gmtoff;
01405    } else {
01406       /* I have valid daylight savings information. */
01407       if(sp->ttis[transition2].tt_isdst) 
01408          *gmt_off = sp->ttis[transition1].tt_gmtoff;
01409       else 
01410          *gmt_off = sp->ttis[transition2].tt_gmtoff;
01411 
01412       /* If I adjusted the time earlier, indicate that the dst is invalid */
01413       if (!bounds_exceeded) {
01414          *dst_enabled = 1;
01415          /* Determine which of the bounds is the start of daylight savings and which is the end */
01416          if(sp->ttis[transition2].tt_isdst) {
01417             *dst_start = sp->ats[i];
01418             *dst_end = sp->ats[i -1];
01419          } else {
01420             *dst_start = sp->ats[i -1];
01421             *dst_end = sp->ats[i];
01422          }
01423       }
01424    }  
01425    return;
01426 }

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

References ast_tzset(), and localsub().

Referenced by __ast_verbose_ap(), acf_strftime(), action_corestatus(), append_date(), ast_check_timing(), ast_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_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(), execute_cb(), find_conf_realtime(), format_date(), get_date(), handle_minivm_show_stats(), handle_show_settings(), handle_time_date_req_message(), httpd_helper_thread(), iax2_datetime(), isodate(), leave_voicemail(), main(), make_email_file(), manager_log(), odbc_log(), packdate(), pgsql_log(), phone_call(), phoneprov_callback(), 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_notify_request_with_callerid(), vmu_tm(), write_history(), and write_metadata().

01307 {
01308    const struct state *sp = ast_tzset(zone);
01309    memset(tmp, 0, sizeof(*tmp));
01310    return sp ? localsub(timep, 0L, tmp, sp) : NULL;
01311 }

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

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

Referenced by acf_strptime(), conf_run(), find_conf_realtime(), rt_extend_conf(), sms_handleincoming_proto2(), sms_readfile(), and unpackdate().

01922 {
01923    const struct state *sp;
01924    if (!(sp = ast_tzset(zone)))
01925       return WRONG;
01926    return time1(tmp, localsub, 0L, sp);
01927 }

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.
Return values:
An integer value specifying the number of bytes placed into buf or -1 on error.

Definition at line 1929 of file localtime.c.

References ast_calloc, ast_free, ast_realloc, format, and ast_tm::tm_usec.

Referenced by __ast_verbose_ap(), acf_strftime(), action_corestatus(), append_date(), ast_log(), build_radius_record(), cdr_get_tv(), cli_prompt(), conf_run(), dump_datetime(), execute_cb(), find_conf_realtime(), format_date(), get_date(), handle_minivm_show_stats(), handle_show_settings(), httpd_helper_thread(), isodate(), leave_voicemail(), make_email_file(), manager_log(), odbc_log(), pgsql_log(), phoneprov_callback(), prep_email_sub_vars(), rt_extend_conf(), sendmail(), sendpage(), sip_show_registry(), static_callback(), timeout_write(), and write_metadata().

01930 {
01931    size_t fmtlen = strlen(tmp) + 1;
01932    char *format = ast_calloc(1, fmtlen), *fptr = format, *newfmt;
01933    int decimals = -1, i, res;
01934    long fraction;
01935 
01936    if (!format)
01937       return -1;
01938    for (; *tmp; tmp++) {
01939       if (*tmp == '%') {
01940          switch (tmp[1]) {
01941          case '1':
01942          case '2':
01943          case '3':
01944          case '4':
01945          case '5':
01946          case '6':
01947             if (tmp[2] != 'q')
01948                goto defcase;
01949             decimals = tmp[1] - '0';
01950             tmp++;
01951             /* Fall through */
01952          case 'q': /* Milliseconds */
01953             if (decimals == -1)
01954                decimals = 3;
01955 
01956             /* Juggle some memory to fit the item */
01957             newfmt = ast_realloc(format, fmtlen + decimals);
01958             if (!newfmt) {
01959                ast_free(format);
01960                return -1;
01961             }
01962             fptr = fptr - format + newfmt;
01963             format = newfmt;
01964             fmtlen += decimals;
01965 
01966             /* Reduce the fraction of time to the accuracy needed */
01967             for (i = 6, fraction = tm->tm_usec; i > decimals; i--)
01968                fraction /= 10;
01969             fptr += sprintf(fptr, "%0*ld", decimals, fraction);
01970 
01971             /* Reset, in case more than one 'q' specifier exists */
01972             decimals = -1;
01973             tmp++;
01974             break;
01975          default:
01976             goto defcase;
01977          }
01978       } else
01979 defcase: *fptr++ = *tmp;
01980    }
01981    *fptr = '\0';
01982 #undef strftime
01983    res = (int)strftime(buf, len, format, (struct tm *)tm);
01984    ast_free(format);
01985    return res;
01986 }

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.
Return values:
A pointer to the first character within s not used to parse the date and time.

Definition at line 1988 of file localtime.c.

References ast_tm::tm_isdst, and ast_tm::tm_usec.

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

01989 {
01990    struct tm tm2 = { 0, };
01991    char *res = strptime(s, format, &tm2);
01992    memcpy(tm, &tm2, sizeof(*tm));
01993    tm->tm_usec = 0;
01994    /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
01995     * to deal with it correctly, we set it to -1. */
01996    tm->tm_isdst = -1;
01997    return res;
01998 }


Generated on Thu Oct 11 06:49:17 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6