From: Erik Wienhold <ewie@ewie.name>
Subject: [PATCH v1] Fix references to ISO 8601
Date: Sun, 19 Nov 2023 19:18:07 +0100
* Name the exact edition in sources and docs that reference particular
sections of the standard. ISO 8601:2019 edition was published since
then. So we should spell it out that we reference ISO 8601:2004 to
avoid confusion because other editions have different section numbers
and titles.
* Fix a typo in references to sections 4.4.4.2.1 and 4.4.4.2.2 in
ISO 8601:2004.
* Fix a reference to the ISO 8601:1988 where the edition is not relevant
because it does not name a particular section but only the general
concept of week numbers.
* Fix general references to ISO 8601 in the docs of the datetime data
types. Remove claims that the SQL standard requires ISO 8601 formats.
SQL only references ISO 8601 to define "date" and UTC, but defines its
own date and time syntax. Postgres implements ISO 8601 formats in
addition to the standard.
* Fix time zone input examples that are described as ISO 8601 but do not
match the standard syntax by omitting the leading zero of the hour
component.
---
doc/src/sgml/config.sgml | 2 +-
doc/src/sgml/datatype.sgml | 26 ++++++++++------------
src/backend/utils/adt/datetime.c | 12 +++++-----
src/interfaces/ecpg/pgtypeslib/interval.c | 10 ++++-----
src/interfaces/ecpg/pgtypeslib/timestamp.c | 2 +-
src/test/regress/expected/interval.out | 4 ++--
src/test/regress/sql/interval.sql | 4 ++--
7 files changed, 29 insertions(+), 31 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgmlindex fc35a46e5e..a1a3981dd9 100644--- a/doc/src/sgml/config.sgml+++ b/doc/src/sgml/config.sgml@@ -9526,7 +9526,7 @@ SET XML OPTION { DOCUMENT | CONTENT };
parameter was set to non-<literal>ISO</literal> output.
The value <literal>iso_8601</literal> will produce output matching the time
interval <quote>format with designators</quote> defined in section
- 4.4.3.2 of ISO 8601.+ 4.4.3.2 of ISO 8601:2004.
</para>
<para>
The <varname>IntervalStyle</varname> parameter also affects the
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgmlindex e4a7b07033..1c54305e25 100644--- a/doc/src/sgml/datatype.sgml+++ b/doc/src/sgml/datatype.sgml@@ -2088,7 +2088,7 @@ MINUTE TO SECOND
<entry>same as 16:05; input hour must be <= 12</entry>
</row>
<row>
- <entry><literal>04:05:06.789-8</literal></entry>+ <entry><literal>04:05:06.789-08</literal></entry>
<entry>ISO 8601, with time zone as UTC offset</entry>
</row>
<row>
@@ -2150,16 +2150,16 @@ MINUTE TO SECOND
<entry>UTC offset for PST</entry>
</row>
<row>
- <entry><literal>-8:00</literal></entry>+ <entry><literal>-08:00</literal></entry>
<entry>UTC offset for PST (ISO 8601 extended format)</entry>
</row>
<row>
- <entry><literal>-800</literal></entry>+ <entry><literal>-0800</literal></entry>
<entry>UTC offset for PST (ISO 8601 basic format)</entry>
</row>
<row>
- <entry><literal>-8</literal></entry>- <entry>UTC offset for PST (ISO 8601 basic format)</entry>+ <entry><literal>-08</literal></entry>+ <entry>UTC offset for PST (ISO 8601)</entry>
</row>
<row>
<entry><literal>zulu</literal></entry>
@@ -2207,7 +2207,7 @@ MINUTE TO SECOND
</programlisting>
and:
<programlisting>
-1999-01-08 04:05:06 -8:00+1999-01-08 04:05:06 -08:00
</programlisting>
are valid values, which follow the <acronym>ISO</acronym> 8601
@@ -2416,15 +2416,13 @@ TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
(Unix <application>date</application> format), or
German. The default
is the <acronym>ISO</acronym> format. (The
- <acronym>SQL</acronym> standard requires the use of the ISO 8601- format. The name of the <quote>SQL</quote> output format is a+ <acronym>SQL</acronym> standard defines <quote>date</quote> in terms of ISO 8601.+ The name of the <quote>SQL</quote> output format is a
historical accident.) <xref
linkend="datatype-datetime-output-table"/> shows examples of each
output style. The output of the <type>date</type> and
<type>time</type> types is generally only the date or time part
- in accordance with the given examples. However, the- <productname>POSTGRES</productname> style outputs date-only values in- <acronym>ISO</acronym> format.+ in accordance with the given examples.
</para>
<table id="datatype-datetime-output-table">
@@ -2771,8 +2769,8 @@ TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
<para>
Interval values can also be written as ISO 8601 time intervals, using
- either the <quote>format with designators</quote> of the standard's section- 4.4.3.2 or the <quote>alternative format</quote> of section 4.4.3.3. The+ either the <quote>format with designators</quote> or the <quote>alternative+ format</quote> (sections 4.4.3.2 and 4.4.3.3 in the 2004 edition). The
format with designators looks like this:
<synopsis>
P <replaceable>quantity</replaceable> <replaceable>unit</replaceable> <optional> <replaceable>quantity</replaceable> <replaceable>unit</replaceable> ...</optional> <optional> T <optional> <replaceable>quantity</replaceable> <replaceable>unit</replaceable> ...</optional></optional>
@@ -2995,7 +2993,7 @@ SELECT EXTRACT(days from '80 hours'::interval);
<para>
The output of the <literal>iso_8601</literal> style matches the <quote>format
with designators</quote> described in section 4.4.3.2 of the
- ISO 8601 standard.+ ISO 8601:2004 standard.
</para>
<table id="interval-style-output-table">
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.cindex fca9a2a6e9..01f36c3aec 100644--- a/src/backend/utils/adt/datetime.c+++ b/src/backend/utils/adt/datetime.c@@ -3724,7 +3724,7 @@ ISO8601IntegerWidth(char *fieldstart)
/* DecodeISO8601Interval()
- * Decode an ISO 8601 time interval of the "format with designators"+ * Decode an ISO 8601:2004 time interval of the "format with designators"
* (section 4.4.3.2) or "alternative format" (section 4.4.3.3)
* Examples: P1D for 1 day
* PT1H for 1 hour
@@ -3805,7 +3805,7 @@ DecodeISO8601Interval(char *str,
!AdjustFractMicroseconds(fval, USECS_PER_DAY, itm_in))
return DTERR_FIELD_OVERFLOW;
break;
- case 'T': /* ISO 8601 4.4.3.3 Alternative Format / Basic */+ case 'T': /* ISO 8601:2004 4.4.3.3 Alternative Format / Basic */
case '\0':
if (ISO8601IntegerWidth(fieldstart) == 8 && !havefield)
{
@@ -3822,7 +3822,7 @@ DecodeISO8601Interval(char *str,
}
/* Else fall through to extended alternative format */
/* FALLTHROUGH */
- case '-': /* ISO 8601 4.4.3.3 Alternative Format,+ case '-': /* ISO 8601:2004 4.4.3.3 Alternative Format,
* Extended */
if (havefield)
return DTERR_BAD_FORMAT;
@@ -3893,7 +3893,7 @@ DecodeISO8601Interval(char *str,
if (!AdjustMicroseconds(val, fval, USECS_PER_SEC, itm_in))
return DTERR_FIELD_OVERFLOW;
break;
- case '\0': /* ISO 8601 4.4.3.3 Alternative Format */+ case '\0': /* ISO 8601:2004 4.4.3.3 Alternative Format */
if (ISO8601IntegerWidth(fieldstart) == 6 && !havefield)
{
if (!AdjustMicroseconds(val / 10000, 0, USECS_PER_HOUR, itm_in) ||
@@ -3905,7 +3905,7 @@ DecodeISO8601Interval(char *str,
}
/* Else fall through to extended alternative format */
/* FALLTHROUGH */
- case ':': /* ISO 8601 4.4.3.3 Alternative Format,+ case ':': /* ISO 8601:2004 4.4.3.3 Alternative Format,
* Extended */
if (havefield)
return DTERR_BAD_FORMAT;
@@ -4596,7 +4596,7 @@ EncodeInterval(struct pg_itm *itm, int style, char *str)
}
break;
- /* ISO 8601 "time-intervals by duration only" */+ /* ISO 8601:2004 4.4.4.2 "time intervals by duration" */
case INTSTYLE_ISO_8601:
/* special-case zero to avoid printing nothing */
if (year == 0 && mon == 0 && mday == 0 &&
diff --git a/src/interfaces/ecpg/pgtypeslib/interval.c b/src/interfaces/ecpg/pgtypeslib/interval.cindex 936a688381..fa23eb2fab 100644--- a/src/interfaces/ecpg/pgtypeslib/interval.c+++ b/src/interfaces/ecpg/pgtypeslib/interval.c@@ -169,7 +169,7 @@ DecodeISO8601Interval(char *str,
tm->tm_mday += val;
AdjustFractSeconds(fval, tm, fsec, SECS_PER_DAY);
break;
- case 'T': /* ISO 8601 4.4.3.3 Alternative Format / Basic */+ case 'T': /* ISO 8601:2004 4.4.3.3 Alternative Format / Basic */
case '\0':
if (ISO8601IntegerWidth(fieldstart) == 8 && !havefield)
{
@@ -185,7 +185,7 @@ DecodeISO8601Interval(char *str,
}
/* Else fall through to extended alternative format */
/* FALLTHROUGH */
- case '-': /* ISO 8601 4.4.3.3 Alternative Format,+ case '-': /* ISO 8601:2004 4.4.3.3 Alternative Format,
* Extended */
if (havefield)
return DTERR_BAD_FORMAT;
@@ -253,7 +253,7 @@ DecodeISO8601Interval(char *str,
tm->tm_sec += val;
AdjustFractSeconds(fval, tm, fsec, 1);
break;
- case '\0': /* ISO 8601 4.4.3.3 Alternative Format */+ case '\0': /* ISO 8601:2004 4.4.3.3 Alternative Format */
if (ISO8601IntegerWidth(fieldstart) == 6 && !havefield)
{
tm->tm_hour += val / 10000;
@@ -264,7 +264,7 @@ DecodeISO8601Interval(char *str,
}
/* Else fall through to extended alternative format */
/* FALLTHROUGH */
- case ':': /* ISO 8601 4.4.3.3 Alternative Format,+ case ':': /* ISO 8601:2004 4.4.3.3 Alternative Format,
* Extended */
if (havefield)
return DTERR_BAD_FORMAT;
@@ -850,7 +850,7 @@ EncodeInterval(struct /* pg_ */ tm *tm, fsec_t fsec, int style, char *str)
}
break;
- /* ISO 8601 "time-intervals by duration only" */+ /* ISO 8601:2004 4.4.4.2 "time intervals by duration" */
case INTSTYLE_ISO_8601:
/* special-case zero to avoid printing nothing */
if (year == 0 && mon == 0 && mday == 0 &&
diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.cindex f1b143fbd2..2fa3f85d01 100644--- a/src/interfaces/ecpg/pgtypeslib/timestamp.c+++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c@@ -596,7 +596,7 @@ dttofmtasc_replace(timestamp * ts, date dDate, int dow, struct tm *tm,
break;
/*
- * The ISO 8601:1988 week number of the current year as a+ * The ISO 8601 week number of the current year as a
* decimal number.
*/
case 'V':
diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.outindex b79b6fcd4d..315efc93f1 100644--- a/src/test/regress/expected/interval.out+++ b/src/test/regress/expected/interval.out@@ -1022,7 +1022,7 @@ select interval '0' AS "zero",
PT0S | P1Y2M | P1DT2H3M4S | PT2H3M4.45679S | P1Y2M3DT4H5M6.7S | P1Y2M-3DT-4H-5M-6.7S | P-1Y-2M3DT4H5M6.7S
(1 row)
--- test inputting ISO 8601 4.4.2.1 "Format With Time Unit Designators"+-- test inputting ISO 8601:2004 4.4.4.2.1 "Format with designators"
SET IntervalStyle to sql_standard;
select interval 'P0Y' AS "zero",
interval 'P1Y2M' AS "a year 2 months",
@@ -1036,7 +1036,7 @@ select interval 'P0Y' AS "zero",
0 | 1-2 | 7 0:00:00 | 1 2:03:04 | +1-2 +3 +4:05:06.7 | -1-2 -3 -4:05:06.7 | -0:00:00.1
(1 row)
--- test inputting ISO 8601 4.4.2.2 "Alternative Format"+-- test inputting ISO 8601:2004 4.4.4.2.2 "Alternative format"
SET IntervalStyle to postgres;
select interval 'P00021015T103020' AS "ISO8601 Basic Format",
interval 'P0002-10-15T10:30:20' AS "ISO8601 Extended Format";
diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sqlindex 5566ad0e51..f4b1ffc424 100644--- a/src/test/regress/sql/interval.sql+++ b/src/test/regress/sql/interval.sql@@ -323,7 +323,7 @@ select interval '0' AS "zero",
(interval '1-2' - interval '3 4:05:06.7') AS "mixed sign",
(- interval '1-2' + interval '3 4:05:06.7') AS "negative";
--- test inputting ISO 8601 4.4.2.1 "Format With Time Unit Designators"+-- test inputting ISO 8601:2004 4.4.4.2.1 "Format with designators"
SET IntervalStyle to sql_standard;
select interval 'P0Y' AS "zero",
interval 'P1Y2M' AS "a year 2 months",
@@ -333,7 +333,7 @@ select interval 'P0Y' AS "zero",
interval 'P-1Y-2M-3DT-4H-5M-6.7S' AS "negative",
interval 'PT-0.1S' AS "fractional second";
--- test inputting ISO 8601 4.4.2.2 "Alternative Format"+-- test inputting ISO 8601:2004 4.4.4.2.2 "Alternative format"
SET IntervalStyle to postgres;
select interval 'P00021015T103020' AS "ISO8601 Basic Format",
interval 'P0002-10-15T10:30:20' AS "ISO8601 Extended Format";
--
2.42.1
--cemualvklixwdetx--
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-docs@postgresql.org
Cc: ewie@ewie.name
Subject: Re: [PATCH v1] Fix references to ISO 8601
In-Reply-To: <no-message-id-9969@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox