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

📄 localtime.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 4 页
字号:
 */extern "C" struct tm *gmtime_r(const time_t *timep, struct tm *tm){	gmtsub(timep, 0L, tm);	return tm;}#ifdef STD_INSPIREDextern "C" struct tm *offtime(const time_t *timep, const long offset){	gmtsub(timep, offset, &tm);	return &tm;}#endif /* defined STD_INSPIRED */static voidtimesub(const time_t *timep, const long offset, const struct state *sp,	struct tm *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;#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);				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 */}extern "C" char *ctime(const time_t *timep){/*** Section 4.12.3.2 of X3.159-1989 requires that**	The ctime function 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));}extern "C" char *ctime_r(const time_t *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(int *number, int delta){	int	number0;	number0 = *number;	*number += delta;	return (*number < number0) != (delta < 0);}static intnormalize_overflow(int *tensptr, int *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(register const struct tm *atmp, register const struct tm *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_ttime2sub(struct tm *tmp, void (*funcp) P((const time_t*, long, struct tm*)),	 const long offset, int *okayp, const int do_norm_secs){	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 (do_norm_secs) {		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,			SECSPERMIN))				return WRONG;	}	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);		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);#ifdef ALL_STATE		if (sp == NULL)			return WRONG;#endif /* defined ALL_STATE */		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);				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);	*okayp = TRUE;	return t;}static time_ttime2(struct tm *tmp, void (*funcp) P((const time_t*, long, struct tm*)),      const long offset, int *okayp){	time_t	t;	/*	** First try without normalization of seconds	** (in case tm_sec contains a value associated with a leap second).	** If that fails, try with normalization of seconds.	*/	t = time2sub(tmp, funcp, offset, okayp, FALSE);	return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);}static time_ttime1(struct tm *tmp, void (*funcp) P((const time_t *, long, struct tm *)),      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);#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);#ifdef ALL_STATE	if (sp == NULL)		return WRONG;#endif /* defined ALL_STATE */	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);			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;}extern "C" time_tmktime(struct tm *tmp){	tzset();	return time1(tmp, localsub, 0L);}#ifdef STD_INSPIREDextern "C" time_ttimelocal(struct tm *tmp){	tmp->tm_isdst = -1;	/* in case it wasn't initialized */	return mktime(tmp);}extern "C" time_ttimegm(struct tm *tmp){	tmp->tm_isdst = 0;	return time1(tmp, gmtsub, 0L);}extern "C" time_ttimeoff(struct tm *tmp, const long offset){	tmp->tm_isdst = 0;	return time1(tmp, gmtsub, offset);}#endif /* defined STD_INSPIRED */#ifdef CMUCS/*** The following is supplied for compatibility with** previous versions of the CMUCS runtime library.*/extern "C" longgtime(struct tm *tmp){	const time_t	t = mktime(tmp);	if (t == WRONG)		return -1;	return t;}#endif /* defined CMUCS *//*** XXX--is the below the right way to conditionalize??*/#ifdef STD_INSPIRED/*** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which** is not the case if we are accounting for leap seconds.** So, we provide the following conversion routines for use** when exchanging timestamps with POSIX conforming systems.*/static longleapcorr(time_t *timep){	register struct state *		sp;	register struct lsinfo *	lp;	register int			i;	sp = lclptr;	i = sp->leapcnt;	while (--i >= 0) {		lp = &sp->lsis[i];		if (*timep >= lp->ls_trans)			return lp->ls_corr;	}	return 0;}extern "C" time_ttime2posix(time_t t){	tzset();	return t - leapcorr(&t);}extern "C" time_tposix2time(time_t t){	time_t	x;	time_t	y;	tzset();	/*	** For a positive leap second hit, the result	** is not unique.  For a negative leap second	** hit, the corresponding time doesn't exist,	** so we return an adjacent second.	*/	x = t + leapcorr(&t);	y = x - leapcorr(&x);	if (y < t) {		do {			x++;			y = x - leapcorr(&x);		} while (y < t);		if (t != y)			return x - 1;	} else if (y > t) {		do {			--x;			y = x - leapcorr(&x);		} while (y > t);		if (t != y)			return x + 1;	}	return x;}#endif /* defined STD_INSPIRED */

⌨️ 快捷键说明

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