⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 localtime.c

📁 Asterisk-1.4.4最新内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		ast_tzsetwall();		sp = lclptr;		/* Find the default zone record */		while (sp != NULL) {			if (sp->name[0] == '\0')				break;			sp = sp->next;		}	}	/* Last ditch effort, use GMT */	if (sp == NULL) {		gmtsub(timep, offset, tmp, zone);		return;	}	if (sp->timecnt == 0 || t < sp->ats[0]) {		i = 0;		while (sp->ttis[i].tt_isdst)			if (++i >= sp->typecnt) {				i = 0;				break;			}	} else {		for (i = 1; i < sp->timecnt; ++i)			if (t < sp->ats[i])				break;		i = sp->types[i - 1];	}	ttisp = &sp->ttis[i];	/*	** To get (wrong) behavior that's compatible with System V Release 2.0	** you'd replace the statement below with	**	t += ttisp->tt_gmtoff;	**	timesub(&t, 0L, sp, tmp);	*/	timesub(&t, ttisp->tt_gmtoff, sp, tmp);	tmp->tm_isdst = ttisp->tt_isdst;	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];#ifdef TM_ZONE	tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];#endif /* defined TM_ZONE */}struct tm *ast_localtime(timep, p_tm, zone)const time_t * const	timep;struct tm *p_tm;const char * const	zone;{#ifdef _THREAD_SAFE	ast_mutex_lock(&lcl_mutex);#endif	ast_tzset(ast_strlen_zero(zone) ? "/etc/localtime" : zone);	localsub(timep, 0L, p_tm, zone);#ifdef _THREAD_SAFE	ast_mutex_unlock(&lcl_mutex);#endif	return(p_tm);}/*** gmtsub is to gmtime as localsub is to localtime.*/static voidgmtsub(timep, offset, tmp, zone)const time_t * const	timep;const long		offset;struct tm * const	tmp;const char * const	zone;{#ifdef	_THREAD_SAFE	ast_mutex_lock(&gmt_mutex);#endif	if (!gmt_is_set) {		gmt_is_set = TRUE;		gmtptr = (struct state *) malloc(sizeof *gmtptr);		if (gmtptr != NULL)			gmtload(gmtptr);	}	ast_mutex_unlock(&gmt_mutex);	timesub(timep, offset, gmtptr, tmp);#ifdef TM_ZONE	/*	** Could get fancy here and deliver something such as	** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,	** but this is no time for a treasure hunt.	*/	if (offset != 0)		tmp->TM_ZONE = wildabbr;	else {		if (gmtptr == NULL)			tmp->TM_ZONE = gmt;		else	tmp->TM_ZONE = gmtptr->chars;	}#endif /* defined TM_ZONE */}static voidtimesub(timep, offset, sp, tmp)const time_t * const			timep;const long				offset;register const struct state * const	sp;register struct tm * const		tmp;{	register const struct lsinfo *	lp;	register long			days;	register long			rem;	register int			y;	register int			yleap;	register const int *		ip;	register long			corr;	register int			hit;	register int			i;	corr = 0;	hit = 0;	i = (sp == NULL) ? 0 : sp->leapcnt;	while (--i >= 0) {		lp = &sp->lsis[i];		if (*timep >= lp->ls_trans) {			if (*timep == lp->ls_trans) {				hit = ((i == 0 && lp->ls_corr > 0) ||					lp->ls_corr > sp->lsis[i - 1].ls_corr);				if (hit)					while (i > 0 &&						sp->lsis[i].ls_trans ==						sp->lsis[i - 1].ls_trans + 1 &&						sp->lsis[i].ls_corr ==						sp->lsis[i - 1].ls_corr + 1) {							++hit;							--i;					}			}			corr = lp->ls_corr;			break;		}	}	days = *timep / SECSPERDAY;	rem = *timep % SECSPERDAY;#ifdef mc68k	if (*timep == 0x80000000) {		/*		** A 3B1 muffs the division on the most negative number.		*/		days = -24855;		rem = -11648;	}#endif /* defined mc68k */	rem += (offset - corr);	while (rem < 0) {		rem += SECSPERDAY;		--days;	}	while (rem >= SECSPERDAY) {		rem -= SECSPERDAY;		++days;	}	tmp->tm_hour = (int) (rem / SECSPERHOUR);	rem = rem % SECSPERHOUR;	tmp->tm_min = (int) (rem / SECSPERMIN);	/*	** A positive leap second requires a special	** representation.  This uses "... ??:59:60" et seq.	*/	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;	tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);	if (tmp->tm_wday < 0)		tmp->tm_wday += DAYSPERWEEK;	y = EPOCH_YEAR;#define LEAPS_THRU_END_OF(y)	((y) / 4 - (y) / 100 + (y) / 400)	while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {		register int	newy;		newy = y + days / DAYSPERNYEAR;		if (days < 0)			--newy;		days -= (newy - y) * DAYSPERNYEAR +			LEAPS_THRU_END_OF(newy - 1) -			LEAPS_THRU_END_OF(y - 1);		y = newy;	}	tmp->tm_year = y - TM_YEAR_BASE;	tmp->tm_yday = (int) days;	ip = mon_lengths[yleap];	for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))		days = days - (long) ip[tmp->tm_mon];	tmp->tm_mday = (int) (days + 1);	tmp->tm_isdst = 0;#ifdef TM_GMTOFF	tmp->TM_GMTOFF = offset;#endif /* defined TM_GMTOFF */}char *ast_ctime(timep)const time_t * const	timep;{/*** Section 4.12.3.2 of X3.159-1989 requires that**	The ctime funciton converts the calendar time pointed to by timer**	to local time in the form of a string.  It is equivalent to**		asctime(localtime(timer))*/	return asctime(localtime(timep));}char *ast_ctime_r(timep, buf)const time_t * const	timep;char *buf;{        struct tm tm;	return asctime_r(localtime_r(timep, &tm), buf);}/*** Adapted from code provided by Robert Elz, who writes:**	The "best" way to do mktime I think is based on an idea of Bob**	Kridle's (so its said...) from a long time ago.**	[kridle@xinet.com as of 1996-01-16.]**	It does a binary search of the time_t space.  Since time_t's are**	just 32 bits, its a max of 32 iterations (even at 64 bits it**	would still be very reasonable).*/#ifndef WRONG#define WRONG	(-1)#endif /* !defined WRONG *//*** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).*/static intincrement_overflow(number, delta)int *	number;int	delta;{	int	number0;	number0 = *number;	*number += delta;	return (*number < number0) != (delta < 0);}static intnormalize_overflow(tensptr, unitsptr, base)int * const	tensptr;int * const	unitsptr;const int	base;{	register int	tensdelta;	tensdelta = (*unitsptr >= 0) ?		(*unitsptr / base) :		(-1 - (-1 - *unitsptr) / base);	*unitsptr -= tensdelta * base;	return increment_overflow(tensptr, tensdelta);}static inttmcomp(atmp, btmp)register const struct tm * const atmp;register const struct tm * const btmp;{	register int	result;	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&		(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&		(result = (atmp->tm_min - btmp->tm_min)) == 0)			result = atmp->tm_sec - btmp->tm_sec;	return result;}static time_ttime2(tmp, funcp, offset, okayp, zone)struct tm * const	tmp;void (* const		funcp) P((const time_t*, long, struct tm*, const char*));const long		offset;int * const		okayp;const char * const	zone;{	register const struct state *	sp;	register int			dir;	register int			bits;	register int			i, j ;	register int			saved_seconds;	time_t				newt;	time_t				t;	struct tm			yourtm, mytm;	*okayp = FALSE;	yourtm = *tmp;	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))		return WRONG;	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))		return WRONG;	if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))		return WRONG;	/*	** Turn yourtm.tm_year into an actual year number for now.	** It is converted back to an offset from TM_YEAR_BASE later.	*/	if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))		return WRONG;	while (yourtm.tm_mday <= 0) {		if (increment_overflow(&yourtm.tm_year, -1))			return WRONG;		i = yourtm.tm_year + (1 < yourtm.tm_mon);		yourtm.tm_mday += year_lengths[isleap(i)];	}	while (yourtm.tm_mday > DAYSPERLYEAR) {		i = yourtm.tm_year + (1 < yourtm.tm_mon);		yourtm.tm_mday -= year_lengths[isleap(i)];		if (increment_overflow(&yourtm.tm_year, 1))			return WRONG;	}	for ( ; ; ) {		i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];		if (yourtm.tm_mday <= i)			break;		yourtm.tm_mday -= i;		if (++yourtm.tm_mon >= MONSPERYEAR) {			yourtm.tm_mon = 0;			if (increment_overflow(&yourtm.tm_year, 1))				return WRONG;		}	}	if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))		return WRONG;	if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {		/*		** We can't set tm_sec to 0, because that might push the		** time below the minimum representable time.		** Set tm_sec to 59 instead.		** This assumes that the minimum representable time is		** not in the same minute that a leap second was deleted from,		** which is a safer assumption than using 58 would be.		*/		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))			return WRONG;		saved_seconds = yourtm.tm_sec;		yourtm.tm_sec = SECSPERMIN - 1;	} else {		saved_seconds = yourtm.tm_sec;		yourtm.tm_sec = 0;	}	/*	** Divide the search space in half	** (this works whether time_t is signed or unsigned).	*/	bits = TYPE_BIT(time_t) - 1;	/*	** If time_t is signed, then 0 is just above the median,	** assuming two's complement arithmetic.	** If time_t is unsigned, then (1 << bits) is just above the median.	*/	t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);	for ( ; ; ) {		(*funcp)(&t, offset, &mytm, zone);		dir = tmcomp(&mytm, &yourtm);		if (dir != 0) {			if (bits-- < 0)				return WRONG;			if (bits < 0)				--t; /* may be needed if new t is minimal */			else if (dir > 0)				t -= ((time_t) 1) << bits;			else	t += ((time_t) 1) << bits;			continue;		}		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)			break;		/*		** Right time, wrong type.		** Hunt for right time, right type.		** It's okay to guess wrong since the guess		** gets checked.		*/		/*		** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.		*/		sp = (const struct state *)			(((void *) funcp == (void *) localsub) ?			lclptr : gmtptr);		if (sp == NULL)			return WRONG;		for (i = sp->typecnt - 1; i >= 0; --i) {			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)				continue;			for (j = sp->typecnt - 1; j >= 0; --j) {				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)					continue;				newt = t + sp->ttis[j].tt_gmtoff -					sp->ttis[i].tt_gmtoff;				(*funcp)(&newt, offset, &mytm, zone);				if (tmcomp(&mytm, &yourtm) != 0)					continue;				if (mytm.tm_isdst != yourtm.tm_isdst)					continue;				/*				** We have a match.				*/				t = newt;				goto label;			}		}		return WRONG;	}label:	newt = t + saved_seconds;	if ((newt < t) != (saved_seconds < 0))		return WRONG;	t = newt;	(*funcp)(&t, offset, tmp, zone);	*okayp = TRUE;	return t;}static time_ttime1(tmp, funcp, offset, zone)struct tm * const	tmp;void (* const		funcp) P((const time_t *, long, struct tm *, const char*));const long		offset;const char * const	zone;{	register time_t			t;	register const struct state *	sp;	register int			samei, otheri;	int				okay;	if (tmp->tm_isdst > 1)		tmp->tm_isdst = 1;	t = time2(tmp, funcp, offset, &okay, zone);#ifdef PCTS	/*	** PCTS code courtesy Grant Sullivan (grant@osf.org).	*/	if (okay)		return t;	if (tmp->tm_isdst < 0)		tmp->tm_isdst = 0;	/* reset to std and try again */#endif /* defined PCTS */#ifndef PCTS	if (okay || tmp->tm_isdst < 0)		return t;#endif /* !defined PCTS */	/*	** We're supposed to assume that somebody took a time of one type	** and did some math on it that yielded a "struct tm" that's bad.	** We try to divine the type they started from and adjust to the	** type they need.	*/	/*	** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.	*/	sp = (const struct state *) (((void *) funcp == (void *) localsub) ?		lclptr : gmtptr);	if (sp == NULL)		return WRONG;	for (samei = sp->typecnt - 1; samei >= 0; --samei) {		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)			continue;		for (otheri = sp->typecnt - 1; otheri >= 0; --otheri) {			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)				continue;			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -					sp->ttis[samei].tt_gmtoff;			tmp->tm_isdst = !tmp->tm_isdst;			t = time2(tmp, funcp, offset, &okay, zone);			if (okay)				return t;			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -					sp->ttis[samei].tt_gmtoff;			tmp->tm_isdst = !tmp->tm_isdst;		}	}	return WRONG;}time_tast_mktime(tmp,zone)struct tm * const	tmp;const char * const	zone;{	time_t mktime_return_value;#ifdef	_THREAD_SAFE	ast_mutex_lock(&lcl_mutex);#endif	ast_tzset(!ast_strlen_zero(zone) ? zone : "/etc/localtime");	mktime_return_value = time1(tmp, localsub, 0L, !ast_strlen_zero(zone) ? zone : "/etc/localtime");#ifdef	_THREAD_SAFE	ast_mutex_unlock(&lcl_mutex);#endif	return(mktime_return_value);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -