From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Zefram Newsgroups: gmane.lisp.guile.bugs Subject: bug#21907: date->string duff ISO 8601 zone format Date: Wed, 19 Apr 2017 22:21:46 +0100 Message-ID: <20170419212146.GB912@fysh.org> References: <20151113145913.GQ13455@fysh.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="4SFOXa2GPu3tIq4H" X-Trace: blaine.gmane.org 1492637117 20042 195.159.176.226 (19 Apr 2017 21:25:17 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 19 Apr 2017 21:25:17 +0000 (UTC) To: 21907@debbugs.gnu.org Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Wed Apr 19 23:25:14 2017 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d0x6A-00058L-23 for guile-bugs@m.gmane.org; Wed, 19 Apr 2017 23:25:14 +0200 Original-Received: from localhost ([::1]:50492 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d0x6F-0000DG-RB for guile-bugs@m.gmane.org; Wed, 19 Apr 2017 17:25:19 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52722) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d0x37-0005xN-Ez for bug-guile@gnu.org; Wed, 19 Apr 2017 17:22:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d0x34-0000U2-9K for bug-guile@gnu.org; Wed, 19 Apr 2017 17:22:05 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:59292) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1d0x33-0000Tx-Vv for bug-guile@gnu.org; Wed, 19 Apr 2017 17:22:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1d0x33-00076c-Qg for bug-guile@gnu.org; Wed, 19 Apr 2017 17:22:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Zefram Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Wed, 19 Apr 2017 21:22:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21907 X-GNU-PR-Package: guile X-GNU-PR-Keywords: Original-Received: via spool by 21907-submit@debbugs.gnu.org id=B21907.149263691327301 (code B ref 21907); Wed, 19 Apr 2017 21:22:01 +0000 Original-Received: (at 21907) by debbugs.gnu.org; 19 Apr 2017 21:21:53 +0000 Original-Received: from localhost ([127.0.0.1]:57491 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d0x2v-00076H-0V for submit@debbugs.gnu.org; Wed, 19 Apr 2017 17:21:53 -0400 Original-Received: from river.fysh.org ([87.98.248.19]:51209 ident=Debian-exim) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d0x2r-000767-SQ for 21907@debbugs.gnu.org; Wed, 19 Apr 2017 17:21:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=fysh.org; s=20170316; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:To:From:Date; bh=P1V5KGKUp7XtgPGAAEVhqDroqM01mpgw2/+W0D1FT/U=; b=67FNIo4KBQM2qcDHztL3tKw/np/tDDrh2LDHocicMYMzwTN/q+leG+o7rKpzZdEunPnp/jt4SJBiAstiEEkxRG8bxuXLT0s2E5djgH7f8/+eojmLgnHS8he0QJVEP55CRo8DqdsE9M2Jb9FdfMCzFej0nVRP+Yo86YroyF+O3vE=; Original-Received: from zefram by river.fysh.org with local (Exim 4.84_2 #1 (Debian)) id 1d0x2o-000858-IQ; Wed, 19 Apr 2017 22:21:46 +0100 Content-Disposition: inline In-Reply-To: <20151113145913.GQ13455@fysh.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Original-Sender: "bug-guile" Xref: news.gmane.org gmane.lisp.guile.bugs:8766 Archived-At: --4SFOXa2GPu3tIq4H Content-Type: text/plain; charset=us-ascii Content-Disposition: inline A sequence of two patches is attached. The first fixes the ~2/~4 bug, signalling an error for any unrepresentable offset. The second is a bonus patch, which fixes related problems in ~z, the RFC 822 zone format specifier. Prior to the patch, ~z outputs "Z" for UT, which would be correct for ISO 8601 format but is deprecated (along with all the other single-letter syntax) for RFC 822. The patch changes that to the approved "+0000". ~z also had exactly the same problems as ~2/~4 regarding unrepresentable offsets, so the patch fixes them in the same way. I could report the ~z problems in a separate ticket if you like. Beware that the second of these patches has some textual dependence on the first, so trying to handle them separately might just be confusing. -zefram --4SFOXa2GPu3tIq4H Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-fix-SRFI-19-s-ISO-8601-zone-output-formats.patch" >From e6db0e40e5464591df204f9d07e66b3d7853c0d7 Mon Sep 17 00:00:00 2001 From: Zefram Date: Wed, 19 Apr 2017 21:50:39 +0100 Subject: [PATCH 1/2] fix SRFI-19's ISO 8601 zone output formats The ISO 8601 timezone formats offered by SRFI-19's date->string function, in the ~2 and ~4 format specifiers, were erroneously in the basic format despite juxtaposition with extended-format date and time. Fix that by switching them to extended format. This incidentally means that the ISO 8601 zone format is no longer implemented as identical to the RFC 822 zone format (~z), so stop documenting them in terms of ~z. The same format specifiers also made too much of an attempt to display zone offsets that are not representable in ISO 8601 format. They would truncate an offset that is not an integral number of minutes, thus producing inaccurate output. The truncation of an offset in the range (-60, 0) yielded a non-conforming "-0000". An offset of 100 hours or more (in either direction) resulted in non-conforming extra digits. In all of these cases, signal as an error that the zone offset is not representable. --- doc/ref/srfi-modules.texi | 4 ++-- module/srfi/srfi-19.scm | 22 +++++++++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index ec3bb20..da7850f 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -2818,9 +2818,9 @@ with locale decimal point, eg.@: @samp{5.2} @item @nicode{~z} @tab time zone, RFC-822 style @item @nicode{~Z} @tab time zone symbol (not currently implemented) @item @nicode{~1} @tab ISO-8601 date, @samp{~Y-~m-~d} -@item @nicode{~2} @tab ISO-8601 time+zone, @samp{~H:~M:~S~z} +@item @nicode{~2} @tab ISO-8601 time+zone, @samp{~3} plus zone @item @nicode{~3} @tab ISO-8601 time, @samp{~H:~M:~S} -@item @nicode{~4} @tab ISO-8601 date/time+zone, @samp{~Y-~m-~dT~H:~M:~S~z} +@item @nicode{~4} @tab ISO-8601 date/time+zone, @samp{~5} plus zone @item @nicode{~5} @tab ISO-8601 date/time, @samp{~Y-~m-~dT~H:~M:~S} @end multitable @end defun diff --git a/module/srfi/srfi-19.scm b/module/srfi/srfi-19.scm index f09ec7a..ed88242 100644 --- a/module/srfi/srfi-19.scm +++ b/module/srfi/srfi-19.scm @@ -152,7 +152,6 @@ (define locale-date-time-format "~a ~b ~d ~H:~M:~S~z ~Y") (define locale-short-date-format "~m/~d/~y") (define locale-time-format "~H:~M:~S") -(define iso-8601-date-time-format "~Y-~m-~dT~H:~M:~S~z") ;;-- Miscellaneous Constants. ;;-- only the tai-epoch-in-jd might need changing if @@ -970,6 +969,21 @@ (display (padding hours #\0 2) port) (display (padding minutes #\0 2) port)))) +(define (iso-8601-tz-print offset port) + (let* ((neg? (negative? offset)) + (all-secs (abs offset)) + (seconds (remainder all-secs 60)) + (all-mins (quotient all-secs 60)) + (minutes (remainder all-mins 60)) + (hours (quotient all-mins 60))) + (if (or (not (= seconds 0)) (> hours 99)) + (time-error 'date-printer 'unrepresentable-zone-offset offset) + (begin + (display (if neg? #\- #\+) port) + (display (padding hours #\0 2) port) + (display #\: port) + (display (padding minutes #\0 2) port))))) + ;; A table of output formatting directives. ;; the first time is the format char. ;; the second is a procedure that takes the date, a padding character @@ -1119,11 +1133,13 @@ (cons #\1 (lambda (date pad-with port) (display (date->string date "~Y-~m-~d") port))) (cons #\2 (lambda (date pad-with port) - (display (date->string date "~H:~M:~S~z") port))) + (display (date->string date "~3") port) + (iso-8601-tz-print (date-zone-offset date) port))) (cons #\3 (lambda (date pad-with port) (display (date->string date "~H:~M:~S") port))) (cons #\4 (lambda (date pad-with port) - (display (date->string date "~Y-~m-~dT~H:~M:~S~z") port))) + (display (date->string date "~5") port) + (iso-8601-tz-print (date-zone-offset date) port))) (cons #\5 (lambda (date pad-with port) (display (date->string date "~Y-~m-~dT~H:~M:~S") port))))) -- 2.1.4 --4SFOXa2GPu3tIq4H Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0002-fix-SRFI-19-s-RFC-822-zone-output-format.patch" >From 3c78db919ba705a5e3f1b1ac919a473b709d26c6 Mon Sep 17 00:00:00 2001 From: Zefram Date: Wed, 19 Apr 2017 22:06:35 +0100 Subject: [PATCH 2/2] fix SRFI-19's RFC 822 zone output format The RFC 822 timezone format offered by SRFI-19's date->string function, the ~z format specifier, was using the deprecated "Z" format for +0000. Change it to the non-deprecated "+0000". The same format specifier also made too much of an attempt to display zone offsets that are not representable in RFC 822 format. It would truncate an offset that is not an integral number of minutes, thus producing inaccurate output. The truncation of an offset in the range (-60, 0) yielded a non-conforming "-0000". An offset of 100 hours or more (in either direction) resulted in non-conforming extra digits. In all of these cases, signal as an error that the zone offset is not representable. --- module/srfi/srfi-19.scm | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/module/srfi/srfi-19.scm b/module/srfi/srfi-19.scm index ed88242..4b8445f 100644 --- a/module/srfi/srfi-19.scm +++ b/module/srfi/srfi-19.scm @@ -953,21 +953,24 @@ ;; FIXME: mkoeppe: Put a symbolic time zone in the date structs. ;; Print it here instead of the numerical offset if available. (define (locale-print-time-zone date port) - (tz-printer (date-zone-offset date) port)) + (rfc-822-tz-print (date-zone-offset date) port)) (define (locale-am-string/pm hr) (if (> hr 11) (locale-pm-string) (locale-am-string))) -(define (tz-printer offset port) - (cond - ((= offset 0) (display "Z" port)) - ((negative? offset) (display "-" port)) - (else (display "+" port))) - (if (not (= offset 0)) - (let ((hours (abs (quotient offset (* 60 60)))) - (minutes (abs (quotient (remainder offset (* 60 60)) 60)))) +(define (rfc-822-tz-print offset port) + (let* ((neg? (negative? offset)) + (all-secs (abs offset)) + (seconds (remainder all-secs 60)) + (all-mins (quotient all-secs 60)) + (minutes (remainder all-mins 60)) + (hours (quotient all-mins 60))) + (if (or (not (= seconds 0)) (> hours 99)) + (time-error 'date-printer 'unrepresentable-zone-offset offset) + (begin + (display (if neg? #\- #\+) port) (display (padding hours #\0 2) port) - (display (padding minutes #\0 2) port)))) + (display (padding minutes #\0 2) port))))) (define (iso-8601-tz-print offset port) (let* ((neg? (negative? offset)) @@ -1127,7 +1130,7 @@ (cons #\Y (lambda (date pad-with port) (display (date-year date) port))) (cons #\z (lambda (date pad-with port) - (tz-printer (date-zone-offset date) port))) + (rfc-822-tz-print (date-zone-offset date) port))) (cons #\Z (lambda (date pad-with port) (locale-print-time-zone date port))) (cons #\1 (lambda (date pad-with port) -- 2.1.4 --4SFOXa2GPu3tIq4H--