On 19/09/15 17:46, Michael Gold wrote:
> Package: coreutils
> Version: 8.23-4
> Severity: minor
> 
> The manual page for 'date' says --iso-8601 will "output date/time in ISO
> 8601 format", but I don't believe the format actually complies with that
> standard when a time is included.
> 
> §4.3.3d says (http://dotat.at/tmp/ISO_8601-2004_E.pdf#):
> "the expression shall either be completely in basic format, in which
> case the minimum number of separators necessary for the required
> expression is used, or completely in extended format, in which case
> additional separators shall be used in accordance with 4.1 and 4.2."
> 
> But --iso-8601=m uses extended format for the date and time, and basic
> format for the timezone.  Since making the option actually use ISO 8601
> format could break scripts, a note in the manual page is probably the
> best fix.  E.g.,
>   "output date/time in ISO 8601 extended format, except for the time
>   zone which will be output in basic format when a time is included and
>   omitted otherwise"
> 
> - Michael

I agree with the above analysis.
I.E. the tz portion should contain a ':' like
  2015-10-23T01:49+01:00

Note date(1) can parse either basic or extended tz:

  $ date --date='2015-10-23T01:49+01:30'
  Fri Oct 23 01:19:00 IST 2015

As can python's iso8601 module for example.

I see the code in date uses %:z (extended format) for --rfc-3339
but %z (basic format) for --iso-8601.  That's because %:z support wasn't
added to gnulib's strftime until 2005, while the --iso-8601 option
was added in 1999.

So there is the possibility of changing the output format
to conform to the standard. How likely is that to break things?
One possibility is that file names might be generated with
`date -Im`, but would even that be likely to break things?

Attached is the change to date(1) to adjust the output format,
and if this is thought too risky, we can instead just
augment the info docs with Michael's comment above.

thanks,
Pádraig.
From f8549660f20a3a394455a6f652ba6d167c1eb3cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Fri, 23 Oct 2015 03:19:18 +0100
Subject: [PATCH] date: use extended format timezone for --iso-8601

* src/date.c (main): Use %:z rather than %z with --iso-8601
as the standard states to consistently use extended format.
Note either format can be parsed by date.
* tests/misc/date.pl: Adjust accordingly.
* doc/coreutils.texi (du invocation): Clarify that "iso"
time styles are only similar to ISO-8601.
(ls invocation): Likewise.
(date invocation): Adjust the comment stating
that only --rfc-3339 output can be parsed by date(1).
* NEWS: Mention the change in behavior.
Reported at http://bugs.debian.org/799479
---
 NEWS               |  3 +++
 doc/coreutils.texi | 28 ++++++++++++++++------------
 src/date.c         |  8 ++++----
 tests/misc/date.pl |  8 ++++----
 4 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/NEWS b/NEWS
index e771585..4780494 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   base64 no longer supports hex or oct --wrap parameters,
   thus better supporting decimals with leading zeros.
 
+  date --iso-8601 now uses +00:00 timezone format rather than +0000.
+  The standard states to use this "extended" format throughout a timestamp.
+
   df now prefers sources towards the root of a device when
   eliding duplicate bind mounted entries.
 
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 1b81daa..b1ba097 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -7498,8 +7498,8 @@ files; if you want output columns to line up, you may need to insert
 spaces in one of the two formats.
 
 @item full-iso
-List timestamps in full using ISO 8601 date, time, and time zone
-format with nanosecond precision, e.g., @samp{2002-03-30
+List timestamps in full using ISO 8601 like date, time, and time zone
+components with nanosecond precision, e.g., @samp{2002-03-30
 23:45:56.477817180 -0700}.  This style is equivalent to
 @samp{+%Y-%m-%d %H:%M:%S.%N %z}.
 
@@ -7509,14 +7509,14 @@ explain @command{make}'s behavior, since GNU @command{make}
 uses the full timestamp to determine whether a file is out of date.
 
 @item long-iso
-List ISO 8601 date and time in minutes, e.g.,
+List ISO 8601 like date and time in minutes, e.g.,
 @samp{2002-03-30 23:45}.  These timestamps are shorter than
 @samp{full-iso} timestamps, and are usually good enough for everyday
 work.  This style is equivalent to @samp{+%Y-%m-%d %H:%M}.
 
 @item iso
 List ISO 8601 dates for non-recent timestamps (e.g.,
-@samp{2002-03-30@ }), and ISO 8601 month, day, hour, and
+@samp{2002-03-30@ }), and ISO 8601 like month, day, hour, and
 minute for recent timestamps (e.g., @samp{03-30 23:45}).  These
 timestamps are uglier than @samp{long-iso} timestamps, but they carry
 nearly the same information in a smaller space and their brevity helps
@@ -11491,13 +11491,13 @@ with @command{date}, @var{format}'s interpretation is affected by the
 @env{LC_TIME} locale category.
 
 @item full-iso
-List timestamps in full using ISO 8601 date, time, and time zone
-format with nanosecond precision, e.g., @samp{2002-03-30
+List timestamps in full using ISO 8601 like date, time, and time zone
+components with nanosecond precision, e.g., @samp{2002-03-30
 23:45:56.477817180 -0700}.  This style is equivalent to
 @samp{+%Y-%m-%d %H:%M:%S.%N %z}.
 
 @item long-iso
-List ISO 8601 date and time in minutes, e.g.,
+List ISO 8601 like date and time in minutes, e.g.,
 @samp{2002-03-30 23:45}.  These timestamps are shorter than
 @samp{full-iso} timestamps, and are usually good enough for everyday
 work.  This style is equivalent to @samp{+%Y-%m-%d %H:%M}.
@@ -15239,7 +15239,13 @@ Append the hours, minutes, seconds and nanoseconds.
 @end table
 
 If showing any time terms, then include the time zone using the format
-@samp{%z}.
+@samp{%:z}.
+@macro dateParseNote
+This format is always suitable as input
+for the @option{--date} (@option{-d}) and @option{--file}
+(@option{-f}) options, regardless of the current locale.
+@end macro
+@dateParseNote
 
 @item -r @var{file}
 @itemx --reference=@var{file}
@@ -15274,10 +15280,8 @@ Display the date using a format specified by
 @uref{ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt, Internet
 RFC 3339}.  This is a subset of the ISO 8601
 format, except that it also permits applications to use a space rather
-than a @samp{T} to separate dates from times.  Unlike the other
-standard formats, RFC 3339 format is always suitable as
-input for the @option{--date} (@option{-d}) and @option{--file}
-(@option{-f}) options, regardless of the current locale.
+than a @samp{T} to separate dates from times.
+@dateParseNote
 
 The argument @var{timespec} specifies how much of the time to include.
 It can be one of the following:
diff --git a/src/date.c b/src/date.c
index fae0256..bf1434d 100644
--- a/src/date.c
+++ b/src/date.c
@@ -382,10 +382,10 @@ main (int argc, char **argv)
             static char const iso_8601_format[][32] =
               {
                 "%Y-%m-%d",
-                "%Y-%m-%dT%H:%M:%S%z",
-                "%Y-%m-%dT%H:%M:%S,%N%z",
-                "%Y-%m-%dT%H%z",
-                "%Y-%m-%dT%H:%M%z"
+                "%Y-%m-%dT%H:%M:%S%:z",
+                "%Y-%m-%dT%H:%M:%S,%N%:z",
+                "%Y-%m-%dT%H%:z",
+                "%Y-%m-%dT%H:%M%:z"
               };
             enum Time_spec i =
               (optarg
diff --git a/tests/misc/date.pl b/tests/misc/date.pl
index 6a7c6f8..ad07fa4 100755
--- a/tests/misc/date.pl
+++ b/tests/misc/date.pl
@@ -203,17 +203,17 @@ my @Tests =
      ['moname-d-y-r', '--rfc-3339=date -d May-23-2003', {OUT=>"2003-05-23"}],
 
      ['epoch', '--iso=sec -d @31536000',
-      {OUT=>"1971-01-01T00:00:00+0000"}],
+      {OUT=>"1971-01-01T00:00:00+00:00"}],
      ['epoch-r', '--rfc-3339=sec -d @31536000',
       {OUT=>"1971-01-01 00:00:00+00:00"}],
 
      ['ns-10', '--iso=ns', '-d "1969-12-31 13:00:00.00000001-1100"',
-      {OUT=>"1970-01-01T00:00:00,000000010+0000"}],
+      {OUT=>"1970-01-01T00:00:00,000000010+00:00"}],
      ['ns-10-r', '--rfc-3339=ns', '-d "1969-12-31 13:00:00.00000001-1100"',
       {OUT=>"1970-01-01 00:00:00.000000010+00:00"}],
 
      ['ns-max32', '--iso=ns', '-d "2038-01-19 03:14:07.999999999"',
-      {OUT=>"2038-01-19T03:14:07,999999999+0000"}],
+      {OUT=>"2038-01-19T03:14:07,999999999+00:00"}],
      ['ns-max32-r', '--rfc-3339=ns', '-d "2038-01-19 03:14:07.999999999"',
       {OUT=>"2038-01-19 03:14:07.999999999+00:00"}],
 
@@ -235,7 +235,7 @@ my @Tests =
      ['ns-relative',
       '--iso=ns',
       "-d'1970-01-01 00:00:00.1234567 UTC +961062237.987654321 sec'",
-      {OUT=>"2000-06-15T09:43:58,111111021+0000"}],
+      {OUT=>"2000-06-15T09:43:58,111111021+00:00"}],
      ['ns-relativer', '--rfc-3339=ns',
       "-d'1970-01-01 00:00:00.1234567 UTC +961062237.987654321 sec'",
       {OUT=>"2000-06-15 09:43:58.111111021+00:00"}],
-- 
2.5.0

Reply via email to