A patch to fix this is attached. The ISO 8601 date formats were implemented by using the ~Y formatter for the year portion, but SRFI-19 doesn't require ~Y to follow ISO 8601, so this raises the question of whether ~Y should. It could be fixed by changing ~Y to conform to ISO 8601, retaining the existing factoring of the formatters. Or a separate internal formatting function could be instituted to do ISO 8601 year formatting, with ~1 et al using that and ~Y left unchanged. I chose the former strategy, partly because the funny non-linear year number doesn't seem a useful thing to support in date->string at all, but more strongly because it's useful to have access to ISO 8601 year formatting on its own. There isn't any other format specifier for that job; it looks like SRFI-19 imagines that ~Y will fill that need.
-zefram
>From 43dfb5fabc9debb80f87b17d82a1adde356e547c Mon Sep 17 00:00:00 2001 From: Zefram <zef...@fysh.org> Date: Thu, 20 Apr 2017 00:42:54 +0100 Subject: [PATCH 1/2] fix SRFI-19's ISO 8601 year syntax The ISO 8601 date formats offered by SRFI-19's date->string function were emitting incorrect syntax for most years. At least four digits of year must be given, but it wasn't padding shorter numbers. And any number with more than four digits requires a leading sign, but this was being omitted for positive numbers. These problems are now fixed. The ISO 8601 date formats were formerly implemented in terms of the ~Y format, which was not specified to be an ISO 8601 format. The fix is achieved by altering ~Y to behave in the ISO 8601 manner, and ~Y is now documented to conform to ISO 8601. Doing it this way means that ISO 8601 year numbering is available in isolation, which is a useful facility not otherwise available. --- doc/ref/srfi-modules.texi | 1 + module/srfi/srfi-19.scm | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index da7850f..8a5f1a0 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -2815,6 +2815,7 @@ with locale decimal point, eg.@: @samp{5.2} @item @nicode{~y} @tab year, two digits, @samp{00} to @samp{99} @item @nicode{~Y} @tab year, full, eg.@: @samp{2003} +(in ISO 8601 format, though SRFI-19 doesn't specify so) @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} diff --git a/module/srfi/srfi-19.scm b/module/srfi/srfi-19.scm index 4b8445f..d4308bb 100644 --- a/module/srfi/srfi-19.scm +++ b/module/srfi/srfi-19.scm @@ -1128,7 +1128,10 @@ 2) port))) (cons #\Y (lambda (date pad-with port) - (display (date-year date) port))) + (let ((y (date-year date))) + (cond ((negative? y) (display #\- port)) + ((>= y 10000) (display #\+ port))) + (display (padding (abs y) #\0 4) port)))) (cons #\z (lambda (date pad-with port) (rfc-822-tz-print (date-zone-offset date) port))) (cons #\Z (lambda (date pad-with port) -- 2.1.4