*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.122.2.2 2007/06/02 16:41:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.122.2.3 2008/07/07 18:10:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int tz;
char tzname[TZ_STRLEN_MAX + 1];
int len;
+ char *lowzone;
+ int type,
+ val;
pg_tz *tzp;
/*
- * Look up the requested timezone. First we look in the timezone database
- * (to handle cases like "America/New_York"), and if that fails, we look
- * in the date token table (to handle cases like "EST").
+ * Look up the requested timezone. First we look in the date token table
+ * (to handle cases like "EST"), and if that fails, we look in the
+ * timezone database (to handle cases like "America/New_York"). (This
+ * matches the order in which timestamp input checks the cases; it's
+ * important because the timezone database unwisely uses a few zone names
+ * that are identical to offset abbreviations.)
*/
- len = Min(VARSIZE(zone) - VARHDRSZ, TZ_STRLEN_MAX);
- memcpy(tzname, VARDATA(zone), len);
- tzname[len] = '\0';
- tzp = pg_tzset(tzname);
- if (tzp)
- {
- /* Get the offset-from-GMT that is valid today for the selected zone */
- pg_time_t now;
- struct pg_tm *tm;
+ lowzone = downcase_truncate_identifier(VARDATA(zone),
+ VARSIZE(zone) - VARHDRSZ,
+ false);
+ type = DecodeSpecial(0, lowzone, &val);
- now = time(NULL);
- tm = pg_localtime(&now, tzp);
- tz = -tm->tm_gmtoff;
- }
+ if (type == TZ || type == DTZ)
+ tz = val * 60;
else
{
- char *lowzone;
- int type,
- val;
-
- lowzone = downcase_truncate_identifier(VARDATA(zone),
- VARSIZE(zone) - VARHDRSZ,
- false);
- type = DecodeSpecial(0, lowzone, &val);
+ len = Min(VARSIZE(zone) - VARHDRSZ, TZ_STRLEN_MAX);
+ memcpy(tzname, VARDATA(zone), len);
+ tzname[len] = '\0';
+ tzp = pg_tzset(tzname);
+ if (tzp)
+ {
+ /* Get the offset-from-GMT that is valid today for the zone */
+ pg_time_t now;
+ struct pg_tm *tm;
- if (type == TZ || type == DTZ)
- tz = val * 60;
+ now = time(NULL);
+ tm = pg_localtime(&now, tzp);
+ tz = -tm->tm_gmtoff;
+ }
else
{
ereport(ERROR,
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.157.2.2 2007/09/16 15:56:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.157.2.3 2008/07/07 18:10:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
TimestampTz result;
int tz;
- pg_tz *tzp;
char tzname[TZ_STRLEN_MAX + 1];
int len;
+ char *lowzone;
+ int type,
+ val;
+ pg_tz *tzp;
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMPTZ(timestamp);
/*
- * Look up the requested timezone. First we look in the timezone database
- * (to handle cases like "America/New_York"), and if that fails, we look
- * in the date token table (to handle cases like "EST").
+ * Look up the requested timezone. First we look in the date token table
+ * (to handle cases like "EST"), and if that fails, we look in the
+ * timezone database (to handle cases like "America/New_York"). (This
+ * matches the order in which timestamp input checks the cases; it's
+ * important because the timezone database unwisely uses a few zone names
+ * that are identical to offset abbreviations.)
*/
- len = Min(VARSIZE(zone) - VARHDRSZ, TZ_STRLEN_MAX);
- memcpy(tzname, VARDATA(zone), len);
- tzname[len] = '\0';
- tzp = pg_tzset(tzname);
- if (tzp)
- {
- /* Apply the timezone change */
- struct pg_tm tm;
- fsec_t fsec;
+ lowzone = downcase_truncate_identifier(VARDATA(zone),
+ VARSIZE(zone) - VARHDRSZ,
+ false);
+ type = DecodeSpecial(0, lowzone, &val);
- if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("timestamp out of range")));
- tz = DetermineTimeZoneOffset(&tm, tzp);
- if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("could not convert to time zone \"%s\"",
- tzname)));
+ if (type == TZ || type == DTZ)
+ {
+ tz = -(val * 60);
+ result = dt2local(timestamp, tz);
}
else
{
- char *lowzone;
- int type,
- val;
-
- lowzone = downcase_truncate_identifier(VARDATA(zone),
- VARSIZE(zone) - VARHDRSZ,
- false);
- type = DecodeSpecial(0, lowzone, &val);
+ len = Min(VARSIZE(zone) - VARHDRSZ, TZ_STRLEN_MAX);
+ memcpy(tzname, VARDATA(zone), len);
+ tzname[len] = '\0';
+ tzp = pg_tzset(tzname);
+ if (tzp)
+ {
+ /* Apply the timezone change */
+ struct pg_tm tm;
+ fsec_t fsec;
- if (type == TZ || type == DTZ)
- tz = -(val * 60);
+ if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+ errmsg("timestamp out of range")));
+ tz = DetermineTimeZoneOffset(&tm, tzp);
+ if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("could not convert to time zone \"%s\"",
+ tzname)));
+ }
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("time zone \"%s\" not recognized", tzname)));
- tz = 0; /* keep compiler quiet */
+ result = 0; /* keep compiler quiet */
}
-
- result = dt2local(timestamp, tz);
}
PG_RETURN_TIMESTAMPTZ(result);
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1);
Timestamp result;
int tz;
- pg_tz *tzp;
char tzname[TZ_STRLEN_MAX + 1];
int len;
+ char *lowzone;
+ int type,
+ val;
+ pg_tz *tzp;
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMP(timestamp);
/*
- * Look up the requested timezone. First we look in the timezone database
- * (to handle cases like "America/New_York"), and if that fails, we look
- * in the date token table (to handle cases like "EST").
+ * Look up the requested timezone. First we look in the date token table
+ * (to handle cases like "EST"), and if that fails, we look in the
+ * timezone database (to handle cases like "America/New_York"). (This
+ * matches the order in which timestamp input checks the cases; it's
+ * important because the timezone database unwisely uses a few zone names
+ * that are identical to offset abbreviations.)
*/
- len = Min(VARSIZE(zone) - VARHDRSZ, TZ_STRLEN_MAX);
- memcpy(tzname, VARDATA(zone), len);
- tzname[len] = '\0';
- tzp = pg_tzset(tzname);
- if (tzp)
- {
- /* Apply the timezone change */
- struct pg_tm tm;
- fsec_t fsec;
+ lowzone = downcase_truncate_identifier(VARDATA(zone),
+ VARSIZE(zone) - VARHDRSZ,
+ false);
+ type = DecodeSpecial(0, lowzone, &val);
- if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("timestamp out of range")));
- if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("could not convert to time zone \"%s\"",
- tzname)));
+ if (type == TZ || type == DTZ)
+ {
+ tz = val * 60;
+ result = dt2local(timestamp, tz);
}
else
{
- char *lowzone;
- int type,
- val;
-
- lowzone = downcase_truncate_identifier(VARDATA(zone),
- VARSIZE(zone) - VARHDRSZ,
- false);
- type = DecodeSpecial(0, lowzone, &val);
+ len = Min(VARSIZE(zone) - VARHDRSZ, TZ_STRLEN_MAX);
+ memcpy(tzname, VARDATA(zone), len);
+ tzname[len] = '\0';
+ tzp = pg_tzset(tzname);
+ if (tzp)
+ {
+ /* Apply the timezone change */
+ struct pg_tm tm;
+ fsec_t fsec;
- if (type == TZ || type == DTZ)
- tz = val * 60;
+ if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+ errmsg("timestamp out of range")));
+ if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("could not convert to time zone \"%s\"",
+ tzname)));
+ }
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("time zone \"%s\" not recognized", tzname)));
- tz = 0; /* keep compiler quiet */
+ result = 0; /* keep compiler quiet */
}
-
- result = dt2local(timestamp, tz);
}
PG_RETURN_TIMESTAMP(result);