home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / rcs57pc3.zip / rcs / src / rcstime.c < prev    next >
C/C++ Source or Header  |  1995-06-16  |  5KB  |  192 lines

  1. /* Convert between RCS time format and Posix and/or C formats.  */
  2.  
  3. /* Copyright 1992, 1993, 1994, 1995 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.
  20. If not, write to the Free Software Foundation,
  21. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22.  
  23. Report problems and direct all questions to:
  24.  
  25.     rcs-bugs@cs.purdue.edu
  26.  
  27. */
  28.  
  29. #include "rcsbase.h"
  30. #include "partime.h"
  31. #include "maketime.h"
  32.  
  33. libId(rcstimeId, "$Id: rcstime.c,v 1.4 1995/06/16 06:19:24 eggert Exp $")
  34.  
  35. static long zone_offset; /* seconds east of UTC, or TM_LOCAL_ZONE */
  36. static int use_zone_offset; /* if zero, use UTC without zone indication */
  37.  
  38. /*
  39. * Convert Unix time to RCS format.
  40. * For compatibility with older versions of RCS,
  41. * dates from 1900 through 1999 are stored without the leading "19".
  42. */
  43.     void
  44. time2date(unixtime,date)
  45.     time_t unixtime;
  46.     char date[datesize];
  47. {
  48.     register struct tm const *tm = time2tm(unixtime, RCSversion<VERSION(5));
  49.     VOID sprintf(date,
  50. #        if has_printf_dot
  51.             "%.2d.%.2d.%.2d.%.2d.%.2d.%.2d",
  52. #        else
  53.             "%02d.%02d.%02d.%02d.%02d.%02d",
  54. #        endif
  55.         tm->tm_year  +  ((unsigned)tm->tm_year < 100 ? 0 : 1900),
  56.         tm->tm_mon+1, tm->tm_mday,
  57.         tm->tm_hour, tm->tm_min, tm->tm_sec
  58.     );
  59. }
  60.  
  61. /* Like str2time, except die if an error was found.  */
  62. static time_t str2time_checked P((char const*,time_t,long));
  63.     static time_t
  64. str2time_checked(source, default_time, default_zone)
  65.     char const *source;
  66.     time_t default_time;
  67.     long default_zone;
  68. {
  69.     time_t t = str2time(source, default_time, default_zone);
  70.     if (t == -1)
  71.         faterror("unknown date/time: %s", source);
  72.     return t;
  73. }
  74.  
  75. /*
  76. * Parse a free-format date in SOURCE, convert it
  77. * into RCS internal format, and store the result into TARGET.
  78. */
  79.     void
  80. str2date(source, target)
  81.     char const *source;
  82.     char target[datesize];
  83. {
  84.     time2date(
  85.         str2time_checked(source, now(),
  86.             use_zone_offset ? zone_offset
  87.             : RCSversion<VERSION(5) ? TM_LOCAL_ZONE
  88.             : 0
  89.         ),
  90.         target
  91.     );
  92. }
  93.  
  94. /* Convert an RCS internal format date to time_t.  */
  95.     time_t
  96. date2time(source)
  97.     char const source[datesize];
  98. {
  99.     char s[datesize + zonelenmax];
  100.     return str2time_checked(date2str(source, s), (time_t)0, 0);
  101. }
  102.  
  103.  
  104. /* Set the time zone for date2str output.  */
  105.     void
  106. zone_set(s)
  107.     char const *s;
  108. {
  109.     if ((use_zone_offset = *s)) {
  110.         long zone;
  111.         char const *zonetail = parzone(s, &zone);
  112.         if (!zonetail || *zonetail)
  113.             error("%s: not a known time zone", s);
  114.         else
  115.             zone_offset = zone;
  116.     }
  117. }
  118.  
  119.  
  120. /*
  121. * Format a user-readable form of the RCS format DATE into the buffer DATEBUF.
  122. * Yield DATEBUF.
  123. */
  124.     char const *
  125. date2str(date, datebuf)
  126.     char const date[datesize];
  127.     char datebuf[datesize + zonelenmax];
  128. {
  129.     register char const *p = date;
  130.  
  131.     while (*p++ != '.')
  132.         continue;
  133.     if (!use_zone_offset)
  134.         VOID sprintf(datebuf,
  135.         "19%.*s/%.2s/%.2s %.2s:%.2s:%s"
  136.             + (date[2]=='.' && VERSION(5)<=RCSversion  ?  0  :  2),
  137.         (int)(p-date-1), date,
  138.         p, p+3, p+6, p+9, p+12
  139.         );
  140.     else {
  141.         struct tm t;
  142.         struct tm const *z;
  143.         int non_hour;
  144.         long 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), d;
  157.         z = localtime(&u);
  158.         d = difftm(z, &t);
  159.         zone  =  (time_t)-1 < 0 || d < -d  ?  d  :  -(long)-d;
  160.         } else {
  161.         adjzone(&t, zone);
  162.         z = &t;
  163.         }
  164.         c = '+';
  165.         if (zone < 0) {
  166.         zone = -zone;
  167.         c = '-';
  168.         }
  169.         VOID sprintf(datebuf,
  170. #        if has_printf_dot
  171.             "%.2d-%.2d-%.2d %.2d:%.2d:%.2d%c%.2d",
  172. #        else
  173.             "%02d-%02d-%02d %02d:%02d:%02d%c%02d",
  174. #        endif
  175.         z->tm_year + 1900,
  176.         z->tm_mon + 1, z->tm_mday, z->tm_hour, z->tm_min, z->tm_sec,
  177.         c, (int) (zone / (60*60))
  178.         );
  179.         if ((non_hour = zone % (60*60))) {
  180. #        if has_printf_dot
  181.             static char const fmt[] = ":%.2d";
  182. #        else
  183.             static char const fmt[] = ":%02d";
  184. #        endif
  185.         VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour / 60);
  186.         if ((non_hour %= 60))
  187.             VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour);
  188.         }
  189.     }
  190.     return datebuf;
  191. }
  192.