1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Apply (a somewhat revised version of) Greg Mullane's patch to eliminate

heuristic determination of day vs month in date/time input.  Add the
ability to specify that input is interpreted as yy-mm-dd order (which
formerly worked, but only for yy greater than 31).  DateStyle's input
component now has the preferred spellings DMY, MDY, or YMD; the older
keywords European and US are now aliases for the first two of these.
Per recent discussions on pgsql-general.
This commit is contained in:
Tom Lane
2003-07-29 00:03:19 +00:00
parent 2baf4efe09
commit 9c2a7c2269
26 changed files with 441 additions and 350 deletions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.120 2003/07/18 03:45:06 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.121 2003/07/29 00:03:17 tgl Exp $
-->
<chapter id="datatype">
@ -1346,15 +1346,12 @@ SELECT b, char_length(b) FROM test2;
Date and time input is accepted in almost any reasonable format, including
ISO 8601, <acronym>SQL</acronym>-compatible,
traditional <productname>POSTGRES</productname>, and others.
For some formats, ordering of month and day in date input can be
For some formats, ordering of month, day, and year in date input is
ambiguous and there is support for specifying the expected
ordering of these fields.
The command
<literal>SET datestyle TO 'US'</literal>
or <literal>SET datestyle TO 'NonEuropean'</literal>
specifies the variant <quote>month before day</quote>, the command
<literal>SET datestyle TO 'European'</literal> sets the variant
<quote>day before month</quote>.
ordering of these fields. Set the <varname>datestyle</> parameter
to <literal>MDY</> to select month-day-year interpretation,
<literal>DMY</> to select day-month-year interpretation, or
<literal>YMD</> to select year-month-day interpretation.
</para>
<para>
@ -1410,36 +1407,42 @@ SELECT b, char_length(b) FROM test2;
<tbody>
<row>
<entry>January 8, 1999</entry>
<entry>unambiguous</entry>
<entry>unambiguous in any datestyle input mode</entry>
</row>
<row>
<entry>1999-01-08</entry>
<entry>ISO-8601 format, preferred</entry>
<entry>ISO-8601, January 8 in any mode
(recommended format)</entry>
</row>
<row>
<entry>1/8/1999</entry>
<entry>ambiguous (January 8 in U.S. mode; August 1 in European mode)</entry>
<entry>January 8 in <literal>MDY</> mode;
August 1 in <literal>DMY</> mode</entry>
</row>
<row>
<entry>1/18/1999</entry>
<entry>U.S. notation; January 18 in any mode</entry>
<entry>January 18 in <literal>MDY</> mode;
rejected in other modes</entry>
</row>
<row>
<entry>01/02/03</entry>
<entry>January 2, 2003 in <literal>MDY</> mode;
February 1, 2003 in <literal>DMY</> mode;
February 3, 2001 in <literal>YMD</> mode
</entry>
</row>
<row>
<entry>19990108</entry>
<entry>ISO-8601; year, month, day</entry>
<entry>ISO-8601; January 8, 1999 in any mode</entry>
</row>
<row>
<entry>990108</entry>
<entry>ISO-8601; year, month, day</entry>
<entry>ISO-8601; January 8, 1999 in any mode</entry>
</row>
<row>
<entry>1999.008</entry>
<entry>year and day of year</entry>
</row>
<row>
<entry>99008</entry>
<entry>year and day of year</entry>
</row>
<row>
<entry>J2451187</entry>
<entry>Julian day</entry>
@ -1480,7 +1483,8 @@ SELECT b, char_length(b) FROM test2;
<para>
Valid input for these types consists of a time of day followed
by an optional time zone. (See <xref
linkend="datatype-datetime-time-table">.) If a time zone is
linkend="datatype-datetime-time-table">
and <xref linkend="datatype-timezone-table">.) If a time zone is
specified in the input for <type>time without time zone</type>,
it is silently ignored.
</para>
@ -1539,14 +1543,43 @@ SELECT b, char_length(b) FROM test2;
<entry>040506-08</entry>
<entry>ISO 8601</entry>
</row>
<row>
<entry>04:05:06 PST</entry>
<entry>timezone specified by name</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
Refer to <xref linkend="datatype-timezone-table"> for
more examples of time zones.
</para>
<table tocentry="1" id="datatype-timezone-table">
<title>Time Zone Input</title>
<tgroup cols="2">
<thead>
<row>
<entry>Example</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>PST</entry>
<entry>Pacific Standard Time</entry>
</row>
<row>
<entry>-8:00</entry>
<entry>ISO-8601 offset for PST</entry>
</row>
<row>
<entry>-800</entry>
<entry>ISO-8601 offset for PST</entry>
</row>
<row>
<entry>-8</entry>
<entry>ISO-8601 offset for PST</entry>
</row>
</tbody>
</tgroup>
</table>
</sect3>
<sect3>
@ -1571,8 +1604,7 @@ SELECT b, char_length(b) FROM test2;
Valid input for the time stamp types consists of a concatenation
of a date and a time, followed by an optional
<literal>AD</literal> or <literal>BC</literal>, followed by an
optional time zone. (See <xref
linkend="datatype-timezone-table">.) Thus
optional time zone. Thus
<programlisting>
1999-01-08 04:05:06
@ -1626,36 +1658,6 @@ January 8 04:05:06 1999 PST
as <varname>timezone</> local time. A different zone reference can
be specified for the conversion using <literal>AT TIME ZONE</>.
</para>
<table tocentry="1" id="datatype-timezone-table">
<title>Time Zone Input</title>
<tgroup cols="2">
<thead>
<row>
<entry>Example</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>PST</entry>
<entry>Pacific Standard Time</entry>
</row>
<row>
<entry>-8:00</entry>
<entry>ISO-8601 offset for PST</entry>
</row>
<row>
<entry>-800</entry>
<entry>ISO-8601 offset for PST</entry>
</row>
<row>
<entry>-8</entry>
<entry>ISO-8601 offset for PST</entry>
</row>
</tbody>
</tgroup>
</table>
</sect3>
<sect3>
@ -1760,7 +1762,7 @@ January 8 04:05:06 1999 PST
<row>
<entry><literal>now</literal></entry>
<entry><type>date</type>, <type>time</type>, <type>timestamp</type></entry>
<entry>current transaction time</entry>
<entry>current transaction's start time</entry>
</row>
<row>
<entry><literal>today</literal></entry>
@ -1805,9 +1807,10 @@ January 8 04:05:06 1999 PST
</indexterm>
<para>
The output format of the date/time types can be set to one of the four styles ISO 8601,
The output format of the date/time types can be set to one of the four
styles ISO 8601,
<acronym>SQL</acronym> (Ingres), traditional POSTGRES, and
German, using the <literal>SET datestyle</literal>. The default
German, using the command <literal>SET datestyle</literal>. 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
@ -1854,9 +1857,10 @@ January 8 04:05:06 1999 PST
</table>
<para>
The <acronym>SQL</acronym> style has European and non-European
(U.S.) variants, which determines whether month follows day or
vice versa. (See <xref linkend="datatype-datetime-input">
In the <acronym>SQL</acronym> and POSTGRES styles, day appears before
month if DMY field ordering has been specified, otherwise month appears
before day.
(See <xref linkend="datatype-datetime-input">
for how this setting also affects interpretation of input values.)
<xref linkend="datatype-datetime-output2-table"> shows an
example.
@ -1867,22 +1871,27 @@ January 8 04:05:06 1999 PST
<tgroup cols="3">
<thead>
<row>
<entry>Style Specification</entry>
<entry>Description</entry>
<entry>Example</entry>
<entry>DateStyle setting</entry>
<entry>Input Ordering</entry>
<entry>Example Output</entry>
</row>
</thead>
<tbody>
<row>
<entry>European</entry>
<entry><literal>SQL, DMY</></entry>
<entry><replaceable>day</replaceable>/<replaceable>month</replaceable>/<replaceable>year</replaceable></entry>
<entry>17/12/1997 15:37:16.00 CET</entry>
</row>
<row>
<entry>US</entry>
<entry><literal>SQL, MDY</></entry>
<entry><replaceable>month</replaceable>/<replaceable>day</replaceable>/<replaceable>year</replaceable></entry>
<entry>12/17/1997 07:37:16.00 PST</entry>
</row>
<row>
<entry><literal>Postgres, DMY</></entry>
<entry><replaceable>day</replaceable>/<replaceable>month</replaceable>/<replaceable>year</replaceable></entry>
<entry>Wed 17 Dec 07:37:16 1997 PST</entry>
</row>
</tbody>
</tgroup>
</table>
@ -1903,7 +1912,7 @@ January 8 04:05:06 1999 PST
The date/time styles can be selected by the user using the
<command>SET datestyle</command> command, the
<varname>datestyle</varname> parameter in the
<filename>postgresql.conf</filename> configuration file, and the
<filename>postgresql.conf</filename> configuration file, or the
<envar>PGDATESTYLE</envar> environment variable on the server or
client. The formatting function <function>to_char</function>
(see <xref linkend="functions-formatting">) is also available as

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/datetime.sgml,v 2.31 2003/04/07 01:29:25 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/datetime.sgml,v 2.32 2003/07/29 00:03:17 tgl Exp $
-->
<appendix id="datetime-appendix">
@ -27,7 +27,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datetime.sgml,v 2.31 2003/04/07 01:29:25 pe
<title>Date/Time Input Interpretation</title>
<para>
The date/time type inputs are all decoded using the following routine.
The date/time type inputs are all decoded using the following procedure.
</para>
<procedure>
@ -103,7 +103,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datetime.sgml,v 2.31 2003/04/07 01:29:25 pe
<step>
<para>
If not found, throw an error.
If still not found, throw an error.
</para>
</step>
</substeps>
@ -111,70 +111,47 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datetime.sgml,v 2.31 2003/04/07 01:29:25 pe
<step>
<para>
The token is a number or number field.
When the token is a number or number field:
</para>
<substeps>
<step>
<para>
If there are more than 4 digits,
If there are eight or six digits,
and if no other date fields have been previously read, then interpret
as a <quote>concatenated date</quote> (e.g., <literal>19990118</literal>). 8
and 6 digits are interpreted as year, month, and day, while 7
and 5 digits are interpreted as year, day of year, respectively.
as a <quote>concatenated date</quote> (e.g.,
<literal>19990118</literal> or <literal>990118</literal>).
The interpretation is <literal>YYYYMMDD</> or <literal>YYMMDD</>.
</para>
</step>
<step>
<para>
If the token is three digits
and a year has already been decoded, then interpret as day of year.
and a year has already been read, then interpret as day of year.
</para>
</step>
<step>
<para>
If four or six digits and a year has already been read, then
interpret as a time.
interpret as a time (<literal>HHMM</> or <literal>HHMMSS</>).
</para>
</step>
<step>
<para>
If four or more digits, then interpret as a year.
If three or more digits and no date fields have yet been found,
interpret as a year (this forces yy-mm-dd ordering of the remaining
date fields).
</para>
</step>
<step>
<para>
If in European date mode, and if the day field has not yet been read,
and if the value is less than or equal to 31, then interpret as a day.
</para>
</step>
<step>
<para>
If the month field has not yet been read,
and if the value is less than or equal to 12, then interpret as a month.
</para>
</step>
<step>
<para>
If the day field has not yet been read,
and if the value is less than or equal to 31, then interpret as a day.
</para>
</step>
<step>
<para>
If two digits or four or more digits, then interpret as a year.
</para>
</step>
<step>
<para>
Otherwise, throw an error.
Otherwise the date field ordering is assumed to follow the
<varname>DateStyle</> setting: mm-dd-yy, dd-mm-yy, or yy-mm-dd.
Throw an error if a month or day field is found to be out of range.
</para>
</step>
</substeps>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.160 2003/07/17 00:55:36 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.161 2003/07/29 00:03:17 tgl Exp $
PostgreSQL documentation
-->
@ -6503,7 +6503,7 @@ SELECT current_setting('datestyle');
current_setting
-----------------
ISO, US
ISO, MDY
(1 row)
</programlisting>
</para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/postgres-ref.sgml,v 1.33 2003/05/02 20:54:33 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/postgres-ref.sgml,v 1.34 2003/07/29 00:03:17 tgl Exp $
PostgreSQL documentation
-->
@ -147,11 +147,10 @@ PostgreSQL documentation
<term><option>-e</option></term>
<listitem>
<para>
Sets the default date style to <quote>European</quote>, which
means that the <quote>day before month</quote> (rather than
month before day) rule is used to interpret ambiguous date
input, and that the day is printed before the month in certain
date output formats. See <xref linkend="datatype-datetime"> for more information.
Sets the default date style to <quote>European</quote>, that is
<literal>DMY</> ordering of input date fields. This also causes
the day to be printed before the month in certain date output formats.
See <xref linkend="datatype-datetime"> for more information.
</para>
</listitem>
</varlistentry>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/set.sgml,v 1.79 2003/07/17 00:55:36 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/set.sgml,v 1.80 2003/07/29 00:03:17 tgl Exp $
PostgreSQL documentation
-->
@ -283,9 +283,10 @@ SET search_path TO my_schema, public;
<para>
Set the style of date to traditional
<productname>POSTGRES</productname> with European conventions:
<productname>POSTGRES</productname> with <quote>day before month</>
input convention:
<screen>
SET datestyle TO postgres,european;
SET datestyle TO postgres, dmy;
</screen>
</para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/show.sgml,v 1.29 2003/07/15 19:19:56 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/show.sgml,v 1.30 2003/07/29 00:03:17 tgl Exp $
PostgreSQL documentation
-->
@ -158,7 +158,7 @@ SHOW ALL
SHOW DateStyle;
DateStyle
-----------
ISO, US
ISO, MDY
(1 row)
</programlisting>
</para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.202 2003/07/25 09:00:17 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.203 2003/07/29 00:03:17 tgl Exp $
-->
<appendix id="release">
@ -26,6 +26,8 @@ worries about funny characters.
<literallayout><![CDATA[
EXTRACT(TIMEZONE) and SET/SHOW TIMEZONE now follow SQL sign convention
(positive = east of UTC)
DATESTYLE can now be set to DMY, YMD, or MDY to specify input field order
Input date order must now be YYYY-MM-DD (with 4-digit year) or match DATESTYLE
Output of SHOW DATESTYLE is now in the same format accepted by SET DATESTYLE
PL/Python is now an untrusted language, and is renamed to 'plpythonu'
Dollar sign ($) is no longer allowed in operator names

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.196 2003/07/27 04:35:53 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.197 2003/07/29 00:03:17 tgl Exp $
-->
<Chapter Id="runtime">
@ -2101,9 +2101,17 @@ SET ENABLE_SEQSCAN TO OFF;
<listitem>
<para>
Sets the display format for date and time values, as well as
the rules for interpreting ambiguous date input values. See
<xref linkend="datatype-datetime"> for more information. The
default is <literal>ISO, US</>.
the rules for interpreting ambiguous date input values.
For historical reasons, this variable contains two independent
components: the output format specification (<literal>ISO</>,
<literal>Postgres</>, <literal>SQL</>, or <literal>German</>) and
the date field order specification (<literal>DMY</>, <literal>MDY</>,
or <literal>YMD</>). These can be set separately or together.
The keywords <literal>Euro</> and <literal>European</> are synonyms
for <literal>DMY</>; the keywords <literal>US</>, <literal>NonEuro</>,
and <literal>NonEuropean</> are synonyms for <literal>MDY</>.
See <xref linkend="datatype-datetime"> for more information. The
default is <literal>ISO, MDY</>.
</para>
</listitem>
</varlistentry>