-<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.178 2006/10/17 21:03:20 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.179 2006/10/18 16:43:13 tgl Exp $ -->
<chapter id="datatype">
<title id="datatype-title">Data Types</title>
<entry><type>time [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
<entry>12 bytes</entry>
<entry>times of day only, with time zone</entry>
- <entry>00:00:00+1359</entry>
- <entry>24:00:00-1359</entry>
+ <entry>00:00:00+1459</entry>
+ <entry>24:00:00-1459</entry>
<entry>1 microsecond / 14 digits</entry>
</row>
</tbody>
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. You can also specify a date but it will
- be ignored, except when you use a full time zone name like
+ be ignored, except when you use a time zone name that involves a
+ daylight-savings rule, such as
<literal>America/New_York</literal>. In this case specifying the date
is required in order to determine whether standard or daylight-savings
time applies. The appropriate time zone offset is recorded in the
</programlisting>
are valid values, which follow the <acronym>ISO</acronym> 8601
- standard. You can also specify the full time zone name as in
-<programlisting>
-1999-01-08 04:05:06 America/New_York
-</programlisting>
-
- In addition, the wide-spread format
+ standard. In addition, the wide-spread format
<programlisting>
January 8 04:05:06 1999 PST
</programlisting>
There is a conceptual and practical difference between the abbreviations
and the full names: abbreviations always represent a fixed offset from
UTC, whereas most of the full names imply a local daylight-savings time
- rule and so have two possible UTC offsets. That's why you always have to
- specify a date if you want to use full time zone names in <type>timetz</>
- values. This is also the reason why you should set <xref
- linkend="guc-timezone"> to a full time zone name: this way,
- <productname>PostgreSQL</productname>
- will always know the correct UTC offset for your region.
+ rule and so have two possible UTC offsets.
</para>
<para>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.173 2006/10/17 21:03:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.174 2006/10/18 16:43:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
ptype = val;
break;
+ case UNKNOWN_FIELD:
+ /*
+ * Before giving up and declaring error, check to see
+ * if it is an all-alpha timezone name.
+ */
+ namedTz = pg_tzset(field[i]);
+ if (!namedTz)
+ return DTERR_BAD_FORMAT;
+ /* we'll apply the zone setting below */
+ tmask = DTK_M(TZ);
+ break;
+
default:
return DTERR_BAD_FORMAT;
}
ptype = val;
break;
+ case UNKNOWN_FIELD:
+ /*
+ * Before giving up and declaring error, check to see
+ * if it is an all-alpha timezone name.
+ */
+ namedTz = pg_tzset(field[i]);
+ if (!namedTz)
+ return DTERR_BAD_FORMAT;
+ /* we'll apply the zone setting below */
+ tmask = DTK_M(TZ);
+ break;
+
default:
return DTERR_BAD_FORMAT;
}
/*
* If we had a full timezone spec, compute the offset (we could not
- * do it before, because we need the date to resolve DST status).
+ * do it before, because we may need the date to resolve DST status).
*/
if (namedTz != NULL)
{
- /* a date has to be specified */
- if ((fmask & DTK_DATE_M) != DTK_DATE_M)
- return DTERR_BAD_FORMAT;
+ long int gmtoff;
+
/* daylight savings time modifier disallowed with full TZ */
if (fmask & DTK_M(DTZMOD))
return DTERR_BAD_FORMAT;
- *tzp = DetermineTimeZoneOffset(tm, namedTz);
+ /* if non-DST zone, we do not need to know the date */
+ if (pg_get_timezone_offset(namedTz, &gmtoff))
+ {
+ *tzp = -(int) gmtoff;
+ }
+ else
+ {
+ /* a date has to be specified */
+ if ((fmask & DTK_DATE_M) != DTK_DATE_M)
+ return DTERR_BAD_FORMAT;
+ *tzp = DetermineTimeZoneOffset(tm, namedTz);
+ }
}
/* timezone not specified? then find local timezone if possible */
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/include/pgtime.h,v 1.13 2006/09/16 20:14:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/pgtime.h,v 1.14 2006/10/18 16:43:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
extern bool tz_acceptable(pg_tz *tz);
+extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff);
extern const char *pg_get_timezone_name(pg_tz *tz);
extern pg_tzenum *pg_tzenumerate_start(void);
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.61 2006/09/16 20:14:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.62 2006/10/18 16:43:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
#define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
-#define MAXDATELEN 51 /* maximum possible length of an input date
+#define MAXDATELEN 63 /* maximum possible length of an input date
* string (not counting tr. null) */
#define MAXDATEFIELDS 25 /* maximum possible number of fields in a date
* string */
* 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.15 2006/10/16 19:58:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.16 2006/10/18 16:43:14 tgl Exp $
*/
/*
return 1;
}
+/*
+ * If the given timezone uses only one GMT offset, store that offset
+ * into *gmtoff and return TRUE, else return FALSE.
+ */
+bool
+pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
+{
+ /*
+ * The zone could have more than one ttinfo, if it's historically used
+ * more than one abbreviation. We return TRUE as long as they all have
+ * the same gmtoff.
+ */
+ const struct state *sp;
+ int i;
+
+ sp = &tz->state;
+ for (i = 1; i < sp->typecnt; i++)
+ {
+ if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
+ return false;
+ }
+ *gmtoff = sp->ttis[0].tt_gmtoff;
+ return true;
+}
+
/*
* Return the name of the current timezone
*/