1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-31 03:21:24 +03:00

Fix breakage in new-in-7.3 timetz_zone() function: was giving random

results due to doing arithmetic on uninitialized values.  Add some
documentation about the AT TIME ZONE construct.  Update some other
date/time documentation that seemed out of date for 7.3.
This commit is contained in:
Tom Lane 2002-11-21 23:31:37 +00:00
parent 040d0ae95d
commit 4dc8a0e4e1
3 changed files with 308 additions and 151 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.106.2.1 2002/11/10 12:45:41 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.106.2.2 2002/11/21 23:31:37 tgl Exp $
--> -->
<chapter id="datatype"> <chapter id="datatype">
@ -245,14 +245,15 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.106.2.1 2002/11/10 12:45:
<note> <note>
<title>Compatibility</title> <title>Compatibility</title>
<para> <para>
The following types (or spellings thereof) are specified by SQL: The following types (or spellings thereof) are specified by
<type>bit</type>, <type>bit varying</type>, <type>boolean</type>, <acronym>SQL</acronym>: <type>bit</type>, <type>bit
<type>char</type>, <type>character</type>, <type>character varying</type>, <type>boolean</type>, <type>char</type>,
varying</type>, <type>varchar</type>, <type>date</type>, <type>character</type>, <type>character varying</type>,
<type>double precision</type>, <type>integer</type>, <type>varchar</type>, <type>date</type>, <type>double
<type>interval</type>, <type>numeric</type>, <type>decimal</type>, precision</type>, <type>integer</type>, <type>interval</type>,
<type>real</type>, <type>smallint</type>, <type>time</type>, <type>numeric</type>, <type>decimal</type>, <type>real</type>,
<type>timestamp</type> (both with or without time zone). <type>smallint</type>, <type>time</type>, <type>timestamp</type>
(both with or without time zone).
</para> </para>
</note> </note>
@ -464,11 +465,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.106.2.1 2002/11/10 12:45:
</para> </para>
<para> <para>
SQL only specifies the integer types <type>integer</type> (or <acronym>SQL</acronym> only specifies the integer types
<type>int</type>) and <type>smallint</type>. The type <type>integer</type> (or <type>int</type>) and
<type>bigint</type>, and the type names <type>int2</type>, <type>smallint</type>. The type <type>bigint</type>, and the
<type>int4</type>, and <type>int8</type> are extensions, which type names <type>int2</type>, <type>int4</type>, and
are shared with various other SQL database systems. <type>int8</type> are extensions, which are shared with various
other <acronym>SQL</acronym> database systems.
</para> </para>
<note> <note>
@ -536,13 +538,15 @@ NUMERIC(<replaceable>precision</replaceable>)
NUMERIC NUMERIC
</programlisting> </programlisting>
without any precision or scale creates a column in which numeric without any precision or scale creates a column in which numeric
values of any precision and scale can be stored, up to the implementation values of any precision and scale can be stored, up to the
limit on precision. A column of this kind will not coerce input implementation limit on precision. A column of this kind will
values to any particular scale, whereas <type>numeric</type> columns not coerce input values to any particular scale, whereas
with a declared scale will coerce input values to that scale. <type>numeric</type> columns with a declared scale will coerce
(The SQL standard requires a default scale of 0, i.e., coercion to input values to that scale. (The <acronym>SQL</acronym> standard
integer precision. We find this a bit useless. If you're concerned about requires a default scale of 0, i.e., coercion to integer
portability, always specify the precision and scale explicitly.) precision. We find this a bit useless. If you're concerned
about portability, always specify the precision and scale
explicitly.)
</para> </para>
<para> <para>
@ -554,7 +558,8 @@ NUMERIC
<para> <para>
The types <type>decimal</type> and <type>numeric</type> are The types <type>decimal</type> and <type>numeric</type> are
equivalent. Both types are part of the SQL standard. equivalent. Both types are part of the <acronym>SQL</acronym>
standard.
</para> </para>
</sect2> </sect2>
@ -806,7 +811,8 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
<para> <para>
<xref linkend="datatype-character-table"> shows the <xref linkend="datatype-character-table"> shows the
general-purpose character types available in PostgreSQL. general-purpose character types available in
<productname>PostgreSQL</productname>.
</para> </para>
<para> <para>
@ -818,11 +824,12 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
longer string into a column of these types will result in an longer string into a column of these types will result in an
error, unless the excess characters are all spaces, in which case error, unless the excess characters are all spaces, in which case
the string will be truncated to the maximum length. (This the string will be truncated to the maximum length. (This
somewhat bizarre exception is required by the SQL standard.) If somewhat bizarre exception is required by the
the string to be stored is shorter than the declared length, <acronym>SQL</acronym> standard.) If the string to be stored is
values of type <type>character</type> will be space-padded; values shorter than the declared length, values of type
of type <type>character varying</type> will simply store the <type>character</type> will be space-padded; values of type
shorter string. <type>character varying</type> will simply store the shorter
string.
</para> </para>
<note> <note>
@ -831,7 +838,8 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
<type>character(<replaceable>n</>)</type> or <type>character <type>character(<replaceable>n</>)</type> or <type>character
varying(<replaceable>n</>)</type>, then an overlength value will varying(<replaceable>n</>)</type>, then an overlength value will
be truncated to <replaceable>n</> characters without raising an be truncated to <replaceable>n</> characters without raising an
error. (This too is required by the SQL standard.) error. (This too is required by the <acronym>SQL</acronym>
standard.)
</para> </para>
</note> </note>
@ -859,8 +867,9 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
more general <type>text</type> type, which stores strings of any more general <type>text</type> type, which stores strings of any
length. Unlike <type>character varying</type>, <type>text</type> length. Unlike <type>character varying</type>, <type>text</type>
does not require an explicit declared upper limit on the size of does not require an explicit declared upper limit on the size of
the string. Although the type <type>text</type> is not in the SQL the string. Although the type <type>text</type> is not in the
standard, many other RDBMS packages have it as well. <acronym>SQL</acronym> standard, many other RDBMS packages have it
as well.
</para> </para>
<para> <para>
@ -1125,12 +1134,12 @@ SELECT b, char_length(b) FROM test2;
<para> <para>
To use the <type>bytea</type> escaped octet notation, string To use the <type>bytea</type> escaped octet notation, string
literals (input strings) must contain two backslashes due because literals (input strings) must contain two backslashes because they
they must pass through two parsers in the PostgreSQL server. The must pass through two parsers in the <productname>PostgreSQL</>
first backslash is interpreted as an escape character by the server. The first backslash is interpreted as an escape character
string-literal parser, and therefore is consumed, leaving the by the string-literal parser, and therefore is consumed, leaving
characters that follow. The remaining backslash is recognized by the characters that follow. The remaining backslash is recognized
the <type>bytea</type> input function as the prefix of a three by the <type>bytea</type> input function as the prefix of a three
digit octal value. For example, a string literal passed to the digit octal value. For example, a string literal passed to the
backend as <literal>'\\001'</literal> becomes backend as <literal>'\\001'</literal> becomes
<literal>'\001'</literal> after passing through the string-literal <literal>'\001'</literal> after passing through the string-literal
@ -1170,21 +1179,22 @@ SELECT b, char_length(b) FROM test2;
</para> </para>
<para> <para>
Depending on the front end to PostgreSQL you use, you may have Depending on the front end to <productname>PostgreSQL</> you use,
additional work to do in terms of escaping and unescaping you may have additional work to do in terms of escaping and
<type>bytea</type> strings. For example, you may also have to escape unescaping <type>bytea</type> strings. For example, you may also
line feeds and carriage returns if your interface automatically have to escape line feeds and carriage returns if your interface
translates these. Or you may have to double up on backslashes if automatically translates these. Or you may have to double up on
the parser for your language or choice also treats them as an backslashes if the parser for your language or choice also treats
escape character. them as an escape character.
</para> </para>
<para> <para>
The SQL standard defines a different binary string type, called The <acronym>SQL</acronym> standard defines a different binary
<type>BLOB</type> or <type>BINARY LARGE OBJECT</type>. The input string type, called <type>BLOB</type> or <type>BINARY LARGE
format is different compared to <type>bytea</type>, but the OBJECT</type>. The input format is different compared to
provided functions and operators are mostly the same. <type>bytea</type>, but the provided functions and operators are
</para> mostly the same.
</para>
</sect1> </sect1>
@ -1559,20 +1569,32 @@ SELECT b, char_length(b) FROM test2;
<secondary>data type</secondary> <secondary>data type</secondary>
</indexterm> </indexterm>
<indexterm>
<primary>timestamp with time zone</primary>
<secondary>data type</secondary>
</indexterm>
<indexterm> <indexterm>
<primary>timestamp without time zone</primary> <primary>timestamp without time zone</primary>
<secondary>data type</secondary> <secondary>data type</secondary>
</indexterm> </indexterm>
<para> <para>
Time stamp types exist as <type>timestamp [ The time stamp types are <type>timestamp [
(<replaceable>p</replaceable>) ]</type>, <type>timestamp [
(<replaceable>p</replaceable>) ] without time zone</type> and (<replaceable>p</replaceable>) ] without time zone</type> and
<type>timestamp [ (<replaceable>p</replaceable>) ] without time <type>timestamp [ (<replaceable>p</replaceable>) ] with time
zone</type>. A plain <type>timestamp</type> is equivalent to zone</type>. Writing just <type>timestamp</type> is equivalent to
<type>timestamp without timezone</type>. <type>timestamp without time zone</type>.
</para> </para>
<note>
<para>
Prior to <productname>PostgreSQL</productname> 7.3, writing just
<type>timestamp</type> was equivalent to <type>timestamp with time
zone</type>. This was changed for SQL spec compliance.
</para>
</note>
<para> <para>
Valid input for the time stamp types consists of a concatenation Valid input for the time stamp types consists of a concatenation
of a date and a time, followed by an optional of a date and a time, followed by an optional
@ -1605,11 +1627,38 @@ January 8 04:05:06 1999 PST
<para> <para>
For <type>timestamp without time zone</type>, any explicit time For <type>timestamp without time zone</type>, any explicit time
zone specified in the input is silently swallowed. That is, the zone specified in the input is silently ignored. That is, the
resulting date/time value is derived from the explicit date/time resulting date/time value is derived from the explicit date/time
fields in the input value, and is not adjusted for time zone. fields in the input value, and is not adjusted for time zone.
</para> </para>
<para>
For <type>timestamp with time zone</type>, the internally stored
value is always in UTC (GMT). An input value that has an explicit
time zone specified is converted to UTC using the appropriate offset
for that time zone. If no time zone is stated in the input string,
then it is assumed to be in the time zone indicated by the system's
<varname>TimeZone</> parameter, and is converted to UTC using the
offset for the <varname>TimeZone</> zone.
</para>
<para>
When a <type>timestamp with time
zone</type> value is output, it is always converted from UTC to the
current <varname>TimeZone</> zone, and displayed as local time in that
zone. To see the time in another time zone, either change
<varname>TimeZone</> or use the <literal>AT TIME ZONE</> construct
(see <xref linkend="functions-datetime-zoneconvert">).
</para>
<para>
Conversions between <type>timestamp without time zone</type> and
<type>timestamp with time zone</type> normally assume that the
<type>timestamp without time zone</type> value should be taken or given
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"> <table tocentry="1" id="datatype-timezone-table">
<title>Time Zone Input</title> <title>Time Zone Input</title>
<tgroup cols="2"> <tgroup cols="2">
@ -1697,24 +1746,28 @@ January 8 04:05:06 1999 PST
<para> <para>
The following <acronym>SQL</acronym>-compatible functions can be The following <acronym>SQL</acronym>-compatible functions can be
used as date or time used as date or time
input for the corresponding data type: <literal>CURRENT_DATE</literal>, values for the corresponding data type: <literal>CURRENT_DATE</literal>,
<literal>CURRENT_TIME</literal>, <literal>CURRENT_TIME</literal>,
<literal>CURRENT_TIMESTAMP</literal>. The latter two accept an <literal>CURRENT_TIMESTAMP</literal>. The latter two accept an
optional precision specification. (See also <xref linkend="functions-datetime">.) optional precision specification. (See also <xref linkend="functions-datetime-current">.)
</para> </para>
<para> <para>
<productname>PostgreSQL</productname> also supports several <productname>PostgreSQL</productname> also supports several
special constants for convenience, shown in <xref special date/time input values for convenience, as shown in <xref
linkend="datatype-datetime-special-table">. linkend="datatype-datetime-special-table">. The values
<literal>infinity</literal> and <literal>-infinity</literal>
are specially represented inside the system and will be displayed
the same way; but the others are simply notational shorthands
that will be converted to ordinary date/time values when read.
</para> </para>
<table id="datatype-datetime-special-table"> <table id="datatype-datetime-special-table">
<title>Special Date/Time Constants</title> <title>Special Date/Time Inputs</title>
<tgroup cols="2"> <tgroup cols="2">
<thead> <thead>
<row> <row>
<entry>Constant</entry> <entry>Input string</entry>
<entry>Description</entry> <entry>Description</entry>
</row> </row>
</thead> </thead>
@ -1725,15 +1778,13 @@ January 8 04:05:06 1999 PST
</row> </row>
<row> <row>
<entry><literal>infinity</literal></entry> <entry><literal>infinity</literal></entry>
<entry>later than other valid times</entry> <entry>later than all other timestamps (not available for
type <type>date</>)</entry>
</row> </row>
<row> <row>
<entry><literal>-infinity</literal></entry> <entry><literal>-infinity</literal></entry>
<entry>earlier than other valid times</entry> <entry>earlier than all other timestamps (not available for
</row> type <type>date</>)</entry>
<row>
<entry><literal>invalid</literal></entry>
<entry>illegal entry</entry>
</row> </row>
<row> <row>
<entry><literal>now</literal></entry> <entry><literal>now</literal></entry>
@ -1781,11 +1832,12 @@ January 8 04:05:06 1999 PST
Output formats can be set to one of the four styles ISO 8601, Output formats can be set to one of the four styles ISO 8601,
<acronym>SQL</acronym> (Ingres), traditional PostgreSQL, and <acronym>SQL</acronym> (Ingres), traditional PostgreSQL, and
German, using the <command>SET DateStyle</command>. The default German, using the <command>SET DateStyle</command>. The default
is the <acronym>ISO</acronym> format. (The SQL standard requires is the <acronym>ISO</acronym> format. (The
the use of the ISO 8601 format. The name of the <acronym>SQL</acronym> standard requires the use of the ISO 8601
<quote>SQL</quote> output format is a historical accident.) format. The name of the <quote>SQL</quote> output format is a
<xref linkend="datatype-datetime-output-table"> shows examples of historical accident.) <xref
each output style. The output of the <type>date</type> and linkend="datatype-datetime-output-table"> shows examples of each
output style. The output of the <type>date</type> and
<type>time</type> types is of course only the date or time part <type>time</type> types is of course only the date or time part
in accordance with the given examples. in accordance with the given examples.
</para> </para>
@ -1920,44 +1972,52 @@ January 8 04:05:06 1999 PST
</para> </para>
<para> <para>
To address these difficulties, we recommend using date/time To address these difficulties, we recommend using date/time types
types that contain both date and time when using time zones. We that contain both date and time when using time zones. We
recommend <emphasis>not</emphasis> using the type <type>time recommend <emphasis>not</emphasis> using the type <type>time with
with time zone</type> (though it is supported by time zone</type> (though it is supported by
<productname>PostgreSQL</productname> for legacy applications and <productname>PostgreSQL</productname> for legacy applications and
for compatibility with other SQL implementations). for compatibility with other <acronym>SQL</acronym>
<productname>PostgreSQL</productname> implementations). <productname>PostgreSQL</productname> assumes
assumes your local time zone for any type containing only your local time zone for any type containing only date or
date or time. Further, time zone support is derived from time. Further, time zone support is derived from the underlying
the underlying operating system operating system time-zone capabilities, and hence can handle
time-zone capabilities, and hence can handle daylight-saving time daylight-saving time and other expected behavior.
and other expected behavior.
</para> </para>
<para> <para>
<productname>PostgreSQL</productname> obtains time-zone support <productname>PostgreSQL</productname> obtains time-zone support
from the underlying operating system for dates between 1902 and from the underlying operating system for dates between 1902 and
2038 (near the typical date limits for Unix-style 2038 (near the typical date limits for Unix-style
systems). Outside of this range, all dates are assumed to be systems). Outside of this range, all dates are assumed to be
specified and used in Universal Coordinated Time (UTC). specified and used in Universal Coordinated Time
(<acronym>UTC</acronym>).
</para> </para>
<para> <para>
All dates and times are stored internally in UTC, All dates and times are stored internally in
traditionally known as Greenwich Mean Time (GMT). <acronym>UTC</acronym>, traditionally known as Greenwich Mean
Times are converted to local time on the database server before being Time (<acronym>GMT</acronym>). Times are converted to local time
sent to the client frontend, hence by default are in the server on the database server before being sent to the client frontend,
time zone. hence by default are in the server time zone.
</para> </para>
<para> <para>
There are several ways to affect the time-zone behavior: There are several ways to select the time zone used by the server:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
The <envar>TZ</envar> environment variable on the server host The <envar>TZ</envar> environment variable on the server host
is used by the server as the default time zone. is used by the server as the default time zone, if no other is
specified.
</para>
</listitem>
<listitem>
<para>
The <varname>timezone</varname> configuration parameter can be
set in <filename>postgresql.conf</>.
</para> </para>
</listitem> </listitem>
@ -1976,25 +2036,13 @@ January 8 04:05:06 1999 PST
sets the time zone for the session. sets the time zone for the session.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The construct
<programlisting>
<replaceable>timestamp</replaceable> AT TIME ZONE '<replaceable>zone</replaceable>'
</programlisting>
where <replaceable>zone</replaceable> can be specified as a
text time zone (e.g., <literal>'PST'</literal>) or as an
interval (e.g., <literal>INTERVAL '-08:00'</literal>).
</para>
</listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<note> <note>
<para> <para>
If an invalid time zone is specified, If an invalid time zone is specified, the time zone becomes
the time zone becomes GMT (on most systems anyway). <acronym>UTC</acronym> (on most systems anyway).
</para> </para>
</note> </note>
@ -2124,8 +2172,9 @@ SELECT * FROM test1 WHERE a;
<para> <para>
Geometric data types represent two-dimensional spatial Geometric data types represent two-dimensional spatial
objects. <xref linkend="datatype-geo-table"> shows the geometric objects. <xref linkend="datatype-geo-table"> shows the geometric
types available in PostgreSQL. The most fundamental type, the types available in <productname>PostgreSQL</productname>. The
point, forms the basis for all of the other types. most fundamental type, the point, forms the basis for all of the
other types.
</para> </para>
<table id="datatype-geo-table"> <table id="datatype-geo-table">
@ -2746,9 +2795,10 @@ SELECT * FROM test1 WHERE a;
<note> <note>
<para> <para>
Prior to <productname>PostgreSQL</> 7.2, <type>BIT</type> data was Prior to <productname>PostgreSQL</> 7.2, <type>BIT</type> data
always silently truncated or zero-padded on the right, with or without an was always silently truncated or zero-padded on the right, with
explicit cast. This was changed to comply with the SQL standard. or without an explicit cast. This was changed to comply with the
<acronym>SQL</acronym> standard.
</para> </para>
</note> </note>
@ -2978,14 +3028,14 @@ SELECT * FROM test;
</para> </para>
<para> <para>
A third identifier type used by the system is <type>cid</>, or command A third identifier type used by the system is <type>cid</>, or
identifier. This is the data type of the system columns command identifier. This is the data type of the system columns
<structfield>cmin</> and <structfield>cmax</>. <structfield>cmin</> and <structfield>cmax</>. Command
Command identifiers are also 32-bit quantities. This creates a hard identifiers are also 32-bit quantities. This creates a hard limit
limit of 2<superscript>32</> (4 billion) SQL commands within a single of 2<superscript>32</> (4 billion) <acronym>SQL</acronym> commands
transaction. within a single transaction. In practice this limit is not a
In practice this limit is not a problem --- note that the limit is on problem --- note that the limit is on number of
number of SQL commands, not number of tuples processed. <acronym>SQL</acronym> commands, not number of tuples processed.
</para> </para>
<para> <para>
@ -3044,9 +3094,10 @@ SELECT * FROM test;
column data type, but it can be used to declare a function's column data type, but it can be used to declare a function's
argument or result type. Each of the available pseudo-types is argument or result type. Each of the available pseudo-types is
useful in situations where a function's behavior does not useful in situations where a function's behavior does not
correspond to simply taking or returning a value of a specific SQL correspond to simply taking or returning a value of a specific
data type. <xref linkend="datatype-pseudotypes-table"> lists the <acronym>SQL</acronym> data type. <xref
existing pseudo-types. linkend="datatype-pseudotypes-table"> lists the existing
pseudo-types.
</para> </para>
<table id="datatype-pseudotypes-table"> <table id="datatype-pseudotypes-table">
@ -3126,14 +3177,15 @@ SELECT * FROM test;
</para> </para>
<para> <para>
The <type>internal</> pseudo-type is used to declare functions that are The <type>internal</> pseudo-type is used to declare functions
meant only to be called internally by the database system, and not by that are meant only to be called internally by the database
direct invocation in a SQL query. If a function has at least one system, and not by direct invocation in a <acronym>SQL</acronym>
<type>internal</>-type argument then it cannot be called from SQL. query. If a function has at least one <type>internal</>-type
To preserve the type safety of this restriction it is important to argument then it cannot be called from <acronym>SQL</acronym>. To
follow this coding rule: do not create any function that is declared preserve the type safety of this restriction it is important to
to return <type>internal</> unless it has at least one <type>internal</> follow this coding rule: do not create any function that is
argument. declared to return <type>internal</> unless it has at least one
<type>internal</> argument.
</para> </para>
</sect1> </sect1>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.129.2.1 2002/11/10 12:45:42 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.129.2.2 2002/11/21 23:31:37 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -3549,9 +3549,14 @@ SUBSTRING('foobar' FROM 'o(.)b') <lineannotation>o</lineannotation>
<literal>*</literal>, etc.). For formatting functions, refer to <literal>*</literal>, etc.). For formatting functions, refer to
<xref linkend="functions-formatting">. You should be familiar with <xref linkend="functions-formatting">. You should be familiar with
the background information on date/time data types (see <xref the background information on date/time data types (see <xref
linkend="datatype-datetime">). The date/time operators described linkend="datatype-datetime">).
below behave similarly for types involving time zones as well as </para>
those without.
<para>
All the functions and operators described below that take time or timestamp
inputs actually come in two variants: one that takes time or timestamp
with time zone, and one that takes time or timestamp without time zone.
For brevity, these variants are not shown separately.
</para> </para>
<table id="operators-datetime-table"> <table id="operators-datetime-table">
@ -3771,7 +3776,7 @@ SUBSTRING('foobar' FROM 'o(.)b') <lineannotation>o</lineannotation>
<row> <row>
<entry><function>now</function>()</entry> <entry><function>now</function>()</entry>
<entry><type>timestamp</type></entry> <entry><type>timestamp with time zone</type></entry>
<entry>Current date and time (equivalent to <entry>Current date and time (equivalent to
<function>current_timestamp</function>); see <xref <function>current_timestamp</function>); see <xref
linkend="functions-datetime-current"> linkend="functions-datetime-current">
@ -3898,8 +3903,8 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
<listitem> <listitem>
<para> <para>
For <type>date</type> and <type>timestamp</type> values, the For <type>date</type> and <type>timestamp</type> values, the
number of seconds since 1970-01-01 00:00:00-00 (Result may be number of seconds since 1970-01-01 00:00:00-00 (can be negative);
negative.); for <type>interval</type> values, the total number for <type>interval</type> values, the total number
of seconds in the interval of seconds in the interval
</para> </para>
@ -4122,12 +4127,12 @@ SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
<para> <para>
The <function>date_part</function> function is modeled on the traditional The <function>date_part</function> function is modeled on the traditional
<productname>Ingres</productname> equivalent to the <productname>Ingres</productname> equivalent to the
<acronym>SQL</acronym>-function <function>extract</function>: <acronym>SQL</acronym>-standard function <function>extract</function>:
<synopsis> <synopsis>
date_part('<replaceable>field</replaceable>', <replaceable>source</replaceable>) date_part('<replaceable>field</replaceable>', <replaceable>source</replaceable>)
</synopsis> </synopsis>
Note that here the <replaceable>field</replaceable> value needs to Note that here the <replaceable>field</replaceable> parameter needs to
be a string. The valid field values for be a string value, not a name. The valid field values for
<function>date_part</function> are the same as for <function>date_part</function> are the same as for
<function>extract</function>. <function>extract</function>.
</para> </para>
@ -4192,6 +4197,95 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
</para> </para>
</sect2> </sect2>
<sect2 id="functions-datetime-zoneconvert">
<title><function>AT TIME ZONE</function></title>
<indexterm>
<primary>timezone</primary>
<secondary>conversion</secondary>
</indexterm>
<para>
The <function>AT TIME ZONE</function> construct allows conversions
of timestamps to different timezones.
</para>
<table id="functions-datetime-zoneconvert-table">
<title>AT TIME ZONE Variants</title>
<tgroup cols="3">
<thead>
<row>
<entry>Expression</entry>
<entry>Returns</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<type>timestamp without time zone</type>
<literal>AT TIME ZONE</literal>
<replaceable>zone</>
</entry>
<entry><type>timestamp with time zone</type></entry>
<entry>Convert local time in given timezone to UTC</entry>
</row>
<row>
<entry>
<type>timestamp with time zone</type>
<literal>AT TIME ZONE</literal>
<replaceable>zone</>
</entry>
<entry><type>timestamp without time zone</type></entry>
<entry>Convert UTC to local time in given timezone</entry>
</row>
<row>
<entry>
<type>time with time zone</type>
<literal>AT TIME ZONE</literal>
<replaceable>zone</>
</entry>
<entry><type>time with time zone</type></entry>
<entry>Convert local time across timezones</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
In these expressions, the desired time <replaceable>zone</> can be
specified either as a text string (e.g., <literal>'PST'</literal>)
or as an interval (e.g., <literal>INTERVAL '-08:00'</literal>).
</para>
<para>
Examples (supposing that <varname>TimeZone</> is <literal>PST8PDT</>):
<screen>
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST';
<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 19:38:40-08</computeroutput>
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST';
<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 18:38:40</computeroutput>
</screen>
The first example takes a zone-less timestamp and interprets it as MST time
(GMT-7) to produce a UTC timestamp, which is then rotated to PST (GMT-8)
for display. The second example takes a timestamp specified in EST
(GMT-5) and converts it to local time in MST (GMT-7).
</para>
<para>
The function <function>timezone</function>(<replaceable>zone</>,
<replaceable>timestamp</>) is equivalent to the SQL-compliant construct
<replaceable>timestamp</> <literal>AT TIME ZONE</literal>
<replaceable>zone</>.
</para>
</sect2>
<sect2 id="functions-datetime-current"> <sect2 id="functions-datetime-current">
<title>Current Date/Time</title> <title>Current Date/Time</title>
@ -4219,6 +4313,16 @@ LOCALTIMESTAMP
LOCALTIME ( <replaceable>precision</replaceable> ) LOCALTIME ( <replaceable>precision</replaceable> )
LOCALTIMESTAMP ( <replaceable>precision</replaceable> ) LOCALTIMESTAMP ( <replaceable>precision</replaceable> )
</synopsis> </synopsis>
</para>
<para>
<function>CURRENT_TIME</function> and
<function>CURRENT_TIMESTAMP</function> deliver values with time zone;
<function>LOCALTIME</function> and
<function>LOCALTIMESTAMP</function> deliver values without time zone.
</para>
<para>
<function>CURRENT_TIME</function>, <function>CURRENT_TIME</function>,
<function>CURRENT_TIMESTAMP</function>, <function>CURRENT_TIMESTAMP</function>,
<function>LOCALTIME</function>, and <function>LOCALTIME</function>, and

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.73 2002/09/21 19:52:41 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.73.2.1 2002/11/21 23:31:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -2013,7 +2013,6 @@ timetz_zone(PG_FUNCTION_ARGS)
text *zone = PG_GETARG_TEXT_P(0); text *zone = PG_GETARG_TEXT_P(0);
TimeTzADT *time = PG_GETARG_TIMETZADT_P(1); TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
TimeTzADT *result; TimeTzADT *result;
TimeADT time1;
int tz; int tz;
int type, int type,
val; val;
@ -2040,15 +2039,17 @@ timetz_zone(PG_FUNCTION_ARGS)
{ {
tz = val * 60; tz = val * 60;
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
time1 = (time->time - ((time->zone + tz) * INT64CONST(1000000))); result->time = time->time + ((time->zone - tz) * INT64CONST(1000000));
result->time -= ((result->time / time1) * time1); while (result->time < INT64CONST(0))
if (result->time < INT64CONST(0))
result->time += INT64CONST(86400000000); result->time += INT64CONST(86400000000);
while (result->time >= INT64CONST(86400000000))
result->time -= INT64CONST(86400000000);
#else #else
time1 = (time->time - time->zone + tz); result->time = time->time + (time->zone - tz);
TMODULO(result->time, time1, 86400e0); while (result->time < 0)
if (result->time < 0)
result->time += 86400; result->time += 86400;
while (result->time >= 86400)
result->time -= 86400;
#endif #endif
result->zone = tz; result->zone = tz;
@ -2087,13 +2088,13 @@ timetz_izone(PG_FUNCTION_ARGS)
result = (TimeTzADT *) palloc(sizeof(TimeTzADT)); result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
result->time = (time->time + ((time->zone - tz) * INT64CONST(1000000))); result->time = time->time + ((time->zone - tz) * INT64CONST(1000000));
while (result->time < INT64CONST(0)) while (result->time < INT64CONST(0))
result->time += INT64CONST(86400000000); result->time += INT64CONST(86400000000);
while (result->time >= INT64CONST(86400000000)) while (result->time >= INT64CONST(86400000000))
result->time -= INT64CONST(86400000000); result->time -= INT64CONST(86400000000);
#else #else
result->time = (time->time + (time->zone - tz)); result->time = time->time + (time->zone - tz);
while (result->time < 0) while (result->time < 0)
result->time += 86400; result->time += 86400;
while (result->time >= 86400) while (result->time >= 86400)