home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c019 / 1.ddi / ARC521_C / DTIME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-01  |  8.8 KB  |  452 lines

  1. /* dtime.c - routines to do ``ARPA-style'' time structures
  2.  
  3. ver  date   who remarks
  4. --- ------- --- -------------------------------------------------------------
  5. 01B 15nov86 JP  Thouroughly hacked by Jef Poskanzer.
  6. 01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
  7.               of Marshall Rose.
  8.  
  9. */
  10.  
  11.  
  12. #include "tws.h"
  13. #include <stdio.h>
  14. #include <sys/types.h>
  15. #include <time.h>
  16. #ifdef  SYS5
  17. #include <string.h>
  18. #else SYS5
  19. #include <strings.h>
  20. #include <sys/timeb.h>
  21. #endif SYS5
  22.  
  23. #ifdef    SYS5
  24. extern int  daylight;
  25. extern long timezone;
  26. extern char *tzname[];
  27. #endif    SYS5
  28.  
  29. /*   */
  30.  
  31. #define    abs(a) ( a >= 0 ? a : -a )
  32.  
  33. char *tw_moty[] = {
  34.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  35.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
  36.  
  37. char *tw_dotw[] = {
  38.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL };
  39.  
  40. char *tw_ldotw[] = {
  41.     "Sunday", "Monday", "Tuesday", "Wednesday",
  42.     "Thursday", "Friday", "Saturday", NULL };
  43.  
  44. /*   */
  45.  
  46. static struct zone
  47.     {
  48.     char *std;
  49.     char *dst;
  50.     int shift;
  51.     }
  52.     zones[] = {
  53.     "GMT", "BST", 0,
  54.     "EST", "EDT", -5,
  55.     "CST", "CDT", -6,
  56.     "MST", NULL, -7,
  57.     "PST", "PDT", -8,
  58.     "A", NULL, -1,
  59.     "B", NULL, -2,
  60.     "C", NULL, -3,
  61.     "D", NULL, -4,
  62.     "E", NULL, -5,
  63.     "F", NULL, -6,
  64.     "G", NULL, -7,
  65.     "H", NULL, -8,
  66.     "I", NULL, -9,
  67.     "K", NULL, -10,
  68.     "L", NULL, -11,
  69.     "M", NULL, -12,
  70.     "N", NULL, 1,
  71. #ifndef    HUJI
  72.     "O", NULL, 2,
  73. #else    HUJI
  74.     "JST", "JDT", 2,
  75. #endif    HUJI
  76.     "P", NULL, 3,
  77.     "Q", NULL, 4,
  78.     "R", NULL, 5,
  79.     "S", NULL, 6,
  80.     "T", NULL, 7,
  81.     "U", NULL, 8,
  82.     "V", NULL, 9,
  83.     "W", NULL, 10,
  84.     "X", NULL, 11,
  85.     "Y", NULL, 12,
  86.     NULL };
  87.  
  88. #define CENTURY 19
  89.  
  90. long time( );
  91. struct tm *localtime( );
  92.  
  93. /*   */
  94.  
  95. char *dtimenow( )
  96.     {
  97.     long clock;
  98.  
  99.     (void) time( &clock );
  100.     return ( dtime( &clock ) );
  101.     }
  102.  
  103.  
  104. char *
  105. dctime( tw )
  106. struct tws *tw;
  107.     {
  108.     static char buffer[25];
  109.  
  110.     if ( tw == NULL )
  111.     return ( NULL );
  112.  
  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 );
  117.  
  118.     return ( buffer );
  119.     }
  120.  
  121. /*   */
  122.  
  123. struct tws *
  124. dtwstime( )
  125.     {
  126.     long clock;
  127.  
  128.     (void) time( &clock );
  129.     return ( dlocaltime( &clock ) );
  130.     }
  131.  
  132.  
  133. struct tws *
  134. dlocaltime( clock )
  135. long *clock;
  136.     {
  137.     register struct tm *tm;
  138. #ifndef SYS5
  139.     struct timeb tb;
  140. #endif not SYS5
  141.     static struct tws tw;
  142.  
  143.     if ( clock == NULL )
  144.     return ( NULL );
  145.     tw.tw_flags = TW_NULL;
  146.  
  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;
  158. #ifndef  SYS5
  159.     ftime( &tb );
  160.     tw.tw_zone = -tb.timezone;
  161. #else   SYS5
  162.     tzset( );
  163.     tw.tw_zone = -(timezone / 60);
  164. #endif  SYS5
  165.     tw.tw_flags &= ~TW_SDAY;
  166.     tw.tw_flags |= TW_SEXP;
  167.     tw.tw_clock = *clock;
  168.  
  169.     return ( &tw );
  170.     }
  171.  
  172.  
  173. struct tws *
  174. dgmtime( clock )
  175. long *clock;
  176.     {
  177.     register struct tm *tm;
  178.     static struct tws tw;
  179.  
  180.     if ( clock == NULL )
  181.     return ( NULL );
  182.     tw.tw_flags = TW_NULL;
  183.  
  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;
  195.     tw.tw_zone = 0;
  196.     tw.tw_flags &= ~TW_SDAY;
  197.     tw.tw_flags |= TW_SEXP;
  198.     tw.tw_clock = *clock;
  199.  
  200.     return( &tw );
  201.     }
  202.  
  203. /*   */
  204.  
  205. char *
  206. dasctime( tw, flags )
  207. struct tws *tw;
  208. int flags;
  209.     {
  210.     static char buffer[80], result[80];
  211.  
  212.     if ( tw == NULL )
  213.     return ( NULL );
  214.  
  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 ) );
  219.  
  220.     if ( (tw -> tw_flags & TW_SDAY) == TW_SEXP )
  221.     (void) sprintf( result, "%s, %s", tw_dotw[tw -> tw_wday], buffer );
  222.     else
  223.     if ( (tw -> tw_flags & TW_SDAY) == TW_SNIL )
  224.         (void) strcpy( result, buffer );
  225.     else
  226.         (void) sprintf( result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday] );
  227.  
  228.     return ( result );
  229.     }
  230.  
  231. /*   */
  232.  
  233. char *
  234. dtimezone( offset, flags )
  235. int offset, flags;
  236.     {
  237.     register int hours, mins;
  238.     register struct zone *z;
  239.     static char buffer[10];
  240.  
  241.     if ( offset < 0 )
  242.     {
  243.     mins = -((-offset) % 60);
  244.     hours = -((-offset) / 60);
  245.     }
  246.     else
  247.     {
  248.     mins = offset % 60;
  249.     hours = offset / 60;
  250.     }
  251.  
  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 );
  256.  
  257. #ifdef    DSTXXX
  258.     if ( flags & TW_DST )
  259.     hours += 1;
  260. #endif    DSTXXX
  261.     (void) sprintf( buffer, "%s%02d%02d",
  262.         offset < 0 ? "-" : "+", abs( hours ), abs( mins ) );
  263.     return ( buffer );
  264.     }
  265.  
  266. /*   */
  267.  
  268. void
  269. twscopy( tb, tw )
  270. struct tws *tb, *tw;
  271.     {
  272. #ifdef    notdef
  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;
  284. #else    not notdef
  285.     *tb = *tw;
  286. #endif    not notdef
  287.     }
  288.  
  289.  
  290. int
  291. twsort( tw1, tw2 )
  292. struct tws *tw1, *tw2;
  293.     {
  294.     register long c1, c2;
  295.  
  296.     (void) twclock( tw1 );
  297.     (void) twclock( tw2 );
  298.  
  299.     return ( (c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1
  300.         : c1 == c2 ? 0 : -1 );
  301.     }
  302.  
  303. /*   */
  304.  
  305.  
  306. /* Julian day number of the Unix* clock's origin, 01 Jan 1970. */
  307. #define JD1970 2440587L
  308.  
  309.  
  310. long
  311. twjuliandate( tw )
  312. struct tws *tw;
  313.     {
  314.     register int mday, mon, year;
  315.     register long a, b;
  316.     double jd;
  317.  
  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 )
  321.     return ( -1L );
  322.     if ( year < 100 )
  323.     year += CENTURY * 100;
  324.  
  325.     if ( mon == 1 || mon == 2 )
  326.     {
  327.     --year;
  328.     mon += 12;
  329.     }
  330.     if ( year < 1583 )
  331.     return ( -1L );
  332.     a = year / 100;
  333.     b = 2 - a + a / 4;
  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 );
  338.     }
  339.  
  340.  
  341. long
  342. twsubdayclock( tw )
  343. struct tws *tw;
  344.     {
  345.     register int sec, min, hour;
  346.     register long result;
  347.  
  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 )
  351.     return ( -1L );
  352.  
  353.     result = ( hour * 60 + min ) * 60 + sec;
  354.     result -= 60 * tw -> tw_zone;
  355.     if ( tw -> tw_flags & TW_DST )
  356.     result -= 60 * 60;
  357.  
  358.     return ( result );
  359.     }
  360.  
  361.  
  362. long
  363. twclock( tw )
  364. struct tws *tw;
  365.     {
  366.     register long jd, sdc, result;
  367.  
  368.     if ( tw -> tw_clock != 0L )
  369.     return ( tw -> tw_clock );
  370.  
  371.     if ( ( jd = twjuliandate( tw ) ) == -1L )
  372.     return ( tw -> tw_clock = -1L );
  373.     if ( ( sdc = twsubdayclock( tw ) ) == -1L )
  374.     return ( tw -> tw_clock = -1L );
  375.  
  376.     result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc;
  377.  
  378.     return ( tw -> tw_clock = result );
  379.     }
  380.  
  381. /*   */
  382.  
  383. /*** twsubtract - subtract tw2 from tw1, returning result in seconds
  384.  
  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
  389. about 66 years.
  390.  
  391. */
  392.  
  393. long
  394. twsubtract( tw1, tw2 )
  395. struct tws *tw1, *tw2;
  396.     {
  397.     register long jd1, jd2, sdc1, sdc2, result;
  398.  
  399.     if ( ( jd1 = twjuliandate( tw1 ) ) == -1L )
  400.     return ( 0L );
  401.     if ( ( sdc1 = twsubdayclock( tw1 ) ) == -1L )
  402.     return ( 0L );
  403.  
  404.     if ( ( jd2 = twjuliandate( tw2 ) ) == -1L )
  405.     return ( 0L );
  406.     if ( ( sdc2 = twsubdayclock( tw2 ) ) == -1L )
  407.     return ( 0L );
  408.     
  409.     result = ( jd1 - jd2 ) * 24 * 60 * 60 + ( sdc1 - sdc2 );
  410.  
  411.     return ( result );
  412.     }
  413.  
  414. /*   */
  415.  
  416. /*
  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.
  420.  */
  421.  
  422. set_dotw( tw )
  423. struct tws *tw;
  424.     {
  425.     register int month, day, year, century;
  426.  
  427.     month = tw -> tw_mon - 1;
  428.     day = tw -> tw_mday;
  429.     year = tw -> tw_year % 100;
  430.     century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : CENTURY;
  431.  
  432.     if ( month <= 0 )
  433.     {
  434.     month += 12;
  435.     if ( --year < 0 )
  436.         {
  437.         year += 100;
  438.         century--;
  439.         }
  440.     }
  441.  
  442.     tw -> tw_wday =
  443.     ((26 * month - 2) / 10 + day + year + year / 4
  444.         - 3 * century / 4 + 1) % 7;
  445.  
  446.     tw -> tw_flags &= ~TW_SDAY;
  447.     tw -> tw_flags |= TW_SIMP;
  448.     }
  449.  
  450.  
  451. /* * Unix is a virus from outer space. */
  452.