iso-8601 sub-seconds problem w/patch

Keith James <[email protected]>
Newsgroups gmane.lisp.clsql.devel
Message-ID <[email protected]>
I came across a problem fetching timestamps (timestamp without time
zone) from a Linux PostgreSQL 8.01 database using clsql-3.1.7.

The timestamps look like this:

 2005-04-01 00:40:43.842878+01

The function syntax-parse-iso-8601 in time.lisp misinterprets the
fractional seconds and silently returns NIL for the gmt-sec-offset,
causing a subsequent failure.

I checked iso-8601 and it seems the sub-second precision may be of
arbitrary precision and separated from the seconds by '.' or ','.

I've attached a patch which simply skips over the sub-second field and
handles the gmt-sec-offset as before.

thanks,


--- time.lisp.orig      2004-09-15 17:45:22.000000000 +0100
+++ time.lisp   2005-04-01 00:46:52.000000000 +0100
@@ -1084,26 +1084,35 @@
                :offset offset)))


+;; Allows for legitimate fractions of seconds to be present without a parse
+;; error e.g. 2005-03-31 20:59:34.615165+01 or 2005-03-31 20:59:34,615165+01
+
 (defun syntax-parse-iso-8601 (string)
-  (let (year month day hour minute second gmt-sec-offset)
+  (let ((strlen (length string))
+        year month day hour minute second gmt-sec-offset)
     (handler-case
         (progn
-          (setf year   (parse-integer (subseq string 0 4))
-                month  (parse-integer (subseq string 5 7))
-                day    (parse-integer (subseq string 8 10))
-                hour   (if (<= 13 (length string))
-                           (parse-integer (subseq string 11 13))
-                           0)
-                minute (if (<= 16 (length string))
-                           (parse-integer (subseq string 14 16))
-                           0)
-                second (if (<= 19 (length string))
-                           (parse-integer (subseq string 17 19))
-                           0)
-                gmt-sec-offset (if (<= 22 (length string))
-                                   (* 60 60
-                                      (parse-integer (subseq string 19 22)))
-                                   0))
+          (setf year           (parse-integer (subseq string 0 4))
+                month          (parse-integer (subseq string 5 7))
+                day            (parse-integer (subseq string 8 10))
+                hour           (if (<= 13 strlen)
+                                   (parse-integer (subseq string 11 13))
+                                 0)
+                minute         (if (<= 16 strlen)
+                                   (parse-integer (subseq string 14 16))
+                                 0)
+                second         (if (<= 19 strlen)
+                                   (parse-integer (subseq string 17 19))
+                                 0)
+                gmt-sec-offset (if (<= 20 strlen)
+                                   (let ((skip-to (or (position #\+ string :start 19)
+                                                      (position #\- string :start 19))))
+                                     (if skip-to
+                                         (* 60 60
+                                            (parse-integer (subseq string skip-to
+                                                                   (+ skip-to 3))))
+                                       0))
+                                 0))
           (unless (< 0 year)
             (error 'iso-8601-syntax-error
                    :bad-component '(year . 0)))
@@ -1122,3 +1131,4 @@
                                (day . ,day) (hour ,hour)
                                (minute ,minute) (second ,second)
                                (timezone ,gmt-sec-offset)))))))))


-- 

- Keith James <[email protected]> - Human Genetics Informatics -
- The Wellcome Trust Sanger Institute, Hinxton, Cambridge, UK -
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.