home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / mush6.4 / part04 / dates.c next >
Encoding:
C/C++ Source or Header  |  1989-03-12  |  8.1 KB  |  288 lines

  1. /* @(#)dates.c    1.1    (c) copyright 10/15/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. /*
  6.  *   %02d%02d%02d%02d%02d%s  yy mm dd hh mm weekday
  7.  * The standard "date format" stored in the msg data structure.
  8.  */
  9. char *day_names[] = {
  10.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  11. };
  12. char *month_names[] = {     /* imported in pick.c */
  13.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  14.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  15. };
  16.  
  17. /* Time() returns a string according to criteria:
  18.  *   if "now" is 0, then the current time is gotten and used.
  19.  *       else, use the time described by now
  20.  *   opts points to a string of args which is parsed until an unknown
  21.  *       arg is found and opts will point to that upon return.
  22.  *   valid args are T (time of day), D (day of week), M (month), Y (year),
  23.  *       N (number of day in month -- couldn't think of a better letter).
  24.  */
  25. char *
  26. Time(opts, now)
  27. register char *opts;
  28. long now;
  29. {
  30.     static char time_buf[30];
  31.     struct tm       *T;
  32.     register char *p = time_buf;
  33.     long      x;
  34.  
  35.     if (!opts)
  36.     return NULL;
  37.     if (now)
  38.     x = now;
  39.     else
  40.     (void) time(&x);
  41.     T = localtime(&x);
  42.     for (;; opts++) {
  43.     switch(*opts) {
  44.         case 'T':
  45.         if (ison(glob_flags, MIL_TIME))
  46.             (void) sprintf(p, "%2d:%02d", T->tm_hour, T->tm_min);
  47.         else
  48.             (void) sprintf(p, "%d:%02d", (T->tm_hour) ?
  49.               ((T->tm_hour <= 12) ? T->tm_hour : T->tm_hour - 12) :
  50.               12, T->tm_min);
  51.         when 'D': case 'W': (void) strcpy(p, day_names[T->tm_wday]);
  52.         when 'M': (void) strcpy(p, month_names[T->tm_mon]);
  53.         when 'y': (void) sprintf(p, "%d", T->tm_year);
  54.         when 'Y': (void) sprintf(p, "19%d", T->tm_year);
  55.         when 'N': (void) sprintf(p, "%d", T->tm_mday);
  56.         otherwise: *--p = 0; return time_buf;
  57.     }
  58.     p += strlen(p);
  59.     *p++ = ' ';
  60.     }
  61. }
  62.  
  63. /* parse date and return a string that looks like
  64.  *    "%2d%2d%2d%2d%2d%3c", wkday,yr,mo,date,hrs,mins
  65.  * This function is a bunch of scanfs on known date formats.  Don't
  66.  * trust the "weekday" name fields because they may not be spelled
  67.  * right, or have the correct punctuation.  Figure it out once the
  68.  * year and month and date have been determined.
  69.  */
  70. char *
  71. parse_date(p)
  72. register char *p;
  73. {
  74.     /* When scanf-ing if month isn't a month, it could be a _long_ string.
  75.      * this is also the static buffer whose address we return.
  76.      */
  77.     static char month[64];
  78.     char Wkday[4];
  79.     int Month = 0, Day = 0, Year = 0, Hours = -1, Mins = -1;
  80.  
  81.     skipspaces(0);
  82.  
  83.     /* Possible combinations that we could have:
  84.      *   day_number month_name year_number time timezone ...
  85.      *   day_name month_name day_number time year_number
  86.      *   day_name month_name day_number year_number time
  87.      *   day_name day_number month_name year_number time
  88.      *   day_number month_name year_number time
  89.      *   day_number month_name year_number time-timezone (day)
  90.      *                                       ^no colon separator
  91.      *   day_name month_name day_number time timezone year_number
  92.      *   day_number-month_name-year time
  93.      *   day_name, day_number-month_name-year time
  94.      *   day_number month_name year_number, time "-"
  95.      */
  96.     /* programmer's note -- there are too many scanfs here for some compilers
  97.      * to put them all into one if statement.  Use goto's :-(
  98.      */
  99.     if (sscanf(p, "%*s %s %d %d %d:%d", month,&Day,&Year,&Hours,&Mins) == 5)
  100.     goto gotit;
  101.     if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  102.     goto gotit;
  103.     if (sscanf(p, "%*s %s %d %d:%d:%*d %d", month,&Day,&Hours,&Mins,&Year) == 5)
  104.     goto gotit;
  105.     if (sscanf(p, "%*s %d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  106.     goto gotit;
  107.     if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  108.     goto gotit;
  109.     if (sscanf(p, "%d %s %d %2d%2d", &Day,month,&Year,&Hours,&Mins) == 5)
  110.     goto gotit;
  111.     if (sscanf(p, "%*s %s %d %d:%d:%*d %*s %d",
  112.                     month, &Day, &Hours, &Mins, &Year) == 5)
  113.     goto gotit;
  114.     if (sscanf(p, "%*s %s %d %d:%d %*s %d",
  115.                     month, &Day, &Hours, &Mins, &Year) == 5)
  116.     goto gotit;
  117.     if (sscanf(p,"%d-%[^-]-%d %d:%d", &Day, month, &Year, &Hours, &Mins) == 5)
  118.     goto gotit;
  119.     if (sscanf(p,"%d %s %d, %d:%d:%*d -",&Day, month, &Year, &Hours, &Mins)== 5)
  120.     goto gotit;
  121.     if (sscanf(p,"%*s %d-%[^-]-%d %d:%d",&Day, month, &Year, &Hours, &Mins)== 5)
  122.     goto gotit;
  123.     goto didnt_getit;
  124. gotit:
  125.     if (Year > 99)
  126.     Year %= 100;
  127.     if ((Month = month_to_n(month)) == -1) {
  128.     print("bad month: %s\n", p);
  129.     return NULL;
  130.     }
  131.     {
  132.     static int mtbl[]={0,31,59,90,120,151,181,212,243,273,304,334};
  133.     int days_ctr;
  134.  
  135.         days_ctr = ((Year * 365) + ((Year + 3) / 4) + mtbl[Month-1] + Day + 6);
  136.         if (Month > 2 && (Year % 4 == 0))
  137.         days_ctr++;
  138.         (void) (sprintf(Wkday, "%.3s", day_names[days_ctr % 7]));
  139.     }
  140.     return sprintf(month, "%02d%02d%02d%02d%02d%s",
  141.               Year, Month, Day, Hours, Mins, Wkday);
  142. didnt_getit:
  143.     if (ison(glob_flags, WARNING))
  144.     print("Unknown date format: %s\n", p);
  145.     return NULL;
  146. }
  147.  
  148. /* pass a string in the standard date format, put into string.
  149.  * return values in buffers provided they are not null.
  150.  */
  151. char *
  152. date_to_string(Date, Yr, Mon, Day, Wkday, Tm, ret_buf)
  153. char *Date, *Yr, *Mon, *Day, *Wkday, *Tm, *ret_buf;
  154. {
  155.     unsigned int days_ctr;
  156.     int yr, mon, day, hr, mins;
  157.     char a_or_p, *p = ret_buf;
  158.  
  159.     (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c",
  160.     &yr, &mon, &day, &hr, &mins, Wkday);
  161.     Wkday[3] = 0;
  162.     a_or_p = (hr < 12)? 'a': 'p';
  163.  
  164.     (void) sprintf(Yr, "19%d", yr);
  165.     (void) sprintf(Day, "%d", day);
  166.     (void) strcpy(Mon, month_names[mon-1]);
  167.     p += strlen(sprintf(p, "%s %2.d, ", month_names[mon-1], day));
  168.     if (ison(glob_flags, MIL_TIME))
  169.     (void) sprintf(p, "%2d:%02d",hr,mins);
  170.     else
  171.     (void) sprintf(p, "%2.d:%02d%cm",
  172.           (hr)? (hr <= 12)? hr: hr - 12: 12, mins, a_or_p);
  173.     (void) strcpy(Tm, p);
  174.     return ret_buf;
  175. }
  176.  
  177. /* pass a string in the internal mush date format.
  178.  * return pointer to static buffer holding ctime-format date.
  179.  */
  180. char *
  181. date_to_ctime(Date)
  182. char *Date;
  183. {
  184.     static char ret_buf[32];
  185.     char Wkday[4];
  186.     int yr, mon, day, hr, mins;
  187.  
  188.     (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c",
  189.     &yr, &mon, &day, &hr, &mins, Wkday);
  190.  
  191.     (void) sprintf(ret_buf, "%.3s %.3s %2.d %02d:%02d:00 19%d\n",
  192.         Wkday, month_names[mon-1], day, hr, mins, yr);
  193.  
  194.     return ret_buf;
  195. }
  196.  
  197. /*
  198.  * Build a date string according to the specification in the RFC for Date:
  199.  */
  200. char *
  201. rfc_date(buf)
  202. char buf[];
  203. {
  204.     struct tm       *T;
  205. #ifdef SYSV
  206.     long      x;
  207.     extern char *tzname[];
  208.     char *tz;
  209.  
  210.     (void) time(&x);
  211.     T = localtime(&x);
  212.     tz = tzname[T->tm_isdst];
  213. #else /* SYSV */
  214. #ifdef BSD
  215.     extern char     *timezone();
  216.     struct timeval  mytime;
  217.     struct timezone myzone;
  218.     char *tz;
  219.  
  220.     (void) gettimeofday(&mytime, &myzone);
  221.     T = localtime(&mytime.tv_sec);
  222.     tz = timezone(myzone.tz_minuteswest, (T->tm_isdst && myzone.tz_dsttime));
  223. #else
  224.     char *tz = "";
  225. #endif /* BSD */
  226. #endif /* !SYSV */
  227.  
  228.     return sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s",
  229.     day_names[T->tm_wday],    /* day name */
  230.     T->tm_mday,        /* day of the month */
  231.     month_names[T->tm_mon],    /* month name */
  232.     T->tm_year,        /* year number */
  233.     T->tm_hour,        /* hours (24hr) */
  234.     T->tm_min, T->tm_sec,    /* mins/secs */
  235.     tz);            /* timezone */
  236. }
  237.  
  238. #define JAN    1
  239. #define FEB    2
  240. #define MAR    3
  241. #define APR    4
  242. #define MAY    5
  243. #define JUN    6
  244. #define JUL    7
  245. #define AUG    8
  246. #define SEP    9
  247. #define OCT    10
  248. #define NOV    11
  249. #define DEC    12
  250.  
  251. /* stolen direct from ELM */
  252. month_to_n(name)
  253. register char *name;
  254. {
  255.     /** return the month number given the month name... **/
  256.  
  257.     register char ch;
  258.  
  259.     switch (lower(*name)) {
  260.     case 'a' : if ((ch = lower(name[1])) == 'p')
  261.                return(APR);
  262.            else if (ch == 'u')
  263.                return(AUG);
  264.            else return(-1);    /* error! */
  265.     case 'd' : return(DEC);
  266.     case 'f' : return(FEB);
  267.     case 'j' : if ((ch = lower(name[1])) == 'a')
  268.                return(JAN);
  269.            else if (ch == 'u') {
  270.              if ((ch = lower(name[2])) == 'n')
  271.              return(JUN);
  272.              else if (ch == 'l')
  273.              return(JUL);
  274.              else return(-1);        /* error! */
  275.            }
  276.            else return(-1);        /* error */
  277.     case 'm' : if ((ch = lower(name[2])) == 'r')
  278.                return(MAR);
  279.            else if (ch == 'y')
  280.                return(MAY);
  281.            else return(-1);        /* error! */
  282.     case 'n' : return(NOV);
  283.     case 'o' : return(OCT);
  284.     case 's' : return(SEP);
  285.     default  : return(-1);
  286.     }
  287. }
  288.