home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / cnews.tar / contrib / lib / isodate.c < prev    next >
C/C++ Source or Header  |  1992-09-07  |  3KB  |  123 lines

  1. /* Conversion routines for ISO3307 dates.  Used in ftp MDTM and nntp2 */
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include "isodate.h"
  5.  
  6. /*
  7.  * Takes a struct tm and formats it as a date according to ISO3307.
  8.  * struct tm should be properly canonicalized in GMT.
  9.  */
  10. char *
  11. tm2isodate(tmp)
  12. struct tm *tmp;
  13. {
  14.     static char isobuf[sizeof "YYYYMMDDHHMMSS"];
  15.  
  16.     (void) sprintf(isobuf, "%04.4d%02.2d%02.2d%02.2d%02.2d%02.2d",
  17.         tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
  18.         tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
  19.     return isobuf;
  20. }
  21.  
  22. char *
  23. time2isodate(t)
  24. time_t t;
  25. {
  26.     return tm2isodate(gmtime(&t));
  27. }
  28.  
  29. /*
  30.  * Extract N chars from startp to buf and NUL-terminate.  startp and
  31.  * endp finish at startp + N
  32.  */
  33. #define ADVANCE(N) \
  34.     endp += N; \
  35.     bufp = buf; \
  36.     while (startp != endp) \
  37.         *bufp++ = *startp++; \
  38.     *bufp = '\0';
  39.     
  40. /*
  41.  * Takes an ISO3307 date string and parses it into a struct tm.  Returns
  42.  * NULL if the date string is not one of YYYYMMDDHHMMSS, YYYYMMDDHHMM or
  43.  * YYYYMMDD.
  44.  */
  45. struct tm *
  46. isodate2tm(isodatestr)
  47. char *isodatestr;
  48. {
  49.     char buf[sizeof "YYYY"];
  50.     register char *bufp, *startp, *endp;
  51.     int len, isolen = sizeof "YYYYMMDDHHMMSS" - 1;
  52.     static struct tm tmstruct;
  53.     register struct tm *tmp = &tmstruct;
  54.  
  55.     endp = startp = isodatestr;
  56.     len = strlen(startp);
  57.     if (len != isolen && len != isolen - 2 && len != isolen - 6)
  58.         return NULL;
  59.     ADVANCE(4);
  60.     tmp->tm_year = atoi(buf) - 1900;
  61.     ADVANCE(2);
  62.     tmp->tm_mon = atoi(buf) - 1;
  63.     ADVANCE(2);
  64.     tmp->tm_mday = atoi(buf);
  65.     if (*startp) {
  66.         ADVANCE(2);
  67.         tmp->tm_hour = atoi(buf);
  68.         ADVANCE(2);
  69.         tmp->tm_min = atoi(buf);
  70.         if (*startp) {
  71.             ADVANCE(2);
  72.             tmp->tm_sec = atoi(buf);
  73.         } else
  74.             tmp->tm_sec = 0;
  75.     } else {
  76.         tmp->tm_hour = tmp->tm_min = tmp->tm_sec = 0;
  77.     }
  78.     tmp->tm_wday = tmp->tm_yday = tmp->tm_isdst = 0;
  79. #ifdef HAVE_GMTOFF
  80.     /*
  81.      * SunOS, Ultrix have these.  Irix doesn't. 4.3reno comment
  82.      * indicates they may go away. Not essential for our needs, I
  83.      * hope nothing else relies on them.
  84.      */
  85.     tmp->tm_gmtoff = 0;
  86.     tmp->tm_zone = "GMT";
  87. #endif
  88.     return tmp;
  89. }
  90.  
  91. #ifdef TEST
  92. int
  93. main(argc, argv)
  94. int argc;
  95. char **argv;
  96. {
  97.     time_t t = argv[1] ? atol(argv[1]) : time((time_t *) 0);
  98.     struct tm *tmptr = gmtime(&t), *tmp2;
  99.     char buf[32], *cp = tm2isodate(tmptr);
  100.  
  101.     tmp2 = isodate2tm(cp);
  102.     printf("%ld %s %s\n", t, cp, time2isodate(t));
  103.     strftime(buf, sizeof buf, "%Y%m%d%H%M%S", tmp2);
  104.     printf("%s\n", buf);
  105.     cp[12] = '\0';
  106.     tmp2 = isodate2tm(cp);
  107.     strftime(buf, sizeof buf, "%Y%m%d%H%M%S", tmp2);
  108.     printf("%s\n", buf);
  109.     cp[8] = '\0';
  110.     tmp2 = isodate2tm(cp);
  111.     strftime(buf, sizeof buf, "%Y%m%d%H%M%S", tmp2);
  112.     printf("%s\n", buf);
  113.     cp[7] = '\0';
  114.     tmp2 = isodate2tm(cp);
  115.     if (tmp2 != NULL) {
  116.         strftime(buf, sizeof buf, "%Y%m%d%H%M%S", tmp2);
  117.         printf("Non NULL tmp! %s\n", buf);
  118.     } else
  119.         printf("NULL\n");
  120.     return 0;
  121. }
  122. #endif
  123.