This is dtime.c in view mode; [Download] [Up]
/* dtime.c - routines to do ``ARPA-style'' time structures ver date who remarks --- ------- --- ------------------------------------------------------------- 01B 15nov86 JP Thouroughly hacked by Jef Poskanzer. 01A ??????? MTR Original version from the MH 6.5 distribution, courtesy of Marshall Rose. */ #include "tws.h" #include <stdio.h> #include <sys/types.h> #include <time.h> #ifdef SYS5 #include <string.h> #else SYS5 #include <strings.h> #include <sys/timeb.h> #endif SYS5 #ifdef SYS5 extern int daylight; extern long timezone; extern char *tzname[]; #endif SYS5 /* */ #define abs(a) ( a >= 0 ? a : -a ) char *tw_moty[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; char *tw_dotw[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL }; char *tw_ldotw[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", NULL }; /* */ static struct zone { char *std; char *dst; int shift; } zones[] = { "GMT", "BST", 0, "EST", "EDT", -5, "CST", "CDT", -6, "MST", NULL, -7, "PST", "PDT", -8, "A", NULL, -1, "B", NULL, -2, "C", NULL, -3, "D", NULL, -4, "E", NULL, -5, "F", NULL, -6, "G", NULL, -7, "H", NULL, -8, "I", NULL, -9, "K", NULL, -10, "L", NULL, -11, "M", NULL, -12, "N", NULL, 1, #ifndef HUJI "O", NULL, 2, #else HUJI "JST", "JDT", 2, #endif HUJI "P", NULL, 3, "Q", NULL, 4, "R", NULL, 5, "S", NULL, 6, "T", NULL, 7, "U", NULL, 8, "V", NULL, 9, "W", NULL, 10, "X", NULL, 11, "Y", NULL, 12, NULL }; #define CENTURY 19 long time( ); struct tm *localtime( ); /* */ char *dtimenow( ) { long clock; (void) time( &clock ); return ( dtime( &clock ) ); } char * dctime( tw ) struct tws *tw; { static char buffer[25]; if ( tw == NULL ) return ( NULL ); (void) sprintf( buffer, "%.3s %.3s %02d %02d:%02d:%02d %.4d\n", tw_dotw[tw -> tw_wday], tw_moty[tw -> tw_mon], tw -> tw_mday, tw -> tw_hour, tw -> tw_min, tw -> tw_sec, tw -> tw_year >= 100 ? tw -> tw_year : 1900 + tw -> tw_year ); return ( buffer ); } /* */ struct tws * dtwstime( ) { long clock; (void) time( &clock ); return ( dlocaltime( &clock ) ); } struct tws * dlocaltime( clock ) long *clock; { register struct tm *tm; #ifndef SYS5 struct timeb tb; #endif not SYS5 static struct tws tw; if ( clock == NULL ) return ( NULL ); tw.tw_flags = TW_NULL; tm = localtime( clock ); tw.tw_sec = tm -> tm_sec; tw.tw_min = tm -> tm_min; tw.tw_hour = tm -> tm_hour; tw.tw_mday = tm -> tm_mday; tw.tw_mon = tm -> tm_mon; tw.tw_year = tm -> tm_year; tw.tw_wday = tm -> tm_wday; tw.tw_yday = tm -> tm_yday; if ( tm -> tm_isdst ) tw.tw_flags |= TW_DST; #ifndef SYS5 ftime( &tb ); tw.tw_zone = -tb.timezone; #else SYS5 tzset( ); tw.tw_zone = -(timezone / 60); #endif SYS5 tw.tw_flags &= ~TW_SDAY; tw.tw_flags |= TW_SEXP; tw.tw_clock = *clock; return ( &tw ); } struct tws * dgmtime( clock ) long *clock; { register struct tm *tm; static struct tws tw; if ( clock == NULL ) return ( NULL ); tw.tw_flags = TW_NULL; tm = gmtime( clock ); tw.tw_sec = tm -> tm_sec; tw.tw_min = tm -> tm_min; tw.tw_hour = tm -> tm_hour; tw.tw_mday = tm -> tm_mday; tw.tw_mon = tm -> tm_mon; tw.tw_year = tm -> tm_year; tw.tw_wday = tm -> tm_wday; tw.tw_yday = tm -> tm_yday; if ( tm -> tm_isdst ) tw.tw_flags |= TW_DST; tw.tw_zone = 0; tw.tw_flags &= ~TW_SDAY; tw.tw_flags |= TW_SEXP; tw.tw_clock = *clock; return( &tw ); } /* */ char * dasctime( tw, flags ) struct tws *tw; int flags; { static char buffer[80], result[80]; if ( tw == NULL ) return ( NULL ); (void) sprintf( buffer, "%02d %s %02d %02d:%02d:%02d %s", tw -> tw_mday, tw_moty[tw -> tw_mon], tw -> tw_year, tw -> tw_hour, tw -> tw_min, tw -> tw_sec, dtimezone( tw -> tw_zone, tw -> tw_flags | flags ) ); if ( (tw -> tw_flags & TW_SDAY) == TW_SEXP ) (void) sprintf( result, "%s, %s", tw_dotw[tw -> tw_wday], buffer ); else if ( (tw -> tw_flags & TW_SDAY) == TW_SNIL ) (void) strcpy( result, buffer ); else (void) sprintf( result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday] ); return ( result ); } /* */ char * dtimezone( offset, flags ) int offset, flags; { register int hours, mins; register struct zone *z; static char buffer[10]; if ( offset < 0 ) { mins = -((-offset) % 60); hours = -((-offset) / 60); } else { mins = offset % 60; hours = offset / 60; } if ( !(flags & TW_ZONE) && mins == 0 ) for ( z = zones; z -> std; z++ ) if ( z -> shift == hours ) return ( z -> dst && (flags & TW_DST) ? z -> dst : z -> std ); #ifdef DSTXXX if ( flags & TW_DST ) hours += 1; #endif DSTXXX (void) sprintf( buffer, "%s%02d%02d", offset < 0 ? "-" : "+", abs( hours ), abs( mins ) ); return ( buffer ); } /* */ void twscopy( tb, tw ) struct tws *tb, *tw; { #ifdef notdef tb -> tw_sec = tw -> tw_sec; tb -> tw_min = tw -> tw_min; tb -> tw_hour = tw -> tw_hour; tb -> tw_mday = tw -> tw_mday; tb -> tw_mon = tw -> tw_mon; tb -> tw_year = tw -> tw_year; tb -> tw_wday = tw -> tw_wday; tb -> tw_yday = tw -> tw_yday; tb -> tw_zone = tw -> tw_zone; tb -> tw_clock = tw -> tw_clock; tb -> tw_flags = tw -> tw_flags; #else not notdef *tb = *tw; #endif not notdef } int twsort( tw1, tw2 ) struct tws *tw1, *tw2; { register long c1, c2; (void) twclock( tw1 ); (void) twclock( tw2 ); return ( (c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1 : c1 == c2 ? 0 : -1 ); } /* */ /* Julian day number of the Unix* clock's origin, 01 Jan 1970. */ #define JD1970 2440587L long twjuliandate( tw ) struct tws *tw; { register int mday, mon, year; register long a, b; double jd; if ( (mday = tw -> tw_mday) < 1 || mday > 31 || (mon = tw -> tw_mon + 1) < 1 || mon > 12 || (year = tw -> tw_year) < 1 || year > 10000 ) return ( -1L ); if ( year < 100 ) year += CENTURY * 100; if ( mon == 1 || mon == 2 ) { --year; mon += 12; } if ( year < 1583 ) return ( -1L ); a = year / 100; b = 2 - a + a / 4; b += (long) ( (double) year * 365.25 ); b += (long) ( 30.6001 * ( (double) mon + 1.0 ) ); jd = mday + b + 1720994.5; return ( (long) jd ); } long twsubdayclock( tw ) struct tws *tw; { register int sec, min, hour; register long result; if ( (sec = tw -> tw_sec) < 0 || sec > 59 || (min = tw -> tw_min) < 0 || min > 59 || (hour = tw -> tw_hour) < 0 || hour > 23 ) return ( -1L ); result = ( hour * 60 + min ) * 60 + sec; result -= 60 * tw -> tw_zone; if ( tw -> tw_flags & TW_DST ) result -= 60 * 60; return ( result ); } long twclock( tw ) struct tws *tw; { register long jd, sdc, result; if ( tw -> tw_clock != 0L ) return ( tw -> tw_clock ); if ( ( jd = twjuliandate( tw ) ) == -1L ) return ( tw -> tw_clock = -1L ); if ( ( sdc = twsubdayclock( tw ) ) == -1L ) return ( tw -> tw_clock = -1L ); result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc; return ( tw -> tw_clock = result ); } /* */ /*** twsubtract - subtract tw2 from tw1, returning result in seconds The point of this routine is that using twclock( tw1 ) - twclock( tw2 ) would limit you to dates after the Unix* Epoch ( 01 January 1970 ). This routine avoids that limit. However, because the result is represented by 32 bits, it is still limited to a span of two billion seconds, which is about 66 years. */ long twsubtract( tw1, tw2 ) struct tws *tw1, *tw2; { register long jd1, jd2, sdc1, sdc2, result; if ( ( jd1 = twjuliandate( tw1 ) ) == -1L ) return ( 0L ); if ( ( sdc1 = twsubdayclock( tw1 ) ) == -1L ) return ( 0L ); if ( ( jd2 = twjuliandate( tw2 ) ) == -1L ) return ( 0L ); if ( ( sdc2 = twsubdayclock( tw2 ) ) == -1L ) return ( 0L ); result = ( jd1 - jd2 ) * 24 * 60 * 60 + ( sdc1 - sdc2 ); return ( result ); } /* */ /* * Simple calculation of day of the week. Algorithm used is Zeller's * congruence. Currently, we assume if tw -> tw_year < 100 * then the century is CENTURY. */ set_dotw( tw ) struct tws *tw; { register int month, day, year, century; month = tw -> tw_mon - 1; day = tw -> tw_mday; year = tw -> tw_year % 100; century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : CENTURY; if ( month <= 0 ) { month += 12; if ( --year < 0 ) { year += 100; century--; } } tw -> tw_wday = ((26 * month - 2) / 10 + day + year + year / 4 - 3 * century / 4 + 1) % 7; tw -> tw_flags &= ~TW_SDAY; tw -> tw_flags |= TW_SIMP; } /* * Unix is a virus from outer space. */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.