home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / com / utils / elm / sources / date.c < prev    next >
C/C++ Source or Header  |  1992-10-04  |  8KB  |  312 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: date.c,v 4.1 90/04/28 22:42:41 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    date.c,v $
  17.  * Revision 4.1  90/04/28  22:42:41  syd
  18.  * checkin of Elm 2.3 as of Release PL0
  19.  *
  20.  *
  21.  ******************************************************************************/
  22.  
  23. /** return the current date and time in a readable format! **/
  24. /** also returns an ARPA RFC-822 format date...            **/
  25.  
  26.  
  27. #include "headers.h"
  28.  
  29. #ifdef I_TIME
  30. #  include <time.h>
  31. #endif
  32. #ifdef I_SYSTIME
  33. #  include <sys/time.h>
  34. #endif
  35. #ifdef BSD
  36. #  include <sys/types.h>
  37. #  include <sys/timeb.h>
  38. #endif
  39.  
  40. #include <ctype.h>
  41.  
  42. #ifndef    _POSIX_SOURCE
  43. extern struct tm *localtime();
  44. extern time_t      time();
  45. #endif
  46.  
  47. #ifdef BSD
  48. #undef toupper
  49. #undef tolower
  50. #endif
  51.  
  52. #define MONTHS_IN_YEAR    11    /* 0-11 equals 12 months! */
  53. #define FEB         1    /* 0 = January           */
  54. #define DAYS_IN_LEAP_FEB 29    /* leap year only       */
  55.  
  56. #define ampm(n)        (n > 12? n - 12 : n)
  57. #define am_or_pm(n)    (n > 11? (n > 23? "am" : "pm") : "am")
  58. #define leapyear(year)    ((year % 4 == 0) && (year % 100 != 0))
  59.  
  60. char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
  61.           "Fri", "Sat", "" };
  62.  
  63. char *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  64.           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
  65.  
  66. int  days_in_month[] = { 31,    28,    31,    30,    31,     30,
  67.           31,     31,    30,   31,    30,     31,  -1};
  68.  
  69. #ifdef BSD
  70.   char *timezone();
  71. #else
  72. #ifndef OS2
  73.   extern char *tzname[];
  74. #endif
  75. #endif
  76.  
  77. char *get_arpa_date()
  78. {
  79.     /** returns an ARPA standard date.  The format for the date
  80.         according to DARPA document RFC-822 is exemplified by;
  81.  
  82.                      Mon, 12 Aug 85 6:29:08 MST
  83.  
  84.     **/
  85.  
  86.     static char buffer[SLEN];    /* static character buffer       */
  87.     struct tm *the_time;        /* Time structure, see CTIME(3C) */
  88.     long       junk;        /* time in seconds....         */
  89.  
  90. #ifdef BSD
  91. # ifndef TZ_MINUTESWEST
  92.     struct timeb    loc_time;
  93.  
  94.     junk = time((long *) 0);
  95.     ftime(&loc_time);
  96. # else
  97.     struct  timeval  time_val;
  98.     struct  timezone time_zone;
  99.  
  100.     gettimeofday(&time_val, &time_zone);
  101.     junk = time_val.tv_sec;
  102. # endif
  103.  
  104. #else
  105.     junk = time((long *) 0);    /* this must be here for it to work! */
  106. #endif
  107.  
  108.     the_time = localtime(&junk);
  109.  
  110.     sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
  111.       arpa_dayname[the_time->tm_wday],
  112.       the_time->tm_mday % 32,
  113.       arpa_monname[the_time->tm_mon],
  114.       the_time->tm_year % 100,
  115.       the_time->tm_hour % 24,
  116.       the_time->tm_min  % 61,
  117.       the_time->tm_sec  % 61,
  118. #ifdef BSD
  119. #ifdef TZ_MINUTESWEST
  120. # ifdef GOULD_NP1
  121.       the_time->tm_zone);
  122. # else
  123.       timezone(time_zone.tz_minuteswest, the_time->tm_isdst));
  124. # endif
  125. #else
  126.       timezone(loc_time.timezone, the_time->tm_isdst));
  127. #endif
  128. #else
  129.       tzname[the_time->tm_isdst]);
  130. #endif
  131.  
  132.     return( (char *) buffer);
  133. }
  134.  
  135. days_ahead(days, buffer)
  136. int days;
  137. char *buffer;
  138. {
  139.     /** return in buffer the date (Day, Mon Day, Year) of the date
  140.         'days' days after today.
  141.     **/
  142.  
  143.     struct tm *the_time;        /* Time structure, see CTIME(3C) */
  144.     long       junk;        /* time in seconds....         */
  145.  
  146.     junk = time((long *) 0);    /* this must be here for it to work! */
  147.     the_time = localtime(&junk);
  148.  
  149.     /* increment the day of the week */
  150.  
  151.     the_time->tm_wday = (the_time->tm_wday + days) % 7;
  152.  
  153.     /* the day of the month... */
  154.     the_time->tm_mday += days;
  155.  
  156.         while (the_time->tm_mday > days_in_month[the_time->tm_mon]) {
  157.           if (the_time->tm_mon == FEB && leapyear(the_time->tm_year)) {
  158.             if (the_time->tm_mday > DAYS_IN_LEAP_FEB) {
  159.               the_time->tm_mday -= DAYS_IN_LEAP_FEB;
  160.               the_time->tm_mon += 1;
  161.             }
  162.             else
  163.               break;            /* Is Feb 29, so leave */
  164.           }
  165.           else {
  166.             the_time->tm_mday -= days_in_month[the_time->tm_mon];
  167.             the_time->tm_mon += 1;
  168.           }
  169.  
  170.           /* check the month of the year */
  171.           if (the_time->tm_mon > MONTHS_IN_YEAR) {
  172.             the_time->tm_mon -= (MONTHS_IN_YEAR + 1);
  173.             the_time->tm_year += 1;
  174.           }
  175.         }
  176.  
  177.         /* now, finally, build the actual date string */
  178.  
  179.     sprintf(buffer, "%s, %d %s %d",
  180.       arpa_dayname[the_time->tm_wday],
  181.       the_time->tm_mday % 32,
  182.       arpa_monname[the_time->tm_mon],
  183.       the_time->tm_year % 100);
  184. }
  185.  
  186. fix_date(entry)
  187. struct header_rec *entry;
  188. {
  189.     /** This routine will 'fix' the date entry for the specified
  190.         message.  This consists of 1) adjusting the year to 0-99
  191.         and 2) altering time from HH:MM:SS to HH:MM am|pm **/
  192.  
  193.     if (atoi(entry->year) > 99)
  194.       sprintf(entry->year,"%d", atoi(entry->year) - 1900);
  195.  
  196.     fix_time(entry->time);
  197. }
  198.  
  199. fix_time(timestring)
  200. char *timestring;
  201. {
  202.     /** Timestring in format HH:MM:SS (24 hour time).  This routine
  203.         will fix it to display as: HH:MM [am|pm] **/
  204.  
  205.     int hour, minute;
  206.  
  207.     sscanf(timestring, "%d:%d", &hour, &minute);
  208.  
  209.     if (hour < 1 || hour == 24)
  210.       sprintf(timestring, "12:%02d am", minute);
  211.     else if (hour < 12)
  212.       sprintf(timestring, "%d:%02d am", hour, minute);
  213.     else if (hour == 12)
  214.       sprintf(timestring, "12:%02d pm", minute);
  215.     else if (hour < 24)
  216.       sprintf(timestring, "%d:%02d pm", hour-12, minute);
  217. }
  218.  
  219. int
  220. compare_parsed_dates(rec1, rec2)
  221. struct date_rec rec1, rec2;
  222. {
  223.     /** This function is very similar to the compare_dates
  224.         function but assumes that the two record structures
  225.         are already parsed and stored in "date_rec" format.
  226.     **/
  227.  
  228.     if (rec1.year != rec2.year)
  229.       return( rec1.year - rec2.year );
  230.  
  231.     if (rec1.month != rec2.month)
  232.       return( rec1.month - rec2.month );
  233.  
  234.     if (rec1.day != rec2.day)
  235.       return( rec1.day - rec2.day );
  236.  
  237.     if (rec1.hour != rec2.hour)
  238.       return( rec1.hour - rec2.hour );
  239.  
  240.     return( rec1.minute - rec2.minute );        /* ignore seconds... */
  241. }
  242.  
  243. int
  244. month_number(name)
  245. char *name;
  246. {
  247.     /** return the month number given the month name... **/
  248.  
  249.     char ch;
  250.  
  251.     switch (tolower(name[0])) {
  252.      case 'a' : if ((ch = tolower(name[1])) == 'p')    return(APRIL);
  253.             else if (ch == 'u') return(AUGUST);
  254.             else return(-1);    /* error! */
  255.  
  256.      case 'd' : return(DECEMBER);
  257.      case 'f' : return(FEBRUARY);
  258.      case 'j' : if ((ch = tolower(name[1])) == 'a') return(JANUARY);
  259.             else if (ch == 'u') {
  260.                   if ((ch = tolower(name[2])) == 'n') return(JUNE);
  261.               else if (ch == 'l') return(JULY);
  262.               else return(-1);        /* error! */
  263.                 }
  264.             else return(-1);        /* error */
  265.      case 'm' : if ((ch = tolower(name[2])) == 'r') return(MARCH);
  266.             else if (ch == 'y') return(MAY);
  267.             else return(-1);        /* error! */
  268.      case 'n' : return(NOVEMBER);
  269.      case 'o' : return(OCTOBER);
  270.      case 's' : return(SEPTEMBER);
  271.      default  : return(-1);
  272.     }
  273. }
  274.  
  275. #ifdef SITE_HIDING
  276.  
  277. char *get_ctime_date()
  278. {
  279.     /** returns a ctime() format date, but a few minutes in the
  280.         past...(more cunningness to implement hidden sites) **/
  281.  
  282.     static char buffer[SLEN];    /* static character buffer       */
  283.     struct tm *the_time;        /* Time structure, see CTIME(3C) */
  284.     long       junk;        /* time in seconds....         */
  285.  
  286. #ifdef BSD
  287.     struct  timeval  time_val;
  288.     struct  timezone time_zone;
  289. #endif
  290.  
  291. #ifdef BSD
  292.     gettimeofday(&time_val, &time_zone);
  293.     junk = time_val.tv_sec;
  294. #else
  295.     junk = time((long *) 0);    /* this must be here for it to work! */
  296. #endif
  297.     the_time = localtime(&junk);
  298.  
  299.     sprintf(buffer, "%s %s %d %02d:%02d:%02d %d",
  300.       arpa_dayname[the_time->tm_wday],
  301.       arpa_monname[the_time->tm_mon],
  302.       the_time->tm_mday % 32,
  303.       min(the_time->tm_hour % 24, (rand() % 24)),
  304.       min(abs(the_time->tm_min  % 61 - (rand() % 60)), (rand() % 60)),
  305.       min(abs(the_time->tm_sec  % 61 - (rand() % 60)), (rand() % 60)),
  306.       the_time->tm_year % 100 + 1900);
  307.  
  308.     return( (char *) buffer);
  309. }
  310.  
  311. #endif
  312.