home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / rcs567s.zip / rcs / src / rcstime.c < prev    next >
C/C++ Source or Header  |  1994-04-14  |  4KB  |  181 lines

  1. /* Convert between RCS time format and Posix and/or C formats.  */
  2.  
  3. /* Copyright 1992, 1993, 1994 Paul Eggert
  4.    Distributed under license by the Free Software Foundation, Inc.
  5.  
  6. This file is part of RCS.
  7.  
  8. RCS is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2, or (at your option)
  11. any later version.
  12.  
  13. RCS is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with RCS; see the file COPYING.  If not, write to
  20. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. Report problems and direct all questions to:
  23.  
  24.     rcs-bugs@cs.purdue.edu
  25.  
  26. */
  27.  
  28. #include "rcsbase.h"
  29. #include "partime.h"
  30. #include "maketime.h"
  31.  
  32. libId(rcstimeId, "$Id: rcstime.c,v 1.2 1994/04/13 16:27:12 eggert Exp $")
  33.  
  34. #if has_printf_dot
  35.     char const dateform[] = "%.2d.%.2d.%.2d.%.2d.%.2d.%.2d";
  36. #else
  37.     char const dateform[] = "%02d.%02d.%02d.%02d.%02d.%02d";
  38. #endif
  39.  
  40. static int zone_offset; /* minutes east of UTC, or TM_LOCAL_ZONE */
  41. static int use_zone_offset; /* if zero, use UTC without zone indication */
  42.  
  43. /*
  44. * Convert Unix time to RCS format.
  45. * For compatibility with older versions of RCS,
  46. * dates from 1900 through 1999 are stored without the leading "19".
  47. */
  48.     void
  49. time2date(unixtime,date)
  50.     time_t unixtime;
  51.     char date[datesize];
  52. {
  53.     register struct tm const *tm = time2tm(unixtime, RCSversion<VERSION(5));
  54.     VOID sprintf(date,
  55.         dateform,
  56.         tm->tm_year  +  ((unsigned)tm->tm_year < 100 ? 0 : 1900),
  57.         tm->tm_mon+1, tm->tm_mday,
  58.         tm->tm_hour, tm->tm_min, tm->tm_sec
  59.     );
  60. }
  61.  
  62. /* Like str2time, except die if an error was found.  */
  63. static time_t str2time_checked P((char const*,time_t,int));
  64.     static time_t
  65. str2time_checked(source, default_time, default_zone)
  66.     char const *source;
  67.     time_t default_time;
  68.     int default_zone;
  69. {
  70.     time_t t = str2time(source, default_time, default_zone);
  71.     if (t == -1)
  72.         faterror("unknown date/time: %s", source);
  73.     return t;
  74. }
  75.  
  76. /*
  77. * Parse a free-format date in SOURCE, convert it
  78. * into RCS internal format, and store the result into TARGET.
  79. */
  80.     void
  81. str2date(source, target)
  82.     char const *source;
  83.     char target[datesize];
  84. {
  85.     time2date(
  86.         str2time_checked(source, now(),
  87.             use_zone_offset ? zone_offset
  88.             : RCSversion<VERSION(5) ? TM_LOCAL_ZONE
  89.             : 0
  90.         ),
  91.         target
  92.     );
  93. }
  94.  
  95. /* Convert an RCS internal format date to time_t.  */
  96.     time_t
  97. date2time(source)
  98.     char const source[datesize];
  99. {
  100.     char s[datesize + zonelenmax];
  101.     return str2time_checked(date2str(source, s), (time_t)0, 0);
  102. }
  103.  
  104.  
  105. /* Set the time zone for date2str output.  */
  106.     void
  107. zone_set(s)
  108.     char const *s;
  109. {
  110.     if ((use_zone_offset = *s)) {
  111.         int zone;
  112.         char const *zonetail = parzone(s, &zone);
  113.         if (!zonetail || *zonetail)
  114.             error("%s: not a known time zone", s);
  115.         else
  116.             zone_offset = zone;
  117.     }
  118. }
  119.  
  120.  
  121. /*
  122. * Format a user-readable form of the RCS format DATE into the buffer DATEBUF.
  123. * Yield DATEBUF.
  124. */
  125.     char const *
  126. date2str(date, datebuf)
  127.     char const date[datesize];
  128.     char datebuf[datesize + zonelenmax];
  129. {
  130.     register char const *p = date;
  131.  
  132.     while (*p++ != '.')
  133.         continue;
  134.     if (!use_zone_offset)
  135.         VOID sprintf(datebuf,
  136.         "19%.*s/%.2s/%.2s %.2s:%.2s:%s"
  137.             + (date[2]=='.' && VERSION(5)<=RCSversion  ?  0  :  2),
  138.         (int)(p-date-1), date,
  139.         p, p+3, p+6, p+9, p+12
  140.         );
  141.     else {
  142.         struct tm t;
  143.         struct tm const *z;
  144.         int zone;
  145.         char c;
  146.  
  147.         t.tm_year = atoi(date) - (date[2]=='.' ? 0 : 1900);
  148.         t.tm_mon = atoi(p) - 1;
  149.         t.tm_mday = atoi(p+3);
  150.         t.tm_hour = atoi(p+6);
  151.         t.tm_min = atoi(p+9);
  152.         t.tm_sec = atoi(p+12);
  153.         t.tm_wday = -1;
  154.         zone = zone_offset;
  155.         if (zone == TM_LOCAL_ZONE) {
  156.         time_t u = tm2time(&t, 0);
  157.         z = localtime(&u);
  158.         zone = difftm(z, &t) / 60;
  159.         } else {
  160.         adjzone(&t, zone);
  161.         z = &t;
  162.         }
  163.         c = '+';
  164.         if (zone < 0) {
  165.         zone = -zone;
  166.         c = '-';
  167.         }
  168.         VOID sprintf(datebuf,
  169. #        if has_printf_dot
  170.             "%.2d-%.2d-%.2d %.2d:%.2d:%.2d%c%.2d%.2d",
  171. #        else
  172.             "%02d-%02d-%02d %02d:%02d:%02d%c%02d%02d",
  173. #        endif
  174.         z->tm_year + 1900,
  175.         z->tm_mon + 1, z->tm_mday, z->tm_hour, z->tm_min, z->tm_sec,
  176.         c, zone/60, zone%60
  177.         );
  178.     }
  179.     return datebuf;
  180. }
  181.