#include "asterisk.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <float.h>#include "private.h"#include "tzfile.h"#include "asterisk/lock.h"#include "asterisk/localtime.h"#include "asterisk/strings.h"#include "asterisk/linkedlists.h"#include "asterisk/utils.h"Include dependency graph for localtime.c:

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

Go to the source code of this file.
Data Structures | |
| struct | lsinfo |
| leap second information More... | |
| struct | rule |
| struct | state |
Defines | |
| #define | BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) |
| #define | DAY_OF_YEAR 1 |
| #define | JULIAN_DAY 0 |
| #define | MONTH_NTH_DAY_OF_WEEK 2 |
| #define | MY_TZNAME_MAX 255 |
| #define | OPEN_MODE O_RDONLY |
| #define | TZ_ABBR_CHAR_SET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" |
| #define | TZ_ABBR_ERR_CHAR '_' |
| #define | TZ_ABBR_MAX_LEN 16 |
| #define | TZ_STRLEN_MAX 255 |
| #define | TZDEFRULESTRING ",M4.1.0,M10.5.0" |
| #define | WRONG (-1) |
Functions | |
| static char | __attribute__ ((unused)) |
| time type information | |
| static | AST_LIST_HEAD_STATIC (zonelist, state) |
| tm * | ast_localtime (const time_t *timep, struct tm *tmp, const char *zone) |
| time_t | ast_mktime (struct tm *tmp, const char *zone) |
| static struct state * | ast_tzset (const char *zone) |
| static long | detzcode (const char *const codep) |
| static time_t | detzcode64 (const char *const codep) |
| static int | differ_by_repeat (const time_t t1, const time_t t0) |
| static const char * | getnum (const char *strp, int *nump, const int min, const int max) |
| Given a pointer into a time zone string, extract a number from that string. Check that the number is within a specified range; if it is not, return NULL. Otherwise, return a pointer to the first character not part of the number. | |
| static const char * | getoffset (const char *strp, long *offsetp) |
| Given a pointer into a time zone string, extract an offset, in [+-]hh[:mm[:ss]] form, from the string. If any error occurs, return NULL. Otherwise, return a pointer to the first character not part of the time. | |
| static const char * | getqzname (const char *strp, const int delim) |
| Given a pointer into an extended time zone string, scan until the ending delimiter of the zone name is located. Return a pointer to the delimiter. | |
| static const char * | getrule (const char *strp, struct rule *rulep) |
| Given a pointer into a time zone string, extract a rule in the form date[/time]. See POSIX section 8 for the format of "date" and "time". If a valid rule is not found, return NULL. Otherwise, return a pointer to the first character not part of the rule. | |
| static const char * | getsecs (const char *strp, long *const secsp) |
| Given a pointer into a time zone string, extract a number of seconds, in hh[:mm[:ss]] form, from the string. If any error occurs, return NULL. Otherwise, return a pointer to the first character not part of the number of seconds. | |
| static const char * | getzname (const char *strp) |
| Given a pointer into a time zone string, scan until a character that is not a valid character in a zone name is found. Return a pointer to that character. | |
| static int | gmtload (struct state *sp) |
| static struct tm * | gmtsub (const time_t *timep, const long offset, struct tm *tmp) |
| static int | increment_overflow (int *number, int delta) |
| Simplified normalize logic courtesy Paul Eggert. | |
| static int | leaps_thru_end_of (const int y) |
| Return the number of leap years through the end of the given year where, to make the math easy, the answer for year zero is defined as zero. | |
| static struct tm * | localsub (const time_t *timep, const long offset, struct tm *tmp, const struct state *sp) |
| static int | long_increment_overflow (long *number, int delta) |
| static int | long_normalize_overflow (long *tensptr, int *unitsptr, const int base) |
| static int | normalize_overflow (int *tensptr, int *unitsptr, const int base) |
| static int tzparse | P ((const char *name, struct state *sp, int lastditch)) |
| static int tzload | P ((const char *name, struct state *sp, int doextend)) |
| static time_t transtime | P ((time_t janfirst, int year, const struct rule *rulep, long offset)) |
| static int tmcomp | P ((const struct tm *atmp, const struct tm *btmp)) |
| static struct tm *timesub | P ((const time_t *timep, long offset, const struct state *sp, struct tm *tmp)) |
| static time_t time2sub | P ((struct tm *tmp, struct tm *(*funcp)(const time_t *, long, struct tm *, const struct state *sp), long offset, int *okayp, int do_norm_secs, const struct state *sp)) |
| static time_t time2 | P ((struct tm *tmp, struct tm *(*funcp) P((const time_t *, long, struct tm *, const struct state *sp)), long offset, int *okayp, const struct state *sp)) |
| static time_t time1 | P ((struct tm *tmp, struct tm *(*funcp) P((const time_t *, long, struct tm *, const struct state *sp)), long offset, const struct state *sp)) |
| static int normalize_overflow | P ((int *tensptr, int *unitsptr, const int base)) |
| static int long_normalize_overflow | P ((long *tensptr, int *unitsptr, const int base)) |
| static int long_increment_overflow | P ((long *number, int delta)) |
| static int leaps_thru_end_of | P ((int y)) |
| static int increment_overflow | P ((int *number, int delta)) |
| static struct tm *localsub | P ((const time_t *timep, long offset, struct tm *tmp, const struct state *sp)) |
| static struct tm *gmtsub | P ((const time_t *timep, long offset, struct tm *tmp)) |
| static int gmtload | P ((struct state *sp)) |
| static const char *getrule | P ((const char *strp, struct rule *rulep)) |
| static const char *getoffset | P ((const char *strp, long *offsetp)) |
| static const char *getsecs | P ((const char *strp, long *secsp)) |
| static const char *getnum | P ((const char *strp, int *nump, int min, int max)) |
| static const char *getqzname | P ((const char *strp, const int delim)) |
| static const char *getzname | P ((const char *strp)) |
| static int differ_by_repeat | P ((time_t t1, time_t t0)) |
| static long detzcode | P ((const char *codep)) |
| static time_t | time1 (struct tm *tmp, struct tm *(*const funcp)(const time_t *, long, struct tm *, const struct state *), const long offset, const struct state *sp) |
| static time_t | time2 (struct tm *tmp, struct tm *(*const funcp)(const time_t *, long, struct tm *, const struct state *sp), const long offset, int *okayp, const struct state *sp) |
| static time_t | time2sub (struct tm *tmp, struct tm *(*const funcp)(const time_t *, long, struct tm *, const struct state *), const long offset, int *okayp, const int do_norm_secs, const struct state *sp) |
| static struct tm * | timesub (const time_t *timep, const long offset, const struct state *sp, struct tm *tmp) |
| static int | tmcomp (const struct tm *atmp, const struct tm *btmp) |
| static time_t | transtime (const time_t janfirst, const int year, const struct rule *rulep, const long offset) |
| Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the year, a rule, and the offset from UTC at the time that rule takes effect, calculate the Epoch-relative time that rule takes effect. | |
| static int | tzload (const char *name, struct state *const sp, const int doextend) |
| static int | tzparse (const char *name, struct state *sp, const int lastditch) |
Variables | |
| static const int | mon_lengths [2][MONSPERYEAR] |
| static const int | year_lengths [2] |
The original source from this file may be obtained from ftp://elsie.nci.nih.gov/pub/
Definition in file localtime.c.
| #define BIGGEST | ( | a, | |||
| b | ) | (((a) > (b)) ? (a) : (b)) |
Definition at line 131 of file localtime.c.
| #define DAY_OF_YEAR 1 |
| #define JULIAN_DAY 0 |
| #define MONTH_NTH_DAY_OF_WEEK 2 |
| #define MY_TZNAME_MAX 255 |
Definition at line 137 of file localtime.c.
| #define OPEN_MODE O_RDONLY |
Referenced by tzload().
| #define TZ_ABBR_CHAR_SET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" |
| #define TZ_ABBR_ERR_CHAR '_' |
| #define TZ_ABBR_MAX_LEN 16 |
| #define TZ_STRLEN_MAX 255 |
Definition at line 140 of file localtime.c.
| #define TZDEFRULESTRING ",M4.1.0,M10.5.0" |
Referenced by tzparse().
| #define WRONG (-1) |
Referenced by gmtload(), time1(), time2sub(), tzload(), and tzparse().
| static char __attribute__ | ( | (unused) | ) | [static] |
time type information
Definition at line 71 of file localtime.c.
00081 :+-._" 00082 #endif /* !defined TZ_ABBR_CHAR_SET */ 00083 00084 #ifndef TZ_ABBR_ERR_CHAR 00085 #define TZ_ABBR_ERR_CHAR '_' 00086 #endif /* !defined TZ_ABBR_ERR_CHAR */ 00087 00088 /* 00089 ** SunOS 4.1.1 headers lack O_BINARY. 00090 */ 00091 00092 #ifdef O_BINARY 00093 #define OPEN_MODE (O_RDONLY | O_BINARY) 00094 #endif /* defined O_BINARY */ 00095 #ifndef O_BINARY 00096 #define OPEN_MODE O_RDONLY 00097 #endif /* !defined O_BINARY */ 00098 00099 static const char gmt[] = "GMT"; 00100 00101 /*! \note 00102 * The DST rules to use if TZ has no rules and we can't load TZDEFRULES. 00103 * We default to US rules as of 1999-08-17. 00104 * POSIX 1003.1 section 8.1.1 says that the default DST rules are 00105 * implementation dependent; for historical reasons, US rules are a 00106 * common default. 00107 */ 00108 #ifndef TZDEFRULESTRING 00109 #define TZDEFRULESTRING ",M4.1.0,M10.5.0" 00110 #endif /* !defined TZDEFDST */ 00111 00112 #ifndef WRONG 00113 #define WRONG (-1) 00114 #endif /* !defined WRONG */ 00115 00116 /*!< \brief time type information */ 00117 struct ttinfo { /* time type information */ 00118 long tt_gmtoff; /* UTC offset in seconds */ 00119 int tt_isdst; /* used to set tm_isdst */ 00120 int tt_abbrind; /* abbreviation list index */ 00121 int tt_ttisstd; /* TRUE if transition is std time */ 00122 int tt_ttisgmt; /* TRUE if transition is UTC */ 00123 };
| static AST_LIST_HEAD_STATIC | ( | zonelist | , | |
| state | ||||
| ) | [static] |
| struct tm* ast_localtime | ( | const time_t * | timep, | |
| struct tm * | tmp, | |||
| const char * | zone | |||
| ) |
Definition at line 1146 of file localtime.c.
References ast_tzset(), and localsub().
Referenced by acf_strftime(), 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_ge(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_nl(), ast_say_date_pt(), 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_tw(), 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_ge(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_pt(), ast_say_datetime_ge(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_pt_BR(), ast_say_datetime_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_tw(), ast_verbose(), build_query(), build_radius_record(), callerid_genmsg(), cdr_get_tv(), cli_prompt(), get_date(), iax2_datetime(), main(), manager_log(), pgsql_log(), phone_call(), play_message_datetime(), rpt_localtime(), say_date_generic(), sip_show_registry(), sqlite_log(), transmit_notify_request_with_callerid(), vmu_tm(), and write_metadata().
01147 { 01148 const struct state *sp = ast_tzset(zone); 01149 memset(tmp, 0, sizeof(*tmp)); 01150 return sp ? localsub(timep, 0L, tmp, sp) : NULL; 01151 }
| time_t ast_mktime | ( | struct tm * | tmp, | |
| const char * | zone | |||
| ) |
Definition at line 1644 of file localtime.c.
References ast_tzset(), localsub(), and time1().
Referenced by acf_strptime(), sms_readfile(), and unpackdate().
01645 { 01646 const struct state *sp; 01647 if (!(sp = ast_tzset(zone))) 01648 return 0; 01649 return time1(tmp, localsub, 0L, sp); 01650 }
| static struct state* ast_tzset | ( | const char * | zone | ) | [static] |
Definition at line 1018 of file localtime.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), FALSE, gmtload(), state::name, TRUE, tzload(), and tzparse().
Referenced by ast_localtime(), and ast_mktime().
01019 { 01020 struct state *sp; 01021 01022 if (ast_strlen_zero(zone)) 01023 zone = "/etc/localtime"; 01024 01025 AST_LIST_LOCK(&zonelist); 01026 AST_LIST_TRAVERSE(&zonelist, sp, list) { 01027 if (!strcmp(sp->name, zone)) { 01028 AST_LIST_UNLOCK(&zonelist); 01029 return sp; 01030 } 01031 } 01032 AST_LIST_UNLOCK(&zonelist); 01033 01034 if (!(sp = ast_calloc(1, sizeof *sp))) 01035 return NULL; 01036 01037 if (tzload(zone, sp, TRUE) != 0) { 01038 if (zone[0] == ':' || tzparse(zone, sp, FALSE) != 0) 01039 (void) gmtload(sp); 01040 } 01041 ast_copy_string(sp->name, zone, sizeof(sp->name)); 01042 AST_LIST_LOCK(&zonelist); 01043 AST_LIST_INSERT_TAIL(&zonelist, sp, list); 01044 AST_LIST_UNLOCK(&zonelist); 01045 return sp; 01046 }
| static long detzcode | ( | const char *const | codep | ) | [static] |
Definition at line 236 of file localtime.c.
Referenced by tzload().
00237 { 00238 long result; 00239 int i; 00240 00241 result = (codep[0] & 0x80) ? ~0L : 0; 00242 for (i = 0; i < 4; ++i) 00243 result = (result << 8) | (codep[i] & 0xff); 00244 return result; 00245 }
| static time_t detzcode64 | ( | const char *const | codep | ) | [static] |
Definition at line 247 of file localtime.c.
References int_fast64_t.
Referenced by tzload().
00248 { 00249 time_t result; 00250 int i; 00251 00252 result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0; 00253 for (i = 0; i < 8; ++i) 00254 result = result * 256 + (codep[i] & 0xff); 00255 return result; 00256 }
| static int differ_by_repeat | ( | const time_t | t1, | |
| const time_t | t0 | |||
| ) | [static] |
Definition at line 258 of file localtime.c.
References SECSPERREPEAT, SECSPERREPEAT_BITS, TYPE_BIT, TYPE_INTEGRAL, and TYPE_SIGNED.
00259 { 00260 const long long at1 = t1, at0 = t0; 00261 if (TYPE_INTEGRAL(time_t) && 00262 TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) 00263 return 0; 00264 return at1 - at0 == SECSPERREPEAT; 00265 }
| static const char* getnum | ( | const char * | strp, | |
| int * | nump, | |||
| const int | min, | |||
| const int | max | |||
| ) | [static] |
Given a pointer into a time zone string, extract a number from that string. Check that the number is within a specified range; if it is not, return NULL. Otherwise, return a pointer to the first character not part of the number.
Definition at line 547 of file localtime.c.
References is_digit.
Referenced by getrule(), and getsecs().
00548 { 00549 char c; 00550 int num; 00551 00552 if (strp == NULL || !is_digit(c = *strp)) 00553 return NULL; 00554 num = 0; 00555 do { 00556 num = num * 10 + (c - '0'); 00557 if (num > max) 00558 return NULL; /* illegal value */ 00559 c = *++strp; 00560 } while (is_digit(c)); 00561 if (num < min) 00562 return NULL; /* illegal value */ 00563 *nump = num; 00564 return strp; 00565 }
| static const char* getoffset | ( | const char * | strp, | |
| long * | offsetp | |||
| ) | [static] |
Given a pointer into a time zone string, extract an offset, in [+-]hh[:mm[:ss]] form, from the string. If any error occurs, return NULL. Otherwise, return a pointer to the first character not part of the time.
Definition at line 614 of file localtime.c.
References getsecs().
Referenced by tzparse().
00615 { 00616 int neg = 0; 00617 00618 if (*strp == '-') { 00619 neg = 1; 00620 ++strp; 00621 } else if (*strp == '+') 00622 ++strp; 00623 strp = getsecs(strp, offsetp); 00624 if (strp == NULL) 00625 return NULL; /* illegal time */ 00626 if (neg) 00627 *offsetp = -*offsetp; 00628 return strp; 00629 }
| static const char* getqzname | ( | const char * | strp, | |
| const int | delim | |||
| ) | [static] |
Given a pointer into an extended time zone string, scan until the ending delimiter of the zone name is located. Return a pointer to the delimiter.
As with getzname above, the legal character set is actually quite restricted, with other characters producing undefined results. We don't do any checking here; checking is done later in common-case code.
Definition at line 531 of file localtime.c.
Referenced by tzparse().
00532 { 00533 int c; 00534 00535 while ((c = *strp) != '\0' && c != delim) 00536 ++strp; 00537 return strp; 00538 }
| static const char* getrule | ( | const char * | strp, | |
| struct rule * | rulep | |||
| ) | [static] |
Given a pointer into a time zone string, extract a rule in the form date[/time]. See POSIX section 8 for the format of "date" and "time". If a valid rule is not found, return NULL. Otherwise, return a pointer to the first character not part of the rule.
Definition at line 638 of file localtime.c.
References DAY_OF_YEAR, DAYSPERNYEAR, DAYSPERWEEK, getnum(), getsecs(), is_digit, JULIAN_DAY, MONSPERYEAR, MONTH_NTH_DAY_OF_WEEK, rule::r_day, rule::r_mon, rule::r_time, rule::r_type, rule::r_week, and SECSPERHOUR.
Referenced by tzparse().
00639 { 00640 if (*strp == 'J') { 00641 /* 00642 ** Julian day. 00643 */ 00644 rulep->r_type = JULIAN_DAY; 00645 ++strp; 00646 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 00647 } else if (*strp == 'M') { 00648 /* 00649 ** Month, week, day. 00650 */ 00651 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 00652 ++strp; 00653 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 00654 if (strp == NULL) 00655 return NULL; 00656 if (*strp++ != '.') 00657 return NULL; 00658 strp = getnum(strp, &rulep->r_week, 1, 5); 00659 if (strp == NULL) 00660 return NULL; 00661 if (*strp++ != '.') 00662 return NULL; 00663 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 00664 } else if (is_digit(*strp)) { 00665 /* 00666 ** Day of year. 00667 */ 00668 rulep->r_type = DAY_OF_YEAR; 00669 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 00670 } else return NULL; /* invalid format */ 00671 if (strp == NULL) 00672 return NULL; 00673 if (*strp == '/') { 00674 /* 00675 ** Time specified. 00676 */ 00677 ++strp; 00678 strp = getsecs(strp, &rulep->r_time); 00679 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 00680 return strp; 00681 }
| static const char* getsecs | ( | const char * | strp, | |
| long *const | secsp | |||
| ) | [static] |
Given a pointer into a time zone string, extract a number of seconds, in hh[:mm[:ss]] form, from the string. If any error occurs, return NULL. Otherwise, return a pointer to the first character not part of the number of seconds.
Definition at line 575 of file localtime.c.
References DAYSPERWEEK, getnum(), HOURSPERDAY, MINSPERHOUR, SECSPERHOUR, and SECSPERMIN.
Referenced by getoffset(), and getrule().
00576 { 00577 int num; 00578 00579 /* 00580 ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like 00581 ** "M10.4.6/26", which does not conform to Posix, 00582 ** but which specifies the equivalent of 00583 ** ``02:00 on the first Sunday on or after 23 Oct''. 00584 */ 00585 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 00586 if (strp == NULL) 00587 return NULL; 00588 *secsp = num * (long) SECSPERHOUR; 00589 if (*strp == ':') { 00590 ++strp; 00591 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 00592 if (strp == NULL) 00593 return NULL; 00594 *secsp += num * SECSPERMIN; 00595 if (*strp == ':') { 00596 ++strp; 00597 /* `SECSPERMIN' allows for leap seconds. */ 00598 strp = getnum(strp, &num, 0, SECSPERMIN); 00599 if (strp == NULL) 00600 return NULL; 00601 *secsp += num; 00602 } 00603 } 00604 return strp; 00605 }
| static const char* getzname | ( | const char * | strp | ) | [static] |
Given a pointer into a time zone string, scan until a character that is not a valid character in a zone name is found. Return a pointer to that character.
Definition at line 512 of file localtime.c.
References is_digit.
Referenced by tzparse().
00513 { 00514 char c; 00515 00516 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 00517 c != '+') 00518 ++strp; 00519 return strp; 00520 }
| static int gmtload | ( | struct state * | sp | ) | [static] |
| static struct tm* gmtsub | ( | const time_t * | timep, | |
| const long | offset, | |||
| struct tm * | tmp | |||
| ) | [static] |
Definition at line 1157 of file localtime.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, state::chars, gmtload(), state::name, and timesub().
Referenced by localsub().
01158 { 01159 struct tm * result; 01160 struct state *sp; 01161 01162 AST_LIST_LOCK(&zonelist); 01163 AST_LIST_TRAVERSE(&zonelist, sp, list) { 01164 if (!strcmp(sp->name, "UTC")) 01165 break; 01166 } 01167 01168 if (!sp) { 01169 if (!(sp = (struct state *) ast_calloc(1, sizeof *sp))) 01170 return NULL; 01171 gmtload(sp); 01172 AST_LIST_INSERT_TAIL(&zonelist, sp, list); 01173 } 01174 AST_LIST_UNLOCK(&zonelist); 01175 01176 result = timesub(timep, offset, sp, tmp); 01177 #ifdef TM_ZONE 01178 /* 01179 ** Could get fancy here and deliver something such as 01180 ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, 01181 ** but this is no time for a treasure hunt. 01182 */ 01183 if (offset != 0) 01184 tmp->TM_ZONE = " "; 01185 else 01186 tmp->TM_ZONE = sp->chars; 01187 #endif /* defined TM_ZONE */ 01188 return result; 01189 }
| static int increment_overflow | ( | int * | number, | |
| int | delta | |||
| ) | [static] |
Simplified normalize logic courtesy Paul Eggert.
Definition at line 1339 of file localtime.c.
Referenced by normalize_overflow(), and timesub().
01340 { 01341 int number0; 01342 01343 number0 = *number; 01344 *number += delta; 01345 return (*number < number0) != (delta < 0); 01346 }
| static int leaps_thru_end_of | ( | const int | y | ) | [static] |
Return the number of leap years through the end of the given year where, to make the math easy, the answer for year zero is defined as zero.
Definition at line 1196 of file localtime.c.
Referenced by timesub().
01197 { 01198 return (y >= 0) ? (y / 4 - y / 100 + y / 400) : 01199 -(leaps_thru_end_of(-(y + 1)) + 1); 01200 }
| static struct tm* localsub | ( | const time_t * | timep, | |
| const long | offset, | |||
| struct tm * | tmp, | |||
| const struct state * | sp | |||
| ) | [static] |
Definition at line 1057 of file localtime.c.
References state::ats, AVGSECSPERYEAR, state::chars, gmtsub(), state::goahead, state::goback, int_fast64_t, t, state::timecnt, timesub(), state::ttis, state::typecnt, state::types, and YEARSPERREPEAT.
Referenced by ast_localtime(), and ast_mktime().
01058 { 01059 const struct ttinfo * ttisp; 01060 int i; 01061 struct tm * result; 01062 const time_t t = *timep; 01063 01064 if (sp == NULL) 01065 return gmtsub(timep, offset, tmp); 01066 if ((sp->goback && t < sp->ats[0]) || 01067 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 01068 time_t newt = t; 01069 time_t seconds; 01070 time_t tcycles; 01071 int_fast64_t icycles; 01072 01073 if (t < sp->ats[0]) 01074 seconds = sp->ats[0] - t; 01075 else seconds = t - sp->ats[sp->timecnt - 1]; 01076 --seconds; 01077 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; 01078 ++tcycles; 01079 icycles = tcycles; 01080 if (tcycles - icycles >= 1 || icycles - tcycles >= 1) 01081 return NULL; 01082 seconds = icycles; 01083 seconds *= YEARSPERREPEAT; 01084 seconds *= AVGSECSPERYEAR; 01085 if (t < sp->ats[0]) 01086 newt += seconds; 01087 else newt -= seconds; 01088 if (newt < sp->ats[0] || 01089 newt > sp->ats[sp->timecnt - 1]) 01090 return NULL; /* "cannot happen" */ 01091 result = localsub(&newt, offset, tmp, sp); 01092 if (result == tmp) { 01093 time_t newy; 01094 01095 newy = tmp->tm_year; 01096 if (t < sp->ats[0]) 01097 newy -= icycles * YEARSPERREPEAT; 01098 else 01099 newy += icycles * YEARSPERREPEAT; 01100 tmp->tm_year = newy; 01101 if (tmp->tm_year != newy) 01102 return NULL; 01103 } 01104 return result; 01105 } 01106 if (sp->timecnt == 0 || t < sp->ats[0]) { 01107 i = 0; 01108 while (sp->ttis[i].tt_isdst) { 01109 if (++i >= sp->typecnt) { 01110 i = 0; 01111 break; 01112 } 01113 } 01114 } else { 01115 int lo = 1; 01116 int hi = sp->timecnt; 01117 01118 while (lo < hi) { 01119 int mid = (lo + hi) >> 1; 01120 01121 if (t < sp->ats[mid]) 01122 hi = mid; 01123 else 01124 lo = mid + 1; 01125 } 01126 i = (int) sp->types[lo - 1]; 01127 } 01128 ttisp = &sp->ttis[i]; 01129 /* 01130 ** To get (wrong) behavior that's compatible with System V Release 2.0 01131 ** you'd replace the statement below with 01132 ** t += ttisp->tt_gmtoff; 01133 ** timesub(&t, 0L, sp, tmp); 01134 */ 01135 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); 01136 tmp->tm_isdst = ttisp->tt_isdst; 01137 #ifndef SOLARIS /* Solaris doesn't have this element */ 01138 tmp->tm_gmtoff = ttisp->tt_gmtoff; 01139 #endif 01140 #ifdef TM_ZONE 01141 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; 01142 #endif /* defined TM_ZONE */ 01143 return result; 01144 }
| static int long_increment_overflow | ( | long * | number, | |
| int | delta | |||
| ) | [static] |
Definition at line 1348 of file localtime.c.
Referenced by long_normalize_overflow(), and time2sub().
01349 { 01350 long number0; 01351 01352 number0 = *number; 01353 *number += delta; 01354 return (*number < number0) != (delta < 0); 01355 }
| static int long_normalize_overflow | ( | long * | tensptr, | |
| int * | unitsptr, | |||
| const int | base | |||
| ) | [static] |
Definition at line 1368 of file localtime.c.
References long_increment_overflow().
Referenced by time2sub().
01369 { 01370 int tensdelta; 01371 01372 tensdelta = (*unitsptr >= 0) ? 01373 (*unitsptr / base) : 01374 (-1 - (-1 - *unitsptr) / base); 01375 *unitsptr -= tensdelta * base; 01376 return long_increment_overflow(tensptr, tensdelta); 01377 }
| static int normalize_overflow | ( | int * | tensptr, | |
| int * | unitsptr, | |||
| const int | base | |||
| ) | [static] |
Definition at line 1357 of file localtime.c.
References increment_overflow().
Referenced by time2sub().
01358 { 01359 int tensdelta; 01360 01361 tensdelta = (*unitsptr >= 0) ? 01362 (*unitsptr / base) : 01363 (-1 - (-1 - *unitsptr) / base); 01364 *unitsptr -= tensdelta * base; 01365 return increment_overflow(tensptr, tensdelta); 01366 }
| static time_t transtime P | ( | (time_t janfirst, int year, const struct rule *rulep, long offset) | ) | [static] |
| static int tmcomp P | ( | (const struct tm *atmp, const struct tm *btmp) | ) | [static] |
| static struct tm* timesub P | ( | (const time_t *timep, long offset, const struct state *sp, struct tm *tmp) | ) | [static] |
| static time_t time2sub P | ( | (struct tm *tmp, struct tm *(*funcp)(const time_t *, long, struct tm *, const struct state *sp), long offset, int *okayp, int do_norm_secs, const struct state *sp) | ) | [static] |
| static time_t time2 P | ( | (struct tm *tmp, struct tm *(*funcp) P((const time_t *, long, struct tm *, const struct state *sp)), long offset, int *okayp, const struct state *sp) | ) | [static] |
| static time_t time1 P | ( | (struct tm *tmp, struct tm *(*funcp) P((const time_t *, long, struct tm *, const struct state *sp)), long offset, const struct state *sp) | ) | [static] |
| static int normalize_overflow P | ( | (int *tensptr, int *unitsptr, const int base) | ) | [static] |
| static int long_normalize_overflow P | ( | (long *tensptr, int *unitsptr, const int base) | ) | [static] |
| static int long_increment_overflow P | ( | (long *number, int delta) | ) | [static] |
| static int leaps_thru_end_of P | ( | (int y) | ) | [static] |
| static int increment_overflow P | ( | (int *number, int delta) | ) | [static] |
| static struct tm* localsub P | ( | (const time_t *timep, long offset, struct tm *tmp, const struct state *sp) | ) | [static] |
| static struct tm* gmtsub P | ( | (const time_t *timep, long offset, struct tm *tmp) | ) | [static] |
| static int gmtload P | ( | (struct state *sp) | ) | [static] |
| static const char* getrule P | ( | (const char *strp, struct rule *rulep) | ) | [static] |
| static const char* getoffset P | ( | (const char *strp, long *offsetp) | ) | [static] |
| static const char* getsecs P | ( | (const char *strp, long *secsp) | ) | [static] |
| static const char* getnum P | ( | (const char *strp, int *nump, int min, int max) | ) | [static] |
| static const char* getqzname P | ( | (const char *strp, const int delim) | ) | [static] |