>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