Tm* gmtime(long tim) { int d0, d1; long hms, day; static Tm xtime; /* * break initial number into days */ hms = tim % 86400L; day = tim / 86400L; if(hms < 0) { hms += 86400L; day -= 1; } /* * generate hours:minutes:seconds */ xtime.sec = hms % 60; d1 = hms / 60; xtime.min = d1 % 60; d1 /= 60; xtime.hour = d1; /* * day is the day number. * generate day of the week. * The addend is 4 mod 7 (1/1/1970 was Thursday) */ xtime.wday = (day + 7340036L) % 7; /* * year number */ if(day >= 0) for(d1 = 1970; day >= dysize(d1); d1++) day -= dysize(d1); else for (d1 = 1970; day < 0; d1--) day += dysize(d1-1); xtime.year = d1-1900; xtime.yday = d0 = day; /* * generate month */ if(dysize(d1) == 366) dmsize[1] = 29; for(d1 = 0; d0 >= dmsize[d1]; d1++) d0 -= dmsize[d1]; dmsize[1] = 28; xtime.mday = d0 + 1; xtime.mon = d1; strcpy(xtime.zone, "GMT"); return &xtime; }
static void kgmtime(long tim, Tm *ct) { int d0, d1; long hms, day; /* * break initial number into days */ hms = tim % 86400L; day = tim / 86400L; if(hms < 0) { hms += 86400L; day -= 1; } /* * generate hours:minutes:seconds */ ct->sec = hms % 60; d1 = hms / 60; ct->min = d1 % 60; d1 /= 60; ct->hour = d1; /* * day is the day number. * generate day of the week. * The addend is 4 mod 7 (1/1/1970 was Thursday) */ ct->wday = (day + 7340036L) % 7; /* * year number */ if(day >= 0) for(d1 = 70; day >= dysize(d1); d1++) day -= dysize(d1); else for (d1 = 70; day < 0; d1--) day += dysize(d1-1); ct->year = d1; ct->yday = d0 = day; /* * generate month */ if(dysize(d1) == 366) dmsize[1] = 29; for(d1 = 0; d0 >= dmsize[d1]; d1++) d0 -= dmsize[d1]; dmsize[1] = 28; ct->mday = d0 + 1; ct->mon = d1; }
int gtime() { register int i, year, month; int day, hour, mins, secs; struct tm *L; char x; ep=ap; while(*ep) ep++; sp=ap; while(sp<ep) { x = *sp; *sp++ = *--ep; *ep = x; } sp=ap; time(&timbuf); L=localtime(&timbuf); secs = gp(-1); if(*sp!='.') { mins=secs; secs=0; } else {sp++; mins = gp(-1); } hour = gp(-1); day = gp(L->tm_mday); month = gp(L->tm_mon+1); year = gp(L->tm_year); if(*sp) return(1); if( month<1 || month>12 || day<1 || day>31 || mins<0 || mins>59 || secs<0 || secs>59) return(1); if (hour==24) { hour=0; day++; } if (hour<0 || hour>23) return(1); timbuf = 0; year += 1900; for(i=1970; i<year; i++) timbuf += dysize(i); /* Leap year */ if (dysize(year)==366 && month >= 3) timbuf++; while(--month) timbuf += dmsize[month-1]; timbuf += day-1; timbuf = 24*timbuf + hour; timbuf = 60*timbuf + mins; timbuf = 60*timbuf + secs; return(0); }
/* * The argument is a 0-origin day number. * The value is the day number of the last * Sunday before or after the day. */ static sunday(Tm *t, int d) { if(d >= 58) d += dysize(t->year) - 365; return d - (d - t->yday + t->wday + 700) % 7; }
time_t dmktime (struct tws *tw) { int i, sec, min, hour, mday, mon, year; time_t result; if (tw->tw_clock != 0) return tw->tw_clock; if ((sec = tw->tw_sec) < 0 || sec > 61 || (min = tw->tw_min) < 0 || min > 59 || (hour = tw->tw_hour) < 0 || hour > 23 || (mday = tw->tw_mday) < 1 || mday > 31 || (mon = tw->tw_mon + 1) < 1 || mon > 12) return (tw->tw_clock = (time_t) -1); year = tw->tw_year; result = 0; if (year < 1970) year += 1900; if (year < 1970) year += 100; for (i = 1970; i < year; i++) result += dysize (i); if (dysize (year) == 366 && mon >= 3) result++; while (--mon) result += dmsize[mon - 1]; result += mday - 1; result = 24 * result + hour; result = 60 * result + min; result = 60 * result + sec; result -= 60 * tw->tw_zone; if (tw->tw_flags & TW_DST) result -= 60 * 60; return (tw->tw_clock = result); }
static time_t gtime ( struct tm *tm ) { register int i, sec, mins, hour, mday, mon, year; register time_t result; if ((sec = tm -> tm_sec) < 0 || sec > 59 || (mins = tm -> tm_min) < 0 || mins > 59 || (hour = tm -> tm_hour) < 0 || hour > 24 || (mday = tm -> tm_mday) < 1 || mday > 31 || (mon = tm -> tm_mon + 1) < 1 || mon > 12) return ((time_t) -1); if (hour == 24) { hour = 0; mday++; } year = YEAR (tm -> tm_year); result = 0L; for (i = 1970; i < year; i++) result += dysize (i); if (dysize (year) == 366 && mon >= 3) result++; while (--mon) result += dmsize[mon - 1]; result += mday - 1; result = 24 * result + hour; result = 60 * result + mins; result = 60 * result + sec; return result; }
static int32_t gtime(uint8_t *p) /* yMdhmsz */ { int32_t t; int i, y, M, d, h, m, s, tz; y=p[0]; M=p[1]; d=p[2]; h=p[3]; m=p[4]; s=p[5]; tz=p[6]; USED(tz); y += 1900; if (y < 1970) return 0; if (M < 1 || M > 12) return 0; if (d < 1 || d > dmsize[M-1]) if (!(M == 2 && d == 29 && dysize(y) == 366)) return 0; if (h > 23) return 0; if (m > 59) return 0; if (s > 59) return 0; t = 0; for(i=1970; i<y; i++) t += dysize(i); if (dysize(y)==366 && M >= 3) t++; while(--M) t += dmsize[M-1]; t += d-1; t = 24*t + h; t = 60*t + m; t = 60*t + s; return t; }
void tm_AstToUt(long *year, long *day, double *hour) { long numdays; (*hour) += 4.0; if (*hour >= 24.0) { (*hour) -= 24.0; (*day)++; numdays = dysize((int) *year); if (((*day > 365) && (numdays == 365)) || ((*day > 366) && (numdays == 366))) { *day=1; (*year)++; *year = *year > 99 ? *year - 100 : *year; } } }
long tm_DayMonToYrDay(long day, long mon, long year) { long yday; if (dysize((int) year) == 366) /* leap year */ if (mon > 2) day++; switch(mon) { case 1 : yday = day; break; case 2 : yday = day + 31; break; case 3 : yday = day + 59; break; case 4 : yday = day + 90; break; case 5 : yday = day + 120; break; case 6 : yday = day + 151; break; case 7 : yday = day + 181; break; case 8 : yday = day + 212; break; case 9 : yday = day + 243; break; case 10 : yday = day + 273; break; case 11 : yday = day + 304; break; case 12 : yday = day + 334; break; default : yday = 0; } return yday; }
extern long cnvdate(int mon, int mday, int year, int hour, int min, int sec) { int t, i; int daylbegin, daylend; int ly_correction; /* Leap Year Correction */ int dl_correction; /* Daylight Savings Time Correction */ long s; static int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; days[2] = 28; /* Verify Input Parameters. */ /* Set year. */ if( year < 0) { return(-1); } if( year < 100) { if (year < 70) year += 2000; else year += 1900; } if (year < 1970) { return(-1); } if( year>2099 ) { return(-1); } if (dysize(year) == 366) { leap_year = 1; days[2]++; } else leap_year = 0; /* * Set ly_correction = number of leap year days from 1/1/1970 to * 1/1/year. */ ly_correction = ((year-1969) / 4); /* Check Month */ if( (mon < 1) || (mon > 12)) { return(-1); } /* Check Day */ if ( (mday < 1) || (mday > days[mon]) ) { return(-1); } /* Check Time */ if( (hour<0) || (hour>23)) { return(-1); } if( (min<0) || (min>59)) { return(-1); } if( (sec<0) || (sec>59)) { return(-1); } /* Calculate Correction for Daylight Savings Time (U.S.) */ dayno = mday-1; for (t=0; t<mon;) dayno += days[t++]; s = (year-1970)*365L + ly_correction + dayno; day_of_week = (s + 4) % 7; i = 0; while (year < daytab[i].yrbgn) { /* fall through when in correct interval */ i++; if (i>DAYTABSIZE) return(-1); } daylbegin = daytab[i].daylb; daylend = daytab[i].dayle; daylbegin = sunday(daylbegin); daylend = sunday(daylend); if(daylight && (dayno>daylbegin || (dayno==daylbegin && hour>=2)) && (dayno<daylend || (dayno==daylend && hour<1))) dl_correction = -1*60*60; else dl_correction = 0; /* Calculate seconds since 00:00:00 1/1/1970. */ s = ( ( s*24 +hour)*60 +min)*60 + sec + dl_correction; return(s+timezone); }
/* * The argument is a 0-origin day number. * The value is the day number of the first * Sunday on or after the day. */ static sunday(struct tm *t, int d) { if (d >= 58) { d += dysize(t->tm_year) - 365; } return d - (d - t->tm_yday + t->tm_wday + 700) % 7; }
struct tm *gmtime(const time_t *tp) { static struct tm xtime; int d0, d1; long hms, day; int *ip; /* * break initial number into days */ hms = *tp % 86400; day = *tp / 86400; if (hms < 0) { hms += 86400; day -= 1; } ip = (int *) &xtime; /* * generate hours:minutes:seconds */ *ip++ = hms % 60; d1 = hms / 60; *ip++ = d1 % 60; d1 /= 60; *ip++ = d1; /* * day is the day number. * generate day of the week. * The addend is 4 mod 7 (1/1/1970 was Thursday) */ xtime.tm_wday = (day + 7340036) % 7; /* * year number */ if (day >= 0) { for (d1 = 70; day >= dysize(d1); d1++) { day -= dysize(d1); } } else { for (d1 = 70; day < 0; d1--) { day += dysize(d1 - 1); } } xtime.tm_year = d1; xtime.tm_yday = d0 = day; /* * generate month */ if (dysize(d1) == 366) { dmsize[1] = 29; } for (d1 = 0; d0 >= dmsize[d1]; d1++) { d0 -= dmsize[d1]; } dmsize[1] = 28; *ip++ = d0 + 1; *ip++ = d1; xtime.tm_isdst = 0; /* * return the result */ return &xtime; }
struct tm* gmtime_r(const time_t *timp, struct tm *result) { int d0, d1; long hms, day; time_t tim; tim = *timp; /* * break initial number into days */ hms = tim % 86400L; day = tim / 86400L; if(hms < 0) { hms += 86400L; day -= 1; } /* * generate hours:minutes:seconds */ result->tm_sec = hms % 60; d1 = hms / 60; result->tm_min = d1 % 60; d1 /= 60; result->tm_hour = d1; /* * day is the day number. * generate day of the week. * The addend is 4 mod 7 (1/1/1970 was Thursday) */ result->tm_wday = (day + 7340036L) % 7; /* * year number */ if(day >= 0) for(d1 = 70; day >= dysize(d1); d1++) day -= dysize(d1); else for (d1 = 70; day < 0; d1--) day += dysize(d1-1); result->tm_year = d1; result->tm_yday = d0 = day; /* * generate month */ if(dysize(d1) == 366) dmsize[1] = 29; for(d1 = 0; d0 >= dmsize[d1]; d1++) d0 -= dmsize[d1]; dmsize[1] = 28; result->tm_mday = d0 + 1; result->tm_mon = d1; result->tm_isdst = 0; return result; }
void tm_DayToMon(long day, long year, struct DateStruct *sdate) { long numdays; sdate->year = year; numdays = dysize((int) year); if (numdays == 365) /* normal year */ { if (day < 31) /* jan 0..30 */ { sdate->month = 1; sdate->day = day+1; } else if (day < 59) /* feb */ { sdate->month = 2; sdate->day = day-30; } else if (day < 90) /* mar */ { sdate->month = 3; sdate->day = day-58; } else if (day < 120) /* apr */ { sdate->month = 4; sdate->day = day-89; } else if (day < 151) /* may */ { sdate->month = 5; sdate->day = day-119; } else if (day < 181) /* jun */ { sdate->month = 6; sdate->day = day-150; } else if (day < 212) /* jul */ { sdate->month = 7; sdate->day = day-180; } else if (day < 243) /* aug */ { sdate->month = 8; sdate->day = day-211; } else if (day < 273) /* sep */ { sdate->month = 9; sdate->day = day-242; } else if (day < 304) /* oct */ { sdate->month = 10; sdate->day = day-272; } else if (day < 334) /* nov */ { sdate->month = 11; sdate->day = day-303; } else if (day < 365) /* dec */ { sdate->month = 12; sdate->day = day-333; } else { sdate->month = 0; sdate->day = 0; } } else /* leap year */ { if (day < 31) /* jan 0..30 */ { sdate->month = 1; sdate->day = day+1; } else if (day < 60) /* feb */ { sdate->month = 2; sdate->day = day-30; } else if (day < 91) /* mar */ { sdate->month = 3; sdate->day = day-59; } else if (day < 121) /* apr */ { sdate->month = 4; sdate->day = day-90; } else if (day < 152) /* may */ { sdate->month = 5; sdate->day = day-120; } else if (day < 182) /* jun */ { sdate->month = 6; sdate->day = day-151; } else if (day < 213) /* jul */ { sdate->month = 7; sdate->day = day-181; } else if (day < 244) /* aug */ { sdate->month = 8; sdate->day = day-212; } else if (day < 274) /* sep */ { sdate->month = 9; sdate->day = day-243; } else if (day < 305) /* oct */ { sdate->month = 10; sdate->day = day-273; } else if (day < 335) /* nov */ { sdate->month = 11; sdate->day = day-304; } else if (day < 366) /* dec */ { sdate->month = 12; sdate->day = day-334; } else { sdate->month = 0; sdate->day = 0; } } }
int main() { time_t xmas2002 = 1040786563ll; struct tm* tm_ptr; // Make sure stime() always fails. printf("stime: %d\n", stime(&xmas2002)); // Verify that tzname sets *something*. tzset(); printf("tzname[0] set: %d\n", strlen(tzname[0]) >= 3); printf("tzname[1] set: %d\n", strlen(tzname[1]) >= 3); // Verify gmtime() creates correct struct. tm_ptr = gmtime(&xmas2002); printf("sec: %d\n", tm_ptr->tm_sec); printf("min: %d\n", tm_ptr->tm_min); printf("hour: %d\n", tm_ptr->tm_hour); printf("day: %d\n", tm_ptr->tm_mday); printf("mon: %d\n", tm_ptr->tm_mon); printf("year: %d\n", tm_ptr->tm_year); printf("wday: %d\n", tm_ptr->tm_wday); printf("yday: %d\n", tm_ptr->tm_yday); printf("dst: %d\n", tm_ptr->tm_isdst); printf("off: %d\n", tm_ptr->tm_gmtoff); printf("zone: %s\n", tm_ptr->tm_zone); // Verify timegm() reverses gmtime. printf("timegm <-> gmtime: %d\n", timegm(tm_ptr) == xmas2002); // Verify gmtime_r() doesn't clobber static data. time_t t1 = 0; struct tm tm1; gmtime_r(&t1, &tm1); printf("old year: %d\n", tm_ptr->tm_year); printf("new year: %d\n", tm1.tm_year); gmtime(&xmas2002); printf("old year again: %d\n", tm_ptr->tm_year); // Verify localtime() picks up timezone data. time_t t2 = xmas2002 - 60 * 60 * 24 * 30 * 6; tm_ptr = localtime(&t2); time_t dst_diff = (tm_ptr->tm_isdst == 1) ? tm_ptr->tm_isdst * 60 * 60 : 0; printf("localtime timezone: %d\n", (_timezone + tm_ptr->tm_gmtoff == dst_diff)); // glibc needs printf("localtime daylight: %d\n", _daylight == tm_ptr->tm_isdst); // no prefix "_"s printf("localtime tzname: %d\n", (!strcmp(tzname[0], tm_ptr->tm_zone) || !strcmp(tzname[1], tm_ptr->tm_zone))); // Verify localtime() and mktime() reverse each other. printf("localtime <-> mktime: %d\n", mktime(localtime(&xmas2002)) == xmas2002); // Verify localtime_r() doesn't clobber static data. time_t t3 = 0; struct tm tm2; localtime_r(&t3, &tm2); printf("localtime_r(1): %d\n", tm2.tm_year != tm_ptr->tm_year); localtime(&xmas2002); printf("localtime_r(2): %d\n", tm2.tm_year != tm_ptr->tm_year); // Verify time() returns reasonable value (between 2011 and 2030). time_t t4 = 0; time(&t4); timespec ts; assert(clock_gettime(0, &ts) == 0); assert(abs(ts.tv_sec - t4) <= 2); printf("time: %d\n", t4 > 1309635200ll && t4 < 1893362400ll); // Verify difftime() calculates accurate time difference. time_t t5 = 1309635200ll; printf("difftime+: %lf\n", difftime(t5, xmas2002)); printf("difftime-: %lf\n", difftime(xmas2002, t5)); // Verify dysize() knows its leap years. printf("1854 days: %d\n", dysize(1854)); printf("2000 days: %d\n", dysize(2000)); printf("2001 days: %d\n", dysize(2001)); printf("2004 days: %d\n", dysize(2004)); // Verify asctime() formatting(). printf("asctime: %s", asctime(gmtime(&xmas2002))); // Verify asctime_r() doesn't clobber static data. time_t t6 = 1309635200ll; tm_ptr = gmtime(&xmas2002); char* formatted = asctime(tm_ptr); char buffer[32]; asctime_r(gmtime(&t6), buffer); printf("old asctime: %s", formatted); printf("new asctime_r: %s", buffer); asctime_r(tm_ptr, buffer); printf("old asctime again: %s", formatted); // Verify that clock() advances. time_t start_t = time(NULL); clock_t start = clock(); printf("clock(start): %d\n", start >= 0); while (clock() - start < 2 * CLOCKS_PER_SEC); // Poor man's sleep(). clock_t diff = time(NULL) - start_t; printf("clock(end): %d\n", diff >= 2 && diff < 30); // Verify that ctime_r(x, buf) is equivalent to asctime_r(localtime(x), buf). time_t t7 = time(0); char buffer2[30]; char buffer3[30]; printf("ctime: %d\n", strcmp(ctime_r(&t7, buffer2), asctime_r(localtime(&t7), buffer3))); return 0; }