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

[PATCH] ISO-8601 date patch #1

From: Nuutti Kotivuori <naked_at_iki.fi>
Date: 2002-05-23 08:57:19 CEST

I've been terribly busy with work - and right now I'm late for work.

But, here's the patch to add parsing for new and old style dates, but
generates still old dates. The change to generating old style dates is
a bit of a hack and would need better comments, but it's going to be
in the tree for a few weeks maximum. Oh and it works on local tests
and possibly over DAV - I haven't been able to verify whether it
started working for me or if I just made a mistake and thought it did.

So, unless someone screams bloody murder here today, I'll commit
this. I can fix minor grievances later.

I won't be around during the weekend (or maybe a bit on sunday), but
hopefully I can fix any major bugs before that. Then when pre-alpha
tarball comes out, we can switch to the real support. I'll also be
working on the other issues related to this change, but I do not know
the timing for them.

But, here goes.
-- Naked

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 Sun May 19 18:25:28 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"
+
+
+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 Thu May 23 08:59:46 2002

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.