Subject: bug#21904: date->string duff ISO 8601 format for non-4-digit years

From: Mark H Weaver <[email-masked]>
Date: Sat, 20 Oct 2018 20:34:10 -0400

Zefram <[email-masked]> writes:

> For year numbers 10000 and above, it is necessary to use more than four
> digits for the year, and that's permitted, but ISO 8601 requires that
> more than four digits are preceded by a sign.  For positive year numbers
> the sign must be "+".  So one should write "+22666" rather than "22666",
> for example.

I skimmed a draft of ISO 8601 that I was able to find gratis online:

  https://web.archive.org/web/20171019211402/https://www.loc.gov/standards/datetime/ISO_DIS%208601-1.pdf
  https://web.archive.org/web/20171020000043/https://www.loc.gov/standards/datetime/ISO_DIS%208601-2.pdf

and also the ISO 8601 Wikipedia page:

  https://en.wikipedia.org/wiki/ISO_8601#Years

and I'm left with a different interpretation about what the standard
permits.  As the Wikipedia page says:

  To represent years before 0000 or after 9999, the standard also
  permits the expansion of the year representation but only by prior
  agreement between the sender and the receiver.[19] An expanded year
  representation [±YYYYY] must have an agreed-upon number of extra year
  digits beyond the four-digit minimum, and it must be prefixed with a +
  or − sign[20] [...]

Note the words "but only by prior agreement between the sender and the
receiver", and "must have an agreed-upon number of extra year digits".

You seem to have reached the conclusion that the sender can choose the
number of digits dynamically, leaving the receiver to auto-detect the
number of digits, but that seems to contradict to requirements given
above.

My interpretation is that although ISO 8601 permits the use of expanded
year formats, it seems to require that in a given format, the year must
have a fixed number of digits, and it must _always_ include a sign.  In
other words, the receiver should know ahead of time, by prior agreement,
how many digits to expect, and there should _always_ be a sign, even if
the year happens to be in the range 0-9999.

In order to support years outside the range 0-9999 and in accordance
with ISO 8601, I think that 'date->string' and 'string->date' would need
to be extended to allow the caller to specify how many digits to use in
the expanded 'year' format, presumably by adding a new format escape.
If the specified number of digits is greater than 4, then a sign would
*always* be printed.  'string->date' would know how many digits to
expect, and whether to expect a sign.

Ideally, such an extension of 'date->string' and 'string->date' would be
adopted by upstream SRFI-19.  However, if that's unsuccessful, I'd be
open to unilaterally adding such an extension.  There's precedent for
this in Guile, e.g. see our (srfi srfi-9 gnu) extensions to SRFI-9.

Another question is whether or not we should raise an exception when
attempting to print a year that cannot be represented in the requested
year format.

What do you think?

      Mark