home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume11 / mush5.7 / part02 / dates.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-09-16  |  5.9 KB  |  216 lines

  1. /* @(#)dates.c    1.1    (c) copyright 10/15/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. char *day_names[] = {
  6.     "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"
  7. };
  8. char *month_names[] = {     /* imported in pick.c */
  9.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  10.     "July", "Aug", "Sep", "Oct", "Nov", "Dec"
  11. };
  12.  
  13. /* Time() returns a string according to criteria:
  14.  *   if "now" is 0, then the current time is gotten and used.
  15.  *       else, use the time described by now
  16.  *   opts points to a string of args which is parsed until an unknown
  17.  *       arg is found and opts will point to that upon return.
  18.  *   valid args are T (time of day), D (day of week), M (month), Y (year),
  19.  *       N (number of day in month -- couldn't think of a better letter).
  20.  */
  21. char *
  22. Time(opts, now)
  23. register char *opts;
  24. long now;
  25. {
  26.     static char time_buf[30];
  27.     struct tm       *T;
  28.     register char *p = time_buf;
  29.     long      x;
  30.  
  31.     if (!opts)
  32.     return NULL;
  33.     if (now)
  34.     x = now;
  35.     else
  36.     (void) time(&x);
  37.     T = localtime(&x);
  38.     for (;; opts++) {
  39.     switch(*opts) {
  40.         case 'T': (void) sprintf(p, "%d:%02d", (T->tm_hour) ?
  41.               ((T->tm_hour <= 12) ? T->tm_hour : T->tm_hour - 12) : 12,
  42.               T->tm_min);
  43.         when 'D': (void) strcpy(p, day_names[T->tm_wday]);
  44.         when 'M': (void) strcpy(p, month_names[T->tm_mon]);
  45.         when 'Y': (void) sprintf(p, "%d", T->tm_year);
  46.         when 'N': (void) sprintf(p, "%d", T->tm_mday);
  47.         otherwise: *--p = 0; return time_buf;
  48.     }
  49.     p += strlen(p);
  50.     *p++ = ' ';
  51.     }
  52. }
  53.  
  54. /* find the date of a message and return a string of the same form
  55.  * described by parse_date() below.
  56.  */
  57. char *
  58. msg_date(n)
  59. register int n;
  60. {
  61.     register char *p, *p2 = NULL;
  62.     char line[256];
  63.  
  64.     /* not in use */
  65.     /* try the easy way out first -- This is potentially a serious kludge
  66.      * because not all message-id lines are right. -- most of the time,
  67.      * this is correct.  it's not correct from messages from strange
  68.      * mailers (non-sendmail) they do a different format in message-id.
  69.     if ((p = header_field(n, "message-id")) && (p2 = index(p, '<'))) {
  70.     p = p2+1;
  71.     if (p2 = index(p, '.')) {
  72.         *p2 = 0;
  73.         return p;
  74.     }
  75.     }
  76.      */
  77.  
  78.     /* else, get the "date" line, if that fails, get the date in "From" line */
  79.     if ((p = header_field(n, "date")) && (p2 = parse_date(p)))
  80.     return p2;
  81.  
  82.     (void) fseek(tmpf, msg[n].m_offset, L_SET);
  83.     (void) fgets(line, BUFSIZ, tmpf);
  84.     if (!(p = index(line, ' ')) || !(p2 = index(p+1, ' ')))
  85.     return NULL;
  86.     p = p2;
  87.  
  88.     if (!(p2 = parse_date(p)))
  89.     print("Message %d has bad date: %s\n", n+1, p);
  90.     return p2;
  91. }
  92.  
  93. /* parse date and return a string that looks like
  94.  *    "%2d%2d%2d%2d%2d", yr,mo,date,hrs,mins
  95.  */
  96. char *
  97. parse_date(p)
  98. register char *p;
  99. {
  100.     static char buf[11];
  101.     int Month = 0, Day = 0, Year = 0, Hours = -1, Mins = -1;
  102.  
  103.     skipspaces(0);
  104.  
  105.     /* Possible combinations that we could have:
  106.      *   day_number month_name year_number time timezone ...
  107.      *   day_name month_name day_number time year_number
  108.      *   day_name month_name day_number year_number time
  109.      *   day_name day_number month_name year_number time
  110.      *   day_number month_name year_number time
  111.      *   day_number month_name year_number time-timezone (day)
  112.      *                                       ^no colon separator
  113.      *   day_name month_name day_number time timezone year_number
  114.      *   day_number-month_name-year time
  115.      *   day_name, day_number-month_name-year time
  116.      */
  117.     if (sscanf(p, "%d %s %2d %d:%d", &Day,buf,&Year,&Hours,&Mins) == 5
  118.     ||
  119.     sscanf(p, "%*s %s %d %d:%d:%*d %d", buf,&Day,&Hours,&Mins,&Year) == 5
  120.     ||
  121.     sscanf(p, "%*s %s %d %d %d:%d", buf,&Day,&Year,&Hours,&Mins) == 5
  122.     ||
  123.     sscanf(p, "%*s %d %s %d %d:%d", &Day,buf,&Year,&Hours,&Mins) == 5
  124.     ||
  125.     sscanf(p, "%d %s %d %d:%d", &Day,buf,&Year,&Hours,&Mins) == 5
  126.     ||
  127.     sscanf(p, "%d %s %d %2d%2d", &Day,buf,&Year,&Hours,&Mins) == 5
  128.     ||
  129.     sscanf(p, "%*s %s %d %d:%d:%*d %*s %d", 
  130.                     buf, &Day, &Hours, &Mins, &Year) == 5
  131.     ||
  132.     sscanf(p,"%d-%[^-]-%d %d:%d", &Day, buf, &Year, &Hours, &Mins) == 5
  133.     ||
  134.     sscanf(p,"%*s %d-%[^-]-%d %d:%d", &Day, buf, &Year, &Hours, &Mins) == 5) {
  135.     if (Year > 1900)
  136.         Year -= 1900;
  137.     if ((Month = month_to_n(buf)) == -1) {
  138.         print("bad month: %s\n", p);
  139.         return NULL;
  140.     }
  141.     return sprintf(buf, "%02d%02d%02d%02d%02d", Year,Month,Day,Hours,Mins);
  142.     }
  143.     print("Unknown date format: %s\n", p);
  144.     return NULL;
  145. }
  146.  
  147. /* pass a string in the form described above, put into string. "yr" is
  148.  * not used, but is here anyway in case you want to modify it to use it.
  149.  */
  150. char *
  151. date_to_string(Date)
  152. char *Date;
  153. {
  154.     static char buf[30];
  155.     int yr, mon, day, hr, mins;
  156.     char a_or_p, *p = buf;
  157.  
  158.     (void) sscanf(Date, "%2d%2d%2d%2d%02d", &yr, &mon, &day, &hr, &mins);
  159.     a_or_p = (hr < 12)? 'a': 'p';
  160.     p += strlen(sprintf(p, "%s %2.d, ", month_names[mon-1], day));
  161.     (void) sprintf(p, "%2.d:%02d%cm",
  162.       (hr)? (hr <= 12)? hr: hr - 12: 12, mins, a_or_p);
  163.     return buf;
  164. }
  165.  
  166. #define JAN    1
  167. #define FEB    2
  168. #define MAR    3
  169. #define APR    4
  170. #define MAY    5
  171. #define JUN    6
  172. #define JUL    7
  173. #define AUG    8
  174. #define SEP    9
  175. #define OCT    10
  176. #define NOV    11
  177. #define DEC    12
  178.  
  179. /* stolen direct from ELM */
  180. month_to_n(name)
  181. register char *name;
  182. {
  183.     /** return the month number given the month name... **/
  184.  
  185.     register char ch;
  186.  
  187.     switch (lower(*name)) {
  188.     case 'a' : if ((ch = lower(name[1])) == 'p')
  189.                return(APR);
  190.            else if (ch == 'u')
  191.                return(AUG);
  192.            else return(-1);    /* error! */
  193.     case 'd' : return(DEC);
  194.     case 'f' : return(FEB);
  195.     case 'j' : if ((ch = lower(name[1])) == 'a')
  196.                return(JAN);
  197.            else if (ch == 'u') {
  198.              if ((ch = lower(name[2])) == 'n')
  199.              return(JUN);
  200.              else if (ch == 'l')
  201.              return(JUL);
  202.              else return(-1);        /* error! */
  203.            }
  204.            else return(-1);        /* error */
  205.     case 'm' : if ((ch = lower(name[2])) == 'r')
  206.                return(MAR);
  207.            else if (ch == 'y')
  208.                return(MAY);
  209.            else return(-1);        /* error! */
  210.     case 'n' : return(NOV);
  211.     case 'o' : return(OCT);
  212.     case 's' : return(SEP);
  213.     default  : return(-1);
  214.     }
  215. }
  216.