]> granicus.if.org Git - postgresql/blob - doc/src/sgml/datetime.sgml
Move incorrectly-located indexterm entry.
[postgresql] / doc / src / sgml / datetime.sgml
1 <!-- $PostgreSQL: pgsql/doc/src/sgml/datetime.sgml,v 2.54 2006/09/22 16:35:55 tgl Exp $ -->
2
3  <appendix id="datetime-appendix">
4   <title>Date/Time Support</title>
5
6   <para>
7    <productname>PostgreSQL</productname> uses an internal heuristic
8    parser for all date/time input support. Dates and times are input as
9    strings, and are broken up into distinct fields with a preliminary
10    determination of what kind of information may be in the
11    field. Each field is interpreted and either assigned a numeric
12    value, ignored, or rejected.
13    The parser contains internal lookup tables for all textual fields,
14    including months, days of the week, and time zones.
15   </para>
16
17   <para>
18    This appendix includes information on the content of these
19    lookup tables and describes the steps used by the parser to decode
20    dates and times.
21   </para>
22
23   <sect1>
24    <title>Date/Time Input Interpretation</title>
25
26    <para>
27     The date/time type inputs are all decoded using the following procedure.
28    </para>
29
30    <procedure>
31     <step>
32      <para>
33       Break the input string into tokens and categorize each token as
34       a string, time, time zone, or number.
35      </para>
36
37      <substeps>
38       <step>
39        <para>
40         If the numeric token contains a colon (<literal>:</>), this is
41         a time string. Include all subsequent digits and colons.
42        </para>
43       </step>
44
45       <step>
46        <para>
47         If the numeric token contains a dash (<literal>-</>), slash
48         (<literal>/</>), or two or more dots (<literal>.</>), this is
49         a date string which may have a text month. In case of a slash
50         (<literal>/</>) it can also be a full time zone name like
51         <literal>America/New_York</>.
52        </para>
53       </step>
54
55       <step>
56        <para>
57         If the token is numeric only, then it is either a single field
58         or an ISO 8601 concatenated date (e.g.,
59         <literal>19990113</literal> for January 13, 1999) or time
60         (e.g., <literal>141516</literal> for 14:15:16).
61        </para>
62       </step>
63
64       <step>
65        <para>
66         If the token starts with a plus (<literal>+</>) or minus
67         (<literal>-</>), then it is either a time zone or a special
68         field.
69        </para>
70       </step>
71      </substeps>
72     </step>
73
74     <step>
75      <para>
76       If the token is a text string, match up with possible strings.
77      </para>
78      
79      <substeps>
80       <step>
81        <para>
82         Do a binary-search table lookup for the token
83         as either a special string (e.g., <literal>today</literal>),
84         day (e.g., <literal>Thursday</literal>),
85         month (e.g., <literal>January</literal>),
86         or noise word (e.g., <literal>at</literal>, <literal>on</literal>).
87        </para>
88
89        <para>
90         Set field values and bit mask for fields.
91         For example, set year, month, day for <literal>today</literal>,
92         and additionally hour, minute, second for <literal>now</literal>.
93        </para>
94       </step>
95       
96       <step>
97        <para>
98         If not found, do a similar binary-search table lookup to match
99         the token with a time zone.
100        </para>
101       </step>
102
103       <step>
104        <para>
105         If still not found, throw an error.
106        </para>
107       </step>
108      </substeps>
109     </step>
110     
111     <step>
112      <para>
113       When the token is a number or number field:
114      </para>
115
116      <substeps>
117       <step>
118        <para>
119         If there are eight or six digits,
120         and if no other date fields have been previously read, then interpret 
121         as a <quote>concatenated date</quote> (e.g.,
122         <literal>19990118</literal> or <literal>990118</literal>).
123         The interpretation is <literal>YYYYMMDD</> or <literal>YYMMDD</>.
124        </para>
125       </step>
126
127       <step>
128        <para>
129         If the token is three digits
130         and a year has already been read, then interpret as day of year.
131        </para>
132       </step>
133       
134       <step>
135        <para>
136         If four or six digits and a year has already been read, then
137         interpret as a time (<literal>HHMM</> or <literal>HHMMSS</>).
138        </para>
139       </step>
140
141       <step>
142        <para>
143         If three or more digits and no date fields have yet been found,
144         interpret as a year (this forces yy-mm-dd ordering of the remaining
145         date fields).
146        </para>
147       </step>
148
149       <step>
150        <para>
151         Otherwise the date field ordering is assumed to follow the
152         <varname>DateStyle</> setting: mm-dd-yy, dd-mm-yy, or yy-mm-dd.
153         Throw an error if a month or day field is found to be out of range.
154        </para>
155       </step>
156      </substeps>
157     </step>
158
159     <step>
160      <para>
161       If BC has been specified, negate the year and add one for
162       internal storage.  (There is no year zero in the Gregorian
163       calendar, so numerically 1 BC becomes year zero.)
164      </para>
165     </step>
166
167     <step>
168      <para>
169       If BC was not specified, and if the year field was two digits in length,
170       then adjust the year to four digits. If the field is less than 70, then
171       add 2000, otherwise add 1900.
172
173       <tip>
174        <para>
175         Gregorian years AD 1-99 may be entered by using 4 digits with leading
176         zeros (e.g., <literal>0099</> is AD 99).
177        </para>
178       </tip>
179      </para>
180     </step>
181    </procedure>
182   </sect1>
183
184
185   <sect1 id="datetime-keywords">
186    <title>Date/Time Key Words</title>
187
188    <para>
189     <xref linkend="datetime-month-table"> shows the tokens that are
190     recognized as names of months.
191    </para>
192
193     <table id="datetime-month-table">
194      <title>Month Names</title>
195      <tgroup cols="2">
196       <thead>
197        <row>
198         <entry>Month</entry>
199         <entry>Abbreviations</entry>
200        </row>
201       </thead>
202       <tbody>
203        <row>
204         <entry>January</entry>
205         <entry>Jan</entry>
206        </row>
207        <row>
208         <entry>February</entry>
209         <entry>Feb</entry>
210        </row>
211        <row>
212         <entry>March</entry>
213         <entry>Mar</entry>
214        </row>
215        <row>
216         <entry>April</entry>
217         <entry>Apr</entry>
218        </row>
219        <row>
220         <entry>May</entry>
221         <entry></entry>
222        </row>
223        <row>
224         <entry>June</entry>
225         <entry>Jun</entry>
226        </row>
227        <row>
228         <entry>July</entry>
229         <entry>Jul</entry>
230        </row>
231        <row>
232         <entry>August</entry>
233         <entry>Aug</entry>
234        </row>
235        <row>
236         <entry>September</entry>
237         <entry>Sep, Sept</entry>
238        </row>
239        <row>
240         <entry>October</entry>
241         <entry>Oct</entry>
242        </row>
243        <row>
244         <entry>November</entry>
245         <entry>Nov</entry>
246        </row>
247        <row>
248         <entry>December</entry>
249         <entry>Dec</entry>
250        </row>
251       </tbody>
252      </tgroup>
253     </table>
254
255     <para>
256      <xref linkend="datetime-dow-table"> shows the tokens that are
257      recognized as names of days of the week.
258     </para>
259
260      <table id="datetime-dow-table">
261       <title>Day of the Week Names</title>
262       <tgroup cols="2">
263        <thead>
264         <row>
265          <entry>Day</entry>
266          <entry>Abbreviations</entry>
267         </row>
268        </thead>
269        <tbody>
270         <row>
271          <entry>Sunday</entry>
272          <entry>Sun</entry>
273         </row>
274         <row>
275          <entry>Monday</entry>
276          <entry>Mon</entry>
277         </row>
278         <row>
279          <entry>Tuesday</entry>
280          <entry>Tue, Tues</entry>
281         </row>
282         <row>
283          <entry>Wednesday</entry>
284          <entry>Wed, Weds</entry>
285         </row>
286         <row>
287          <entry>Thursday</entry>
288          <entry>Thu, Thur, Thurs</entry>
289         </row>
290         <row>
291          <entry>Friday</entry>
292          <entry>Fri</entry>
293         </row>
294         <row>
295          <entry>Saturday</entry>
296          <entry>Sat</entry>
297         </row>
298        </tbody>
299       </tgroup>
300      </table>
301
302    <para>
303     <xref linkend="datetime-mod-table"> shows the tokens that serve
304     various modifier purposes.
305    </para>
306
307     <table id="datetime-mod-table">
308      <title>Date/Time Field Modifiers</title>
309      <tgroup cols="2">
310       <thead>
311        <row>
312         <entry>Identifier</entry>
313         <entry>Description</entry>
314        </row>
315       </thead>
316       <tbody>
317        <row>
318         <entry><literal>ABSTIME</literal></entry>
319         <entry>Ignored</entry>
320        </row>
321        <row>
322         <entry><literal>AM</literal></entry>
323         <entry>Time is before 12:00</entry>
324        </row>
325        <row>
326         <entry><literal>AT</literal></entry>
327         <entry>Ignored</entry>
328        </row>
329        <row>
330         <entry><literal>JULIAN</>, <literal>JD</>, <literal>J</></entry>
331         <entry>Next field is Julian Day</entry>
332        </row>
333        <row>
334         <entry><literal>ON</literal></entry>
335         <entry>Ignored</entry>
336        </row>
337        <row>
338         <entry><literal>PM</literal></entry>
339         <entry>Time is on or after 12:00</entry>
340        </row>
341        <row>
342         <entry><literal>T</literal></entry>
343         <entry>Next field is time</entry>
344        </row>
345       </tbody>
346      </tgroup>
347     </table>
348
349    <para>
350     The key word <literal>ABSTIME</literal> is ignored for historical
351     reasons: In very old releases of
352     <productname>PostgreSQL</productname>, invalid values of type <type>abstime</type>
353     were emitted as <literal>Invalid Abstime</literal>. This is no
354     longer the case however and this key word will likely be dropped in
355     a future release.
356    </para>
357   </sect1>
358
359   <sect1 id="datetime-config-files">
360   <title>Date/Time Configuration Files</title>
361
362    <indexterm>
363     <primary>time zone</primary>
364     <secondary>input abbreviations</secondary>
365    </indexterm>
366
367    <para>
368     Since timezone abbreviations are not well standardized,
369     <productname>PostgreSQL</productname> provides a means to customize
370     the set of abbreviations accepted by the server.  The
371     <xref linkend="guc-timezone-abbreviations"> run-time parameter
372     determines the active set of abbreviations.  While this parameter
373     can be altered by any database user, the possible values for it
374     are under the control of the database administrator &mdash; they
375     are in fact names of configuration files stored in
376     <filename>.../share/timezonesets/</> of the installation directory.
377     By adding or altering files in that directory, the administrator
378     can set local policy for timezone abbreviations.
379    </para>
380
381    <para>
382     <literal>timezone_abbreviations</> can be set to any file name
383     found in <filename>.../share/timezonesets/</>, if the file's name
384     is entirely alphabetic.  (The prohibition against non-alphabetic
385     characters in <literal>timezone_abbreviations</> prevents reading
386     files outside the intended directory, as well as reading editor
387     backup files and other extraneous files.)
388    </para>
389
390    <para>
391     A timezone abbreviation file may contain blank lines and comments
392     beginning with <literal>#</>.  Non-comment lines must have one of
393     these formats:
394
395 <synopsis>
396 <replaceable>time_zone_name</replaceable> <replaceable>offset</replaceable>
397 <replaceable>time_zone_name</replaceable> <replaceable>offset</replaceable> D
398 @INCLUDE <replaceable>file_name</replaceable>
399 @OVERRIDE
400 </synopsis>
401    </para>
402
403    <para>
404     A <replaceable>time_zone_name</replaceable> is just the abbreviation
405     being defined.  The <replaceable>offset</replaceable> is the zone's
406     offset in seconds from UTC, positive being east from Greenwich and
407     negative being west.  For example, -18000 would be five hours west
408     of Greenwich, or North American east coast standard time.  <literal>D</>
409     indicates that the zone name represents local daylight-savings time
410     rather than standard time. Since all known time zone offsets are on
411     15 minute boundaries, the number of seconds has to be a multiple of 900.
412    </para>
413
414    <para>
415     The <literal>@INCLUDE</> syntax allows inclusion of another file in the
416     <filename>.../share/timezonesets/</> directory.  Inclusion can be nested,
417     to a limited depth.
418    </para>
419
420    <para>
421     The <literal>@OVERRIDE</> syntax indicates that subsequent entries in the
422     file may override previous entries (i.e., entries obtained from included
423     files).  Without this, conflicting definitions of the same timezone
424     abbreviation are considered an error.
425    </para>
426
427    <para>
428     In an unmodified installation, the file <filename>Default</> contains
429     all the non-conflicting time zone abbreviations for most of the world.
430     Additional files <filename>Australia</> and <filename>India</> are
431     provided for those regions: these files first include the
432     <literal>Default</> file and then add or modify timezones as needed.
433    </para>
434
435    <para>
436     For reference purposes, a standard installation also contains files
437     <filename>Africa.txt</>, <filename>America.txt</>, etc, containing
438     information about every time zone abbreviation known to be in use
439     according to the <literal>zic</> timezone database.  The zone name
440     definitions found in these files can be copied and pasted into a custom
441     configuration file as needed.  Note that these files cannot be directly
442     referenced as <literal>timezone_abbreviations</> settings, because of
443     the dot embedded in their names.
444    </para>
445
446    <note>
447     <para>
448      If an error occurs while reading the time zone data sets, no new value is
449      applied but the old set is kept. If the error occurs while starting the
450      database, startup fails.
451     </para>
452    </note>
453
454    <caution>
455     <para>
456      Time zone abbreviations defined in the configuration file override
457      non-timezone meanings built into <productname>PostgreSQL</productname>.
458      For example, the <filename>Australia</> configuration file defines
459      <literal>SAT</> (for South Australian Standard Time).  When this
460      file is active, <literal>SAT</> will not be recognized as an abbreviation
461      for Saturday.
462     </para>
463    </caution>
464
465    <caution>
466     <para>
467      If you modify files in <filename>.../share/timezonesets/</>,
468      it is up to you to make backups &mdash; a normal database dump
469      will not include this directory.
470     </para>
471    </caution>
472
473   </sect1>
474
475   <sect1 id="datetime-units-history">
476   <title>History of Units</title>
477
478   <para>
479    The Julian Date was invented by the French scholar
480    Joseph Justus Scaliger (1540-1609)
481    and probably takes its name from Scaliger's father,
482    the Italian scholar Julius Caesar Scaliger (1484-1558).
483    Astronomers have used the Julian period to assign a unique number to
484    every day since 1 January 4713 BC. This is the so-called Julian Date
485    (JD). JD 0 designates the 24 hours from noon UTC on 1 January 4713 BC
486    to noon UTC on 2 January 4713 BC.
487   </para>
488
489    <para>
490    The <quote>Julian Date</quote> is different from the <quote>Julian
491    Calendar</quote>.  The Julian calendar
492    was introduced by Julius Caesar in 45 BC. It was in common use
493    until the year 1582, when countries started changing to the Gregorian
494    calendar.  In the Julian calendar, the tropical year is
495    approximated as 365 1/4 days = 365.25 days. This gives an error of
496    about 1 day in 128 years.
497   </para>
498
499   <para>   
500    The accumulating calendar error prompted
501    Pope Gregory XIII to reform the calendar in accordance with
502    instructions from the Council of Trent.
503    In the Gregorian calendar, the tropical year is approximated as
504    365 + 97 / 400 days = 365.2425 days. Thus it takes approximately 3300
505    years for the tropical year to shift one day with respect to the
506    Gregorian calendar.
507   </para>
508
509   <para>
510    The approximation 365+97/400 is achieved by having 97 leap years
511    every 400 years, using the following rules:
512
513    <simplelist>
514     <member>
515      Every year divisible by 4 is a leap year.
516     </member>
517     <member>
518      However, every year divisible by 100 is not a leap year.
519     </member>
520     <member>
521      However, every year divisible by 400 is a leap year after all.
522     </member>
523    </simplelist>
524
525    So, 1700, 1800, 1900, 2100, and 2200 are not leap years. But 1600,
526    2000, and 2400 are leap years.
527
528    By contrast, in the older Julian calendar all years divisible by 4 are leap
529    years.
530   </para>
531
532   <para>
533    The papal bull of February 1582 decreed that 10 days should be dropped
534    from October 1582 so that 15 October should follow immediately after
535    4 October.
536    This was observed in Italy, Poland, Portugal, and Spain. Other Catholic
537    countries followed shortly after, but Protestant countries were
538    reluctant to change, and the Greek orthodox countries didn't change
539    until the start of the 20th century.
540
541    The reform was observed by Great Britain and Dominions (including what is
542    now the USA) in 1752.
543    Thus 2 September 1752 was followed by 14 September 1752.
544
545    This is why Unix systems have the <command>cal</command> program
546    produce the following:
547
548 <screen>
549 $ <userinput>cal 9 1752</userinput>
550    September 1752
551  S  M Tu  W Th  F  S
552        1  2 14 15 16
553 17 18 19 20 21 22 23
554 24 25 26 27 28 29 30
555 </screen>
556   </para>
557
558    <note>
559     <para>
560      The SQL standard states that <quote>Within the definition of a
561      <quote>datetime literal</quote>, the <quote>datetime
562      value</quote>s are constrained by the natural rules for dates and
563      times according to the Gregorian calendar</quote>.  Dates between
564      1752-09-03 and 1752-09-13, although eliminated in some countries
565      by Papal fiat, conform to <quote>natural rules</quote> and are
566      hence valid dates.
567     </para>
568    </note>
569
570   <para>
571    Different calendars have been developed in various parts of the
572    world, many predating the Gregorian system.
573
574    For example,
575    the beginnings of the Chinese calendar can be traced back to the 14th
576    century BC. Legend has it that the Emperor Huangdi invented the
577    calendar in 2637 BC.
578    
579    The People's Republic of China uses the Gregorian calendar
580    for civil purposes. The Chinese calendar is used for determining
581    festivals.
582   </para>
583  </sect1>
584 </appendix>