home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / src / date.c < prev    next >
C/C++ Source or Header  |  1996-07-27  |  8KB  |  298 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(), *gmtime();
  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. char *tzoffset(long time)
  70. {
  71.   static char offset[SLEN];
  72.   struct tm tm = *gmtime(&time);
  73.   long utime = mktime(&tm);
  74.   sprintf(offset, "%+03d00", (time - utime) / 3600);
  75.   return offset;
  76. }
  77.  
  78. char *get_arpa_date()
  79. {
  80.     /** returns an ARPA standard date.  The format for the date
  81.         according to DARPA document RFC-822 is exemplified by:
  82.  
  83.                      Mon, 12 Aug 85 6:29:08 -0800
  84.  
  85.     **/
  86.  
  87.     static char buffer[SLEN];    /* static character buffer       */
  88.     struct tm the_time;        /* Time structure, see CTIME(3C) */
  89.     long       junk;        /* time in seconds....         */
  90.  
  91. #ifdef BSD
  92. # ifndef TZ_MINUTESWEST
  93.     junk = time((long *) 0);
  94. # else
  95.     struct  timeval  time_val;
  96.     struct  timezone time_zone;
  97.  
  98.     gettimeofday(&time_val, &time_zone);
  99.     junk = time_val.tv_sec;
  100. # endif
  101.  
  102. #else
  103.     junk = time((long *) 0);    /* this must be here for it to work! */
  104. #endif
  105.  
  106.     the_time = *localtime(&junk);
  107.  
  108.     sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
  109.       arpa_dayname[the_time.tm_wday],
  110.       the_time.tm_mday % 32,
  111.       arpa_monname[the_time.tm_mon],
  112.       the_time.tm_year % 100,
  113.       the_time.tm_hour % 24,
  114.       the_time.tm_min  % 61,
  115.       the_time.tm_sec  % 61,
  116.       tzoffset(junk));
  117.  
  118.     return( (char *) buffer);
  119. }
  120.  
  121. days_ahead(days, buffer)
  122. int days;
  123. char *buffer;
  124. {
  125.     /** return in buffer the date (Day, Mon Day, Year) of the date
  126.         'days' days after today.
  127.     **/
  128.  
  129.     struct tm *the_time;        /* Time structure, see CTIME(3C) */
  130.     long       junk;        /* time in seconds....         */
  131.  
  132.     junk = time((long *) 0);    /* this must be here for it to work! */
  133.     the_time = localtime(&junk);
  134.  
  135.     /* increment the day of the week */
  136.  
  137.     the_time->tm_wday = (the_time->tm_wday + days) % 7;
  138.  
  139.     /* the day of the month... */
  140.     the_time->tm_mday += days;
  141.  
  142.         while (the_time->tm_mday > days_in_month[the_time->tm_mon]) {
  143.           if (the_time->tm_mon == FEB && leapyear(the_time->tm_year)) {
  144.             if (the_time->tm_mday > DAYS_IN_LEAP_FEB) {
  145.               the_time->tm_mday -= DAYS_IN_LEAP_FEB;
  146.               the_time->tm_mon += 1;
  147.             }
  148.             else
  149.               break;            /* Is Feb 29, so leave */
  150.           }
  151.           else {
  152.             the_time->tm_mday -= days_in_month[the_time->tm_mon];
  153.             the_time->tm_mon += 1;
  154.           }
  155.  
  156.           /* check the month of the year */
  157.           if (the_time->tm_mon > MONTHS_IN_YEAR) {
  158.             the_time->tm_mon -= (MONTHS_IN_YEAR + 1);
  159.             the_time->tm_year += 1;
  160.           }
  161.         }
  162.  
  163.         /* now, finally, build the actual date string */
  164.  
  165.     sprintf(buffer, "%s, %d %s %d",
  166.       arpa_dayname[the_time->tm_wday],
  167.       the_time->tm_mday % 32,
  168.       arpa_monname[the_time->tm_mon],
  169.       the_time->tm_year % 100);
  170. }
  171.  
  172. fix_date(entry)
  173. struct header_rec *entry;
  174. {
  175.     /** This routine will 'fix' the date entry for the specified
  176.         message.  This consists of 1) adjusting the year to 0-99
  177.         and 2) altering time from HH:MM:SS to HH:MM am|pm **/
  178.  
  179.     if (atoi(entry->year) > 99)
  180.       sprintf(entry->year,"%d", atoi(entry->year) - 1900);
  181.  
  182.     fix_time(entry->time);
  183. }
  184.  
  185. fix_time(timestring)
  186. char *timestring;
  187. {
  188.     /** Timestring in format HH:MM:SS (24 hour time).  This routine
  189.         will fix it to display as: HH:MM [am|pm] **/
  190.  
  191.     int hour, minute;
  192.  
  193.     sscanf(timestring, "%d:%d", &hour, &minute);
  194.  
  195.     if (hour < 1 || hour == 24)
  196.       sprintf(timestring, "12:%02d am", minute);
  197.     else if (hour < 12)
  198.       sprintf(timestring, "%d:%02d am", hour, minute);
  199.     else if (hour == 12)
  200.       sprintf(timestring, "12:%02d pm", minute);
  201.     else if (hour < 24)
  202.       sprintf(timestring, "%d:%02d pm", hour-12, minute);
  203. }
  204.  
  205. int
  206. compare_parsed_dates(rec1, rec2)
  207. struct date_rec rec1, rec2;
  208. {
  209.     /** This function is very similar to the compare_dates
  210.         function but assumes that the two record structures
  211.         are already parsed and stored in "date_rec" format.
  212.     **/
  213.  
  214.     if (rec1.year != rec2.year)
  215.       return( rec1.year - rec2.year );
  216.  
  217.     if (rec1.month != rec2.month)
  218.       return( rec1.month - rec2.month );
  219.  
  220.     if (rec1.day != rec2.day)
  221.       return( rec1.day - rec2.day );
  222.  
  223.     if (rec1.hour != rec2.hour)
  224.       return( rec1.hour - rec2.hour );
  225.  
  226.     return( rec1.minute - rec2.minute );        /* ignore seconds... */
  227. }
  228.  
  229. int
  230. month_number(name)
  231. char *name;
  232. {
  233.     /** return the month number given the month name... **/
  234.  
  235.     char ch;
  236.  
  237.     switch (tolower(name[0])) {
  238.      case 'a' : if ((ch = tolower(name[1])) == 'p')    return(APRIL);
  239.             else if (ch == 'u') return(AUGUST);
  240.             else return(-1);    /* error! */
  241.  
  242.      case 'd' : return(DECEMBER);
  243.      case 'f' : return(FEBRUARY);
  244.      case 'j' : if ((ch = tolower(name[1])) == 'a') return(JANUARY);
  245.             else if (ch == 'u') {
  246.                   if ((ch = tolower(name[2])) == 'n') return(JUNE);
  247.               else if (ch == 'l') return(JULY);
  248.               else return(-1);        /* error! */
  249.                 }
  250.             else return(-1);        /* error */
  251.      case 'm' : if ((ch = tolower(name[2])) == 'r') return(MARCH);
  252.             else if (ch == 'y') return(MAY);
  253.             else return(-1);        /* error! */
  254.      case 'n' : return(NOVEMBER);
  255.      case 'o' : return(OCTOBER);
  256.      case 's' : return(SEPTEMBER);
  257.      default  : return(-1);
  258.     }
  259. }
  260.  
  261. #ifdef SITE_HIDING
  262.  
  263. char *get_ctime_date()
  264. {
  265.     /** returns a ctime() format date, but a few minutes in the
  266.         past...(more cunningness to implement hidden sites) **/
  267.  
  268.     static char buffer[SLEN];    /* static character buffer       */
  269.     struct tm *the_time;        /* Time structure, see CTIME(3C) */
  270.     long       junk;        /* time in seconds....         */
  271.  
  272. #ifdef BSD
  273.     struct  timeval  time_val;
  274.     struct  timezone time_zone;
  275. #endif
  276.  
  277. #ifdef BSD
  278.     gettimeofday(&time_val, &time_zone);
  279.     junk = time_val.tv_sec;
  280. #else
  281.     junk = time((long *) 0);    /* this must be here for it to work! */
  282. #endif
  283.     the_time = localtime(&junk);
  284.  
  285.     sprintf(buffer, "%s %s %d %02d:%02d:%02d %d",
  286.       arpa_dayname[the_time->tm_wday],
  287.       arpa_monname[the_time->tm_mon],
  288.       the_time->tm_mday % 32,
  289.       min(the_time->tm_hour % 24, (rand() % 24)),
  290.       min(abs(the_time->tm_min  % 61 - (rand() % 60)), (rand() % 60)),
  291.       min(abs(the_time->tm_sec  % 61 - (rand() % 60)), (rand() % 60)),
  292.       the_time->tm_year % 100 + 1900);
  293.  
  294.     return( (char *) buffer);
  295. }
  296.  
  297. #endif
  298.