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

📄 ctime.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
			return;		}	}#endif /* defined ALL_STATE */	if (tzload((char *) NULL, lclptr) != 0)		gmtload(lclptr);	settzname();}/*** 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.*//*ARGSUSED*/static voidlocalsub(timep, offset, tmp)const time_t * const	timep;const long		offset;struct tm * const	tmp;{	register struct state *	sp;	register const struct ttinfo *	ttisp;	register int			i;	const time_t			t = *timep;	if (!lcl_is_set)		tzset();	sp = lclptr;#ifdef ALL_STATE	if (sp == NULL) {		gmtsub(timep, offset, tmp);		return;	}#endif /* defined ALL_STATE */	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] = (char *) &sp->chars[ttisp->tt_abbrind];	tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];}struct tm *localtime(timep)const time_t * const	timep;{	static struct tm	tm;	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;#ifdef ALL_STATE		gmtptr = (struct state *) malloc(sizeof *gmtptr);		if (gmtptr != NULL)#endif /* defined ALL_STATE */			gmtload(gmtptr);	}	timesub(timep, offset, gmtptr, 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 {#ifdef ALL_STATE		if (gmtptr == NULL)			tmp->TM_ZONE = GMT;		else	tmp->TM_ZONE = gmtptr->chars;#endif /* defined ALL_STATE */#ifndef ALL_STATE		tmp->tm_zone = gmtptr->chars;#endif /* State Farm */	}}struct tm *gmtime(timep)const time_t * const	timep;{	static struct tm	tm;	gmtsub(timep, 0L, &tm);	return &tm;}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 = FALSE;#ifdef ALL_STATE	i = (sp == NULL) ? 0 : sp->leapcnt;#endif /* defined ALL_STATE */#ifndef ALL_STATE	i = sp->leapcnt;#endif /* State Farm */	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);			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 /* 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);	tmp->tm_sec = (int) (rem % SECSPERMIN);	if (hit)		/*		** A positive leap second requires a special		** representation.  This uses "... ??:59:60".		*/		++(tmp->tm_sec);	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;}/*** A la X3J11*/char *asctime(timeptr)register const struct tm *	timeptr;{	static const char	wday_name[DAYSPERWEEK][3] = {		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"	};	static const char	mon_name[MONSPERYEAR][3] = {		"Jan", "Feb", "Mar", "Apr", "May", "Jun",		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"	};	static char	result[26];	(void) sprintf(result, "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n",		wday_name[timeptr->tm_wday],		mon_name[timeptr->tm_mon],		timeptr->tm_mday, timeptr->tm_hour,		timeptr->tm_min, timeptr->tm_sec,		TM_YEAR_BASE + timeptr->tm_year);	return result;}char *ctime(timep)const time_t * const	timep;{	return asctime(localtime(timep));}/*** 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 -= 1 + (-(*unitsptr + 1)) / base;		*unitsptr = base - 1 - (-(*unitsptr + 1)) % 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)];	}	while (yourtm.tm_mday > DAYSPERLYEAR) {		yourtm.tm_mday -=		    year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];		++yourtm.tm_year;	}	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);#ifdef ALL_STATE		if (sp == NULL)			return WRONG;#endif /* defined ALL_STATE */		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);#ifdef ALL_STATE	if (sp == NULL)		return WRONG;#endif /* defined ALL_STATE */	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);}

⌨️ 快捷键说明

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