[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] ISO-8601 dates patch #1 - please see

From: Nuutti Kotivuori <naked_at_iki.fi>
Date: 2002-05-24 01:28:17 CEST

On advisory from sussman I am re-submitting this patch with a log
message here. I am unavailable during the weekend and will be back
sometime next week. This patch should make in before the next tarball
is rolled. So there's a few ways to do this.

1) If no-one says anything at all, I will be committing this patch in
about 12 hours. That would be around noon GMT.

2) If someone volunteers to take care of the patch and commit it, I'll
leave it to him.

3) Someone has an objection to make, in which case I'll leave the
matter for next week.

TIA,
-- Naked

Log message:
---------------------------------------------------------------------------
This is the first part of the changes for issue 614, eg. to make svn
use ISO-8601 timestamps.

It makes svn_time_from_nts understand a new style of timestamps,
roughly looking like this:

  2002-05-13T19:00:50.966679Z

For now, the code still generates old style timestamps, but that is to
be fixed after the next tarball is out.

* subversion/svn/subversion/libsvn_subr/time.c (timestamp_format):
  Change format to the new format.
  (old_timestamp_format): New variable.
  (svn_time_to_nts): Use apr_time_exp_gmt to get the time in GMT.
  Add commented version for printing the new format, but use the old
  format still.
  (svn_time_from_nts): Make it understand both new and old formats.

* subversion/svn/subversion/tests/libsvn_subr/time-test.c: New file,
  tests for the time conversion functions, both new and old format.

* subversion/svn/build.conf (time-test): Added building of the new
  test.
---------------------------------------------------------------------------

Patch:
---------------------------------------------------------------------------
Index: ./build.conf
===================================================================
--- ./build.conf
+++ ./build.conf Mon May 13 23:13:16 2002
@@ -289,6 +289,14 @@
 install = test
 libs = libsvn_test libsvn_subr $(SVN_APRUTIL_LIBS) $(SVN_APR_LIBS)
 
+# test time functions
+[time-test]
+type = exe
+path = subversion/tests/libsvn_subr
+sources = time-test.c
+install = test
+libs = libsvn_test libsvn_subr $(SVN_APRUTIL_LIBS) $(SVN_APR_LIBS)
+
 # test eol conversion and keyword substitution routines
 [translate-test]
 type = exe
Index: ./subversion/libsvn_subr/time.c
===================================================================
--- ./subversion/libsvn_subr/time.c
+++ ./subversion/libsvn_subr/time.c Sun May 19 18:14:02 2002
@@ -29,6 +29,18 @@
 /*** Code. ***/
 
 /* Our timestamp strings look like this:
+ *
+ * "2002-05-07Thh:mm:ss.uuuuuuZ"
+ *
+ * The format is conformant with ISO-8601 and the date format required
+ * by RFC2518 for creationdate. It is a direct converision between
+ * apr_time_t and a string, so converting to string and back retains
+ * the exact value.
+ */
+static const char * const timestamp_format =
+"%04d-%02d-%02dT%02d:%02d:%02d.%06dZ";
+
+/* Our old timestamp strings looked like this:
  *
  * "Tue 3 Oct 2000 HH:MM:SS.UUU (day 277, dst 1, gmt_off -18000)"
  *
@@ -37,12 +49,10 @@
  * to completely fill in an apr_time_exp_t: tm_yday, tm_isdst,
  * and tm_gmtoff.
  *
- * kff todo: what about portability problems resulting from the
- * plain int assumptions below, though? Using apr_strftime() would
- * fix that, but converting the strings back is still a problem (see
- * the comment in svn_wc__time_to_string()).
+ * This format is still recognized on input, for backward
+ * compatibility, but no longer generated.
  */
-static const char * const timestamp_format =
+static const char * const old_timestamp_format =
 "%s %d %s %d %02d:%02d:%02d.%06d (day %03d, dst %d, gmt_off %06d)";
 
 
@@ -58,14 +68,31 @@
      furthermore their current implementations can only return success
      anyway. */
 
- apr_time_exp_lt (&exploded_time, t);
+ /* We get the date in GMT now -- and expect the tm_gmtoff and
+ tm_isdst to be not set. We also ignore the weekday and yearday,
+ since those are not needed. */
+
+ apr_time_exp_gmt (&exploded_time, t);
+
+ /* It would be nice to use apr_strftime(), but APR doesn't give a
+ way to convert back, so we wouldn't be able to share the format
+ string between the writer and reader. */
+ /* XXX: Enable this bit of code and remove the one below when a
+ bootstrap tarball has been released with this change included.
 
- /* It would be nice to use apr_strftime(), but APR doesn't give a way
- to convert back, so we wouldn't be able to share the format string
- between the writer and reader. Sigh. Also, apr_strftime() doesn't
- offer format codes for its special tm_usec and tm_gmtoff fields. */
   t_cstr = apr_psprintf (pool,
                          timestamp_format,
+ exploded_time.tm_year + 1900,
+ exploded_time.tm_mon + 1,
+ exploded_time.tm_mday,
+ exploded_time.tm_hour,
+ exploded_time.tm_min,
+ exploded_time.tm_sec,
+ exploded_time.tm_usec);
+ */
+
+ t_cstr = apr_psprintf (pool,
+ old_timestamp_format,
                          apr_day_snames[exploded_time.tm_wday],
                          exploded_time.tm_mday,
                          apr_month_snames[exploded_time.tm_mon],
@@ -95,30 +122,6 @@
 }
 
 
-/* ### todo:
-
- Recently Branko changed svn_time_from_string (or rather, he changed
- svn_wc__string_to_time, but the function's name has changed since
- then) to use apr_implode_gmt. So now that function is using GMT,
- but its inverse above, svn_time_to_string, is using localtime.
-
- I'm not sure what the right thing to do is; see issue #404. See
- also the thread entitled "apr_implode_time and time zones" in the
- APR dev mailing list archives:
-
- http://apr.apache.org/mail/dev/200106.gz
-
- That discussion between Branko and David Reid is directly
- relevant.
-
- Note that Subversion repositories probably want to record commit
- dates in GMT. Maybe we should just make Subversion's string
- representation for times always use GMT -- that's good for
- repositories, and for working copies it doesn't really matter since
- humans don't have to read the timestamps in SVN/entries files much
- (and when they do, they can easily do the conversion). */
-
-
 apr_time_t
 svn_time_from_nts (const char *data)
 {
@@ -126,26 +129,56 @@
   char wday[4], month[4];
   apr_time_t when;
 
- sscanf (data,
- timestamp_format,
- wday,
- &exploded_time.tm_mday,
- month,
- &exploded_time.tm_year,
- &exploded_time.tm_hour,
- &exploded_time.tm_min,
- &exploded_time.tm_sec,
- &exploded_time.tm_usec,
- &exploded_time.tm_yday,
- &exploded_time.tm_isdst,
- &exploded_time.tm_gmtoff);
-
- exploded_time.tm_year -= 1900;
- exploded_time.tm_yday -= 1;
- exploded_time.tm_wday = find_matching_string (wday, apr_day_snames);
- exploded_time.tm_mon = find_matching_string (month, apr_month_snames);
-
- apr_implode_gmt (&when, &exploded_time);
+ /* First try the new timestamp format. */
+ if (sscanf (data,
+ timestamp_format,
+ &exploded_time.tm_year,
+ &exploded_time.tm_mon,
+ &exploded_time.tm_mday,
+ &exploded_time.tm_hour,
+ &exploded_time.tm_min,
+ &exploded_time.tm_sec,
+ &exploded_time.tm_usec) == 7)
+ {
+ exploded_time.tm_year -= 1900;
+ exploded_time.tm_mon -= 1;
+ exploded_time.tm_wday = 0;
+ exploded_time.tm_yday = 0;
+ exploded_time.tm_isdst = 0;
+ exploded_time.tm_gmtoff = 0;
+
+ apr_implode_gmt (&when, &exploded_time);
+ }
+ /* Then try the compatibility option. */
+ else if (sscanf (data,
+ old_timestamp_format,
+ wday,
+ &exploded_time.tm_mday,
+ month,
+ &exploded_time.tm_year,
+ &exploded_time.tm_hour,
+ &exploded_time.tm_min,
+ &exploded_time.tm_sec,
+ &exploded_time.tm_usec,
+ &exploded_time.tm_yday,
+ &exploded_time.tm_isdst,
+ &exploded_time.tm_gmtoff) == 11)
+ {
+ exploded_time.tm_year -= 1900;
+ exploded_time.tm_yday -= 1;
+ exploded_time.tm_wday = find_matching_string (wday, apr_day_snames);
+ exploded_time.tm_mon = find_matching_string (month, apr_month_snames);
+
+ apr_implode_gmt (&when, &exploded_time);
+ }
+ /* Timestamp is something we do not recognize. */
+ else
+ {
+ /* XXX: fix this function to return real error codes and all the
+ places that use it. */
+ /* Better zero than something random. */
+ when = 0;
+ }
 
   return when;
 }

Property changes on: ./subversion/tests/libsvn_subr
___________________________________________________________________
Name: svn:ignore
   - Debug
Release
.libs
hashdump-test
hashdump.out
hashdump2.out
stringtest
stringtest.tmp
target-test
stream-test
path-test
subst-test
*.src
*.dst
z
*.o
*~
.*~

   + Debug
Release
.libs
hashdump-test
hashdump.out
hashdump2.out
stringtest
stringtest.tmp
target-test
stream-test
path-test
subst-test
time-test
*.src
*.dst
z
*.o
*~
.*~

Index: ./subversion/tests/libsvn_subr/time-test.c
===================================================================
--- ./subversion/tests/libsvn_subr/time-test.c
+++ ./subversion/tests/libsvn_subr/time-test.c Fri May 24 01:49:12 2002
@@ -0,0 +1,166 @@
+/*
+ * time-test.c -- test the time functions
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2002 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <apr_general.h>
+#include "svn_time.h"
+#include "svn_test.h"
+
+/* All these variables should refer to the same point in time. */
+apr_time_t test_timestamp = APR_TIME_C(1021316450966679);
+const char *test_timestring =
+"2002-05-13T19:00:50.966679Z";
+const char *test_old_timestring =
+"Mon 13 May 2002 22:00:50.966679 (day 133, dst 1, gmt_off 010800)";
+
+
+static svn_error_t *
+test_time_to_nts (const char **msg,
+ svn_boolean_t msg_only,
+ apr_pool_t *pool)
+{
+ const char *timestring;
+
+ *msg = "test svn_time_to_nts";
+
+ if (msg_only)
+ return SVN_NO_ERROR;
+
+ timestring = svn_time_to_nts(test_timestamp,pool);
+
+ if (strcmp(timestring,test_timestring) != 0)
+ {
+ return svn_error_createf
+ (SVN_ERR_TEST_FAILED, 0, NULL, pool,
+ "svn_time_to_nts (%" APR_TIME_T_FMT
+ ") returned date string '%s' instead of '%s'",
+ test_timestamp,timestring,test_timestring);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+test_time_from_nts (const char **msg,
+ svn_boolean_t msg_only,
+ apr_pool_t *pool)
+{
+ apr_time_t timestamp;
+
+ *msg = "test svn_time_from_nts";
+
+ if (msg_only)
+ return SVN_NO_ERROR;
+
+ timestamp = svn_time_from_nts(test_timestring);
+
+ if (timestamp != test_timestamp)
+ {
+ return svn_error_createf
+ (SVN_ERR_TEST_FAILED, 0, NULL, pool,
+ "svn_time_from_nts (%s) returned time '%" APR_TIME_T_FMT
+ "' instead of '%" APR_TIME_T_FMT "'",
+ test_timestring,timestamp,test_timestamp);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+test_time_from_nts_old (const char **msg,
+ svn_boolean_t msg_only,
+ apr_pool_t *pool)
+{
+ apr_time_t timestamp;
+
+ *msg = "test svn_time_from_nts (old format)";
+
+ if (msg_only)
+ return SVN_NO_ERROR;
+
+ timestamp = svn_time_from_nts(test_old_timestring);
+
+ if (timestamp != test_timestamp)
+ {
+ return svn_error_createf
+ (SVN_ERR_TEST_FAILED, 0, NULL, pool,
+ "svn_time_from_nts (%s) returned time '%" APR_TIME_T_FMT
+ "' instead of '%" APR_TIME_T_FMT "'",
+ test_old_timestring,timestamp,test_timestamp);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+test_time_invariant (const char **msg,
+ svn_boolean_t msg_only,
+ apr_pool_t *pool)
+{
+ apr_time_t current_timestamp = apr_time_now();
+ const char *timestring;
+ apr_time_t timestamp;
+
+ *msg = "test svn_time_to_nts and svn_time_from_nts invariant";
+
+ if (msg_only)
+ return SVN_NO_ERROR;
+
+ timestring = svn_time_to_nts(current_timestamp,pool);
+ timestamp = svn_time_from_nts(timestring);
+
+ if (timestamp != current_timestamp)
+ {
+ return svn_error_createf
+ (SVN_ERR_TEST_FAILED, 0, NULL, pool,
+ "svn_time_from_nts ( svn_time_to_nts (n) ) returned time '%" APR_TIME_T_FMT
+ "' instead of '%" APR_TIME_T_FMT "'",
+ timestamp,current_timestamp);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+
+/* The test table. */
+
+svn_error_t * (*test_funcs[]) (const char **msg,
+ svn_boolean_t msg_only,
+ apr_pool_t *pool) = {
+ 0,
+ /* XXX: enable after new timestamps are in use */
+ /* test_time_to_nts, */
+ test_time_from_nts,
+ test_time_from_nts_old,
+ test_time_invariant,
+ 0
+};
+
+
+
+/*
+ * local variables:
+ * eval: (load-file "../../../tools/dev/svn-dev.el")
+ * end:
+ */
+

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri May 24 01:30:57 2002

This is an archived mail posted to the Subversion Dev mailing list.