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

📄 localtime.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (lclptr == NULL) {#ifdef S5EMUL			settzname();	/* all we can do */#endif			return;		}	}	if (tzload((char *) NULL, lclptr) != 0)		gmtload(lclptr);#ifdef S5EMUL	settzname();#endif}voidtzset(){	register const char *	name;	name = getenv("TZ");	if (name == NULL) {		tzsetwall();		return;	}	lcl_is_set = TRUE;	if (lclptr == NULL) {		lclptr = (struct state *) calloc(1, (unsigned)sizeof *lclptr);		if (lclptr == NULL) {#ifdef S5EMUL			settzname();	/* all we can do */#endif			return;		}	}	if (*name == '\0') {		/*		** User wants it fast rather than right.		*/		lclptr->timecnt = 0;		lclptr->typecnt = 1;		lclptr->charcnt = sizeof GMT;		if (allocall(lclptr) < 0)			return;		lclptr->ttis[0].tt_gmtoff = 0;		lclptr->ttis[0].tt_abbrind = 0;		(void) strcpy(lclptr->chars, GMT);	} else if (tzload(name, lclptr) != 0)		if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)			(void) tzparse(name, lclptr, TRUE);#ifdef S5EMUL	settzname();#endif}/*** The easy way to behave "as if no library function calls" localtime** is to not call it--so we drop its guts into "localsub", which can be** freely called.  (And no, the PANS doesn't require the above behavior--** but it *is* desirable.)**** The unused offset argument is for the benefit of mktime variants.*/static struct tm	tm;/*ARGSUSED*/static voidlocalsub(timep, offset, tmp)const time_t * const	timep;const long		offset;struct tm * const	tmp;{	register const struct state *	sp;	register const struct ttinfo *	ttisp;	register int			i;	const time_t			t = *timep;	if (!lcl_is_set)		tzset();	sp = lclptr;	if (sp == NULL) {		gmtsub(timep, offset, tmp);		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];	timesub(&t, ttisp->tt_gmtoff, tmp);	tmp->tm_isdst = ttisp->tt_isdst;#ifdef S5EMUL	tzname[tmp->tm_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];#endif /* S5EMUL */	tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];}struct tm *localtime(timep)const time_t * const	timep;{	localsub(timep, 0L, &tm);	return &tm;}/*** gmtsub is to gmtime as localsub is to localtime.*/static voidgmtsub(timep, offset, tmp)const time_t * const	timep;const long		offset;struct tm * const	tmp;{	if (!gmt_is_set) {		gmt_is_set = TRUE;		gmtptr = (struct state *) calloc(1, (unsigned)sizeof *gmtptr);		if (gmtptr != NULL)			gmtload(gmtptr);	}	timesub(timep, offset, tmp);	/*	** 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;	}}struct tm *gmtime(timep)const time_t * const	timep;{	gmtsub(timep, 0L, &tm);	return &tm;}struct tm *offtime(timep, offset)const time_t * const	timep;const long		offset;{	gmtsub(timep, offset, &tm);	return &tm;}static voidtimesub(timep, offset, tmp)const time_t * const			timep;const long				offset;register struct tm * const		tmp;{	register long			days;	register long			rem;	register int			y;	register int			yleap;	register const int *		ip;	days = *timep / SECSPERDAY;	rem = *timep % SECSPERDAY;	rem += offset;	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);	tmp->tm_sec = (int) (rem % SECSPERMIN);	tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);	if (tmp->tm_wday < 0)		tmp->tm_wday += DAYSPERWEEK;	y = EPOCH_YEAR;	if (days >= 0)		for ( ; ; ) {			yleap = isleap(y);			if (days < (long) year_lengths[yleap])				break;			++y;			days = days - (long) year_lengths[yleap];		}	else do {		--y;		yleap = isleap(y);		days = days + (long) year_lengths[yleap];	} while (days < 0);	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;	tmp->tm_gmtoff = offset;}/*** 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. (mtxinu!kridle now).**	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 */static voidnormalize(tensptr, unitsptr, base)int * const	tensptr;int * const	unitsptr;const int	base;{	if (*unitsptr >= base) {		*tensptr += *unitsptr / base;		*unitsptr %= base;	} else if (*unitsptr < 0) {		--*tensptr;		*unitsptr += base;		if (*unitsptr < 0) {			*tensptr -= 1 + (-*unitsptr) / base;			*unitsptr = base - (-*unitsptr) % base;		}	}}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)struct tm * const	tmp;void (* const		funcp)();const long		offset;int * const		okayp;{	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 (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0)		normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN);	normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR);	normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY);	normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR);	while (yourtm.tm_mday <= 0) {		--yourtm.tm_year;		yourtm.tm_mday +=			year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];	}	for ( ; ; ) {		i = mon_lengths[isleap(yourtm.tm_year +			TM_YEAR_BASE)][yourtm.tm_mon];		if (yourtm.tm_mday <= i)			break;		yourtm.tm_mday -= i;		if (++yourtm.tm_mon >= MONSPERYEAR) {			yourtm.tm_mon = 0;			++yourtm.tm_year;		}	}	saved_seconds = yourtm.tm_sec;	yourtm.tm_sec = 0;	/*	** Calculate the number of magnitude bits in a time_t	** (this works regardless of whether time_t is	** signed or unsigned, though lint complains if unsigned).	*/	for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)		;	/*	** If time_t is signed, then 0 is the median value,	** if time_t is unsigned, then 1 << bits is median.	*/	t = (t < 0) ? 0 : ((time_t) 1 << bits);	for ( ; ; ) {		(*funcp)(&t, offset, &mytm);		dir = tmcomp(&mytm, &yourtm);		if (dir != 0) {			if (bits-- < 0)				return WRONG;			if (bits < 0)				--t;			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.		*/		sp = (const struct state *)			((funcp == localsub) ? lclptr : gmtptr);		if (sp == NULL)			return WRONG;		for (i = 0; i < sp->typecnt; ++i) {			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)				continue;			for (j = 0; j < sp->typecnt; ++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);				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:	t += saved_seconds;	(*funcp)(&t, offset, tmp);	*okayp = TRUE;	return t;}static time_ttime1(tmp, funcp, offset)struct tm * const	tmp;void (* const		funcp)();const long		offset;{	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);	if (okay || tmp->tm_isdst < 0)		return t;	/*	** 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.	*/	sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr);	if (sp == NULL)		return WRONG;	for (samei = 0; samei < sp->typecnt; ++samei) {		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)			continue;		for (otheri = 0; otheri < sp->typecnt; ++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);			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_tmktime(tmp)struct tm * const	tmp;{	return time1(tmp, localsub, 0L);}time_ttimelocal(tmp)struct tm * const	tmp;{	tmp->tm_isdst = -1; 	return mktime(tmp);}time_ttimegm(tmp)struct tm * const	tmp;{	return time1(tmp, gmtsub, 0L);}time_ttimeoff(tmp, offset)struct tm * const	tmp;const long		offset;{	return time1(tmp, gmtsub, offset);}

⌨️ 快捷键说明

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