Skip to content

Commit d328991

Browse files
committed
Document handling of invalid/ambiguous timestamp input near DST boundaries.
The source code comments documented this, but the user-facing docs, not so much. Add a section to Appendix B that discusses it. In passing, improve a couple other things in Appendix B --- notably, a long-obsolete claim that time zone abbreviations are looked up in a fixed table. Per bug #15527 from Michael Davidson. Discussion: https://postgr.es/m/15527-f1be0b4dc99ebbe7@postgresql.org
1 parent 88bdbd3 commit d328991

File tree

1 file changed

+84
-6
lines changed

1 file changed

+84
-6
lines changed

doc/src/sgml/datetime.sgml

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<title>Date/Time Input Interpretation</title>
2525

2626
<para>
27-
The date/time type inputs are all decoded using the following procedure.
27+
Date/time input strings are decoded using the following procedure.
2828
</para>
2929

3030
<procedure>
@@ -73,20 +73,21 @@
7373

7474
<step>
7575
<para>
76-
If the token is a text string, match up with possible strings:
76+
If the token is an alphabetic string, match up with possible strings:
7777
</para>
7878

7979
<substeps>
8080
<step>
8181
<para>
82-
Do a binary-search table lookup for the token as a time zone
83-
abbreviation.
82+
See if the token matches any known time zone abbreviation.
83+
These abbreviations are supplied by the configuration file
84+
described in <xref linkend="datetime-config-files"/>.
8485
</para>
8586
</step>
8687

8788
<step>
8889
<para>
89-
If not found, do a similar binary-search table lookup to match
90+
If not found, search an internal table to match
9091
the token as either a special string (e.g., <literal>today</literal>),
9192
day (e.g., <literal>Thursday</literal>),
9293
month (e.g., <literal>January</literal>),
@@ -176,6 +177,83 @@
176177
</sect1>
177178

178179

180+
<sect1 id="datetime-invalid-input">
181+
<title>Handling of Invalid or Ambiguous Timestamps</title>
182+
183+
<para>
184+
Ordinarily, if a date/time string is syntactically valid but contains
185+
out-of-range field values, an error will be thrown. For example, input
186+
specifying the 31st of February will be rejected.
187+
</para>
188+
189+
<para>
190+
During a daylight-savings-time transition, it is possible for a
191+
seemingly valid timestamp string to represent a nonexistent or ambiguous
192+
timestamp. Such cases are not rejected; the ambiguity is resolved by
193+
determining which UTC offset to apply. For example, supposing that the
194+
<xref linkend="guc-timezone"/> parameter is set
195+
to <literal>America/New_York</literal>, consider
196+
<programlisting>
197+
=&gt; SELECT '2018-03-11 02:30'::timestamptz;
198+
timestamptz
199+
------------------------
200+
2018-03-11 03:30:00-04
201+
(1 row)
202+
</programlisting>
203+
Because that day was a spring-forward transition date in that time zone,
204+
there was no civil time instant 2:30AM; clocks jumped forward from 2AM
205+
EST to 3AM EDT. <productname>PostgreSQL</productname> interprets the
206+
given time as if it were standard time (UTC-5), which then renders as
207+
3:30AM EDT (UTC-4).
208+
</para>
209+
210+
<para>
211+
Conversely, consider the behavior during a fall-back transition:
212+
<programlisting>
213+
=&gt; SELECT '2018-11-04 02:30'::timestamptz;
214+
timestamptz
215+
------------------------
216+
2018-11-04 02:30:00-05
217+
(1 row)
218+
</programlisting>
219+
On that date, there were two possible interpretations of 2:30AM; there
220+
was 2:30AM EDT, and then an hour later after the reversion to standard
221+
time, there was 2:30AM EST.
222+
Again, <productname>PostgreSQL</productname> interprets the given time
223+
as if it were standard time (UTC-5). We can force the matter by
224+
specifying daylight-savings time:
225+
<programlisting>
226+
=&gt; SELECT '2018-11-04 02:30 EDT'::timestamptz;
227+
timestamptz
228+
------------------------
229+
2018-11-04 01:30:00-05
230+
(1 row)
231+
</programlisting>
232+
This timestamp could validly be rendered as either 2:30 UTC-4 or
233+
1:30 UTC-5; the timestamp output code chooses the latter.
234+
</para>
235+
236+
<para>
237+
The precise rule that is applied in such cases is that an invalid
238+
timestamp that appears to fall within a jump-forward daylight savings
239+
transition is assigned the UTC offset that prevailed in the time zone
240+
just before the transition, while an ambiguous timestamp that could fall
241+
on either side of a jump-back transition is assigned the UTC offset that
242+
prevailed just after the transition. In most time zones this is
243+
equivalent to saying that <quote>the standard-time interpretation is
244+
preferred when in doubt</quote>.
245+
</para>
246+
247+
<para>
248+
In all cases, the UTC offset associated with a timestamp can be
249+
specified explicitly, using either a numeric UTC offset or a time zone
250+
abbreviation that corresponds to a fixed UTC offset. The rule just
251+
given applies only when it is necessary to infer a UTC offset for a time
252+
zone in which the offset varies.
253+
</para>
254+
</sect1>
255+
256+
179257
<sect1 id="datetime-keywords">
180258
<title>Date/Time Key Words</title>
181259

@@ -553,7 +631,7 @@
553631
is now the USA) in 1752.
554632
Thus 2 September 1752 was followed by 14 September 1752.
555633

556-
This is why Unix systems have the <command>cal</command> program
634+
This is why Unix systems that have the <command>cal</command> program
557635
produce the following:
558636

559637
<screen>

0 commit comments

Comments
 (0)