ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
25 апреля
732693 Топик полностью
sav_ua (31.01.2017 12:32 - 12:41, просмотров: 98) ответил SciFi на Вот, мне не жалко:
полная версия :)  
/*******************************************************************************/
typedef struct {
  int tm_sec;     /* seconds after the minute - [0,59] */
  int tm_min;     /* minutes after the hour - [0,59] */
  int tm_hour;    /* hours since midnight - [0,23] */
  int tm_mday;    /* day of the month - [1,31] */
  int tm_mon;     /* months since January - [0,11] */
  int tm_year;    /* years since 1900 */
  int tm_wday;    /* days since Sunday - [0,6] */
  int tm_yday;    /* days since January 1 - [0,365] */
  int tm_isdst;   /* daylight savings time flag */
} tm;
extern 	tm  xTimeAndDate;
/*******************************************************************************/


int gmtime32(unsigned long timp, tm *ptm);

unsigned long makegmtime32(tm *tb);



#define _DAY_SEC           (24L * 60L * 60L)       /* secs in a day */
#define _YEAR_SEC          (365L * _DAY_SEC)     /* secs in a year */
#define _FOUR_YEAR_SEC     (1461L * _DAY_SEC)    /* secs in a 4 year interval */
#define _DEC_SEC           315532800L            /* secs in 1970-1979 */
#define _BASE_YEAR         70L                   /* 1970 is the base year */
#define _BASE_DOW          4L                    /* 01-01-70 was a Thursday */

#define _LEAP_YEAR_ADJUST  17L                   /* Leap years 1900 - 1970 */

#define _MAX_YEAR          138L                  /* 2038 is the max year */

/*
 * Macro to determine if a given year, expressed as the number of years since
 * 1900, is a leap year.
 */
#define _IS_LEAP_YEAR(y)        (((y % 4 == 0) && (y % 100 != 0)) || ((y + 1900) % 400 == 0))

/*
 * Number of leap years from 1970 up to, but not including, the specified year
 * (expressed as the number of years since 1900).
 */
#define _ELAPSED_LEAP_YEARS(y)  (((y - 1)/4) - ((y - 1)/100) + ((y + 299)/400) - _LEAP_YEAR_ADJUST)

const int _lpdays[]	= {-1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
const int _days[]	= {-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364};

tm  xTimeAndDate;

int gmtime32(unsigned long timp, tm *ptm){
	unsigned long	caltim;			/* = *timp; *//* calendar time to convert */
	int				islpyr = 0;     /* is-current-year-a-leap-year flag */
	int				tmptim;
	int*			mdays;          /* pointer to days or lpdays */
	tm*				ptb = ptm;
		memset( ptm, 0xff, sizeof(tm));
		caltim = timp;
		/*
		* Determine years since 1970. First, identify the four-year interval
		* since this makes handling leap-years easy (note that 2000 IS a
		* leap year and 2100 is out-of-range).
		*/
		tmptim = (int)(caltim /_FOUR_YEAR_SEC);
		caltim -= ((unsigned long)tmptim * _FOUR_YEAR_SEC);
		/*
		* Determine which year of the interval
		*/
		tmptim = (tmptim * 4) + 70;         /* 1970, 1974, 1978,...,etc. */
		if ( caltim >= _YEAR_SEC ) {
			tmptim++;                       /* 1971, 1975, 1979,...,etc. */
			caltim -= _YEAR_SEC;
			if ( caltim >= _YEAR_SEC ) {
				tmptim++;                   /* 1972, 1976, 1980,...,etc. */
				caltim -= _YEAR_SEC;
				/*
				* Note, it takes 366 days-worth of seconds to get past a leap
				* year.
				*/
				if ( caltim >= (_YEAR_SEC + _DAY_SEC) ) {
					tmptim++;           /* 1973, 1977, 1981,...,etc. */
					caltim -= (_YEAR_SEC + _DAY_SEC);
				}
				else {
					/*
					* In a leap year after all, set the flag.
					*/
					islpyr++;
				}
			}
		}
		/*
		* tmptim now holds the value for tm_year. caltim now holds the
		* number of elapsed seconds since the beginning of that year.
		*/
		ptb->tm_year = tmptim;
		/*
		* Determine days since January 1 (0 - 365). This is the tm_yday value.
		* Leave caltim with number of elapsed seconds in that day.
		*/
		ptb->tm_yday = (int)(caltim / _DAY_SEC);
		caltim -= (unsigned long)(ptb->tm_yday) * _DAY_SEC;
		/*
		* Determine months since January (0 - 11) and day of month (1 - 31)
		*/
		if (islpyr)	mdays = _lpdays;
		else		mdays = _days;
		for (tmptim = 1 ; mdays[tmptim] < ptb->tm_yday ; tmptim++);
		ptb->tm_mon = --tmptim;
		ptb->tm_mday = ptb->tm_yday - mdays[tmptim];
		/*
		* Determine days since Sunday (0 - 6)
		*/
		ptb->tm_wday = ((int)(timp / _DAY_SEC) + _BASE_DOW) % 7;
		/*
		*  Determine hours since midnight (0 - 23), minutes after the hour
		*  (0 - 59), and seconds after the minute (0 - 59).
		*/
		ptb->tm_hour = (int)(caltim / 3600);
		caltim -= (unsigned long)ptb->tm_hour * 3600L;
		ptb->tm_min = (int)(caltim / 60);
		ptb->tm_sec = (int)(caltim - (ptb->tm_min) * 60);
		ptb->tm_isdst = 0;
		return 0;
}

/*
 * ChkAdd evaluates to TRUE if dest = src1 + src2 has overflowed
 */
#define ChkAdd(dest, src1, src2)   ( ((src1 >= 0L) && (src2 >= 0L) && (dest < 0L)) || ((src1 < 0L) && (src2 < 0L) && (dest >= 0L)) )
/*
 * ChkMul evaluates to TRUE if dest = src1 * src2 has overflowed
 */
#define ChkMul(dest, src1, src2)   ( src1 ? (dest/src1 != src2) : 0 )

unsigned long makegmtime32(tm *tb){
	unsigned long tmptm1, tmptm2, tmptm3;
	tm tbtemp;
	long dstbias = 0;
	long timezone = 0;
		/*
		* First, make sure tm_year is reasonably close to being in range.
		*/
		if ( ((tmptm1 = tb->tm_year) < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR + 1) )
		goto err_mktime;
		/*
		* Adjust month value so it is in the range 0 - 11.  This is because
		* we don't know how many days are in months 12, 13, 14, etc.
		*/
		if ( (tb->tm_mon < 0) || (tb->tm_mon > 11) ) {
			/*
			* no danger of overflow because the range check above.
			*/
			tmptm1 += (tb->tm_mon / 12);

			if ( (tb->tm_mon %= 12) < 0 ) {
			tb->tm_mon += 12;
			tmptm1--;
		}
		/*
		* Make sure year count is still in range.
		*/
		if ( (tmptm1 < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR + 1) )
			goto err_mktime;
		}
		/***** HERE: tmptm1 holds number of elapsed years *****/
		/*
		* Calculate days elapsed minus one, in the given year, to the given
		* month. Check for leap year and adjust if necessary.
		*/
		tmptm2 = _days[tb->tm_mon];
		if ( !(tmptm1 & 3) && (tb->tm_mon > 1) ) tmptm2++;
		/*
		* Calculate elapsed days since base date (midnight, 1/1/70, UTC)
		*
		*
		* 365 days for each elapsed year since 1970, plus one more day for
		* each elapsed leap year. no danger of overflow because of the range
		* check (above) on tmptm1.
		*/
		tmptm3 = (tmptm1 - _BASE_YEAR) * 365L + ((tmptm1 - 1L) >> 2) - _LEAP_YEAR_ADJUST;
		/*
		* elapsed days to current month (still no possible overflow)
		*/
		tmptm3 += tmptm2;
		/*
		* elapsed days to current date. overflow is now possible.
		*/
		tmptm1 = tmptm3 + (tmptm2 = (unsigned long)(tb->tm_mday));
		if ( ChkAdd(tmptm1, tmptm3, tmptm2) ) goto err_mktime;
		/***** HERE: tmptm1 holds number of elapsed days *****/
		/*
		* Calculate elapsed hours since base date
		*/
		tmptm2 = tmptm1 * 24L;
		if ( ChkMul(tmptm2, tmptm1, 24L) ) goto err_mktime;
		tmptm1 = tmptm2 + (tmptm3 = (unsigned long)tb->tm_hour);
		if ( ChkAdd(tmptm1, tmptm2, tmptm3) ) goto err_mktime;
		/***** HERE: tmptm1 holds number of elapsed hours *****/
		/*
		* Calculate elapsed minutes since base date
		*/
		tmptm2 = tmptm1 * 60L;
		if ( ChkMul(tmptm2, tmptm1, 60L) ) goto err_mktime;
		tmptm1 = tmptm2 + (tmptm3 = (unsigned long)tb->tm_min);
		if ( ChkAdd(tmptm1, tmptm2, tmptm3) ) goto err_mktime;

		/***** HERE: tmptm1 holds number of elapsed minutes *****/

		/*
		* Calculate elapsed seconds since base date
		*/

		tmptm2 = tmptm1 * 60L;
		if ( ChkMul(tmptm2, tmptm1, 60L) )
		goto err_mktime;

		tmptm1 = tmptm2 + (tmptm3 = (unsigned long)tb->tm_sec);
		if ( ChkAdd(tmptm1, tmptm2, tmptm3) )
		goto err_mktime;

		/***** HERE: tmptm1 holds number of elapsed seconds *****/

		if ( gmtime32(tmptm1, &tbtemp) != 0 )
		goto err_mktime;

		/***** HERE: tmptm1 holds number of elapsed seconds, adjusted *****/
		/*****       for local time if requested                      *****/

		*tb = tbtemp;
		return (unsigned long)tmptm1;

		err_mktime:
		/*
		* All errors come to here
		*/

		return (unsigned long)(-1);
}