1 /* dtime.c - routines to do ``ARPA-style'' time structures
4 --- ------- --- -------------------------------------------------------------
5 01B 15nov86 JP Thouroughly hacked by Jef Poskanzer.
6 01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
14 #include <sys/types.h>
20 #include <sys/timeb.h>
26 extern char *tzname[];
31 #define abs(a) ( a >= 0 ? a : -a )
34 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
35 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
38 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL };
41 "Sunday", "Monday", "Tuesday", "Wednesday",
42 "Thursday", "Friday", "Saturday", NULL };
91 struct tm *localtime( );
99 (void) time( &clock );
100 return ( dtime( &clock ) );
108 static char buffer[25];
113 (void) sprintf( buffer, "%.3s %.3s %02d %02d:%02d:%02d %.4d\n",
114 tw_dotw[tw -> tw_wday], tw_moty[tw -> tw_mon], tw -> tw_mday,
115 tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
116 tw -> tw_year >= 100 ? tw -> tw_year : 1900 + tw -> tw_year );
128 (void) time( &clock );
129 return ( dlocaltime( &clock ) );
137 register struct tm *tm;
141 static struct tws tw;
145 tw.tw_flags = TW_NULL;
147 tm = localtime( clock );
148 tw.tw_sec = tm -> tm_sec;
149 tw.tw_min = tm -> tm_min;
150 tw.tw_hour = tm -> tm_hour;
151 tw.tw_mday = tm -> tm_mday;
152 tw.tw_mon = tm -> tm_mon;
153 tw.tw_year = tm -> tm_year;
154 tw.tw_wday = tm -> tm_wday;
155 tw.tw_yday = tm -> tm_yday;
156 if ( tm -> tm_isdst )
157 tw.tw_flags |= TW_DST;
160 tw.tw_zone = -tb.timezone;
163 tw.tw_zone = -(timezone / 60);
165 tw.tw_flags &= ~TW_SDAY;
166 tw.tw_flags |= TW_SEXP;
167 tw.tw_clock = *clock;
177 register struct tm *tm;
178 static struct tws tw;
182 tw.tw_flags = TW_NULL;
184 tm = gmtime( clock );
185 tw.tw_sec = tm -> tm_sec;
186 tw.tw_min = tm -> tm_min;
187 tw.tw_hour = tm -> tm_hour;
188 tw.tw_mday = tm -> tm_mday;
189 tw.tw_mon = tm -> tm_mon;
190 tw.tw_year = tm -> tm_year;
191 tw.tw_wday = tm -> tm_wday;
192 tw.tw_yday = tm -> tm_yday;
193 if ( tm -> tm_isdst )
194 tw.tw_flags |= TW_DST;
196 tw.tw_flags &= ~TW_SDAY;
197 tw.tw_flags |= TW_SEXP;
198 tw.tw_clock = *clock;
206 dasctime( tw, flags )
210 static char buffer[80], result[80];
215 (void) sprintf( buffer, "%02d %s %02d %02d:%02d:%02d %s",
216 tw -> tw_mday, tw_moty[tw -> tw_mon], tw -> tw_year,
217 tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
218 dtimezone( tw -> tw_zone, tw -> tw_flags | flags ) );
220 if ( (tw -> tw_flags & TW_SDAY) == TW_SEXP )
221 (void) sprintf( result, "%s, %s", tw_dotw[tw -> tw_wday], buffer );
223 if ( (tw -> tw_flags & TW_SDAY) == TW_SNIL )
224 (void) strcpy( result, buffer );
226 (void) sprintf( result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday] );
234 dtimezone( offset, flags )
237 register int hours, mins;
238 register struct zone *z;
239 static char buffer[10];
243 mins = -((-offset) % 60);
244 hours = -((-offset) / 60);
252 if ( !(flags & TW_ZONE) && mins == 0 )
253 for ( z = zones; z -> std; z++ )
254 if ( z -> shift == hours )
255 return ( z -> dst && (flags & TW_DST) ? z -> dst : z -> std );
258 if ( flags & TW_DST )
261 (void) sprintf( buffer, "%s%02d%02d",
262 offset < 0 ? "-" : "+", abs( hours ), abs( mins ) );
273 tb -> tw_sec = tw -> tw_sec;
274 tb -> tw_min = tw -> tw_min;
275 tb -> tw_hour = tw -> tw_hour;
276 tb -> tw_mday = tw -> tw_mday;
277 tb -> tw_mon = tw -> tw_mon;
278 tb -> tw_year = tw -> tw_year;
279 tb -> tw_wday = tw -> tw_wday;
280 tb -> tw_yday = tw -> tw_yday;
281 tb -> tw_zone = tw -> tw_zone;
282 tb -> tw_clock = tw -> tw_clock;
283 tb -> tw_flags = tw -> tw_flags;
292 struct tws *tw1, *tw2;
294 register long c1, c2;
296 (void) twclock( tw1 );
297 (void) twclock( tw2 );
299 return ( (c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1
300 : c1 == c2 ? 0 : -1 );
306 /* Julian day number of the Unix clock's origin, 01 Jan 1970. */
307 #define JD1970 2440587L
314 register int mday, mon, year;
318 if ( (mday = tw -> tw_mday) < 1 || mday > 31 ||
319 (mon = tw -> tw_mon + 1) < 1 || mon > 12 ||
320 (year = tw -> tw_year) < 1 || year > 10000 )
323 year += CENTURY * 100;
325 if ( mon == 1 || mon == 2 )
334 b += (long) ( (double) year * 365.25 );
335 b += (long) ( 30.6001 * ( (double) mon + 1.0 ) );
336 jd = mday + b + 1720994.5;
337 return ( (long) jd );
345 register int i, sec, min, hour;
346 register long result;
348 if ( (sec = tw -> tw_sec) < 0 || sec > 59 ||
349 (min = tw -> tw_min) < 0 || min > 59 ||
350 (hour = tw -> tw_hour) < 0 || hour > 23 )
353 result = ( hour * 60 + min ) * 60 + sec;
354 result -= 60 * tw -> tw_zone;
355 if ( tw -> tw_flags & TW_DST )
366 register long jd, sdc, result;
368 if ( tw -> tw_clock != 0L )
369 return ( tw -> tw_clock );
371 if ( ( jd = twjuliandate( tw ) ) == -1L )
372 return ( tw -> tw_clock = -1L );
373 if ( ( sdc = twsubdayclock( tw ) ) == -1L )
374 return ( tw -> tw_clock = -1L );
376 result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc;
378 return ( tw -> tw_clock = result );
383 /*** twsubtract - subtract tw2 from tw1, returning result in seconds
385 The point of this routine is that using twclock( tw1 ) - twclock( tw2 )
386 would limit you to dates after the Unix Epoch ( 01 January 1970 ). This
387 routine avoids that limit. However, because the result is represented
388 by 32 bits, it is still limited to a span of two billion seconds, which is
394 twsubtract( tw1, tw2 )
395 struct tws *tw1, *tw2;
397 register long jd1, jd2, sdc1, sdc2, result;
399 if ( ( jd1 = twjuliandate( tw1 ) ) == -1L )
401 if ( ( sdc1 = twsubdayclock( tw1 ) ) == -1L )
404 if ( ( jd2 = twjuliandate( tw2 ) ) == -1L )
406 if ( ( sdc2 = twsubdayclock( tw2 ) ) == -1L )
409 result = ( jd1 - jd2 ) * 24 * 60 * 60 + ( sdc1 - sdc2 );
417 * Simple calculation of day of the week. Algorithm used is Zeller's
418 * congruence. Currently, we assume if tw -> tw_year < 100
419 * then the century is CENTURY.
425 register int month, day, year, century;
427 month = tw -> tw_mon - 1;
429 year = tw -> tw_year % 100;
430 century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : CENTURY;
443 ((26 * month - 2) / 10 + day + year + year / 4
444 - 3 * century / 4 + 1) % 7;
446 tw -> tw_flags &= ~TW_SDAY;
447 tw -> tw_flags |= TW_SIMP;