#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_tm * | ast_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) |
Definition in file localtime.h.
typedef void* locale_t |
Definition at line 32 of file localtime.h.
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).
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. |
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).
tmp | Current broken-out time, including microseconds | |
zone | Text string of a standard system zoneinfo file. If NULL, the system localtime will be used. |
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.
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. |
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.
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. |
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 }