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 -