@ -8,7 +8,7 @@
*
*
* 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 $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -4012,61 +4012,64 @@ timestamp_zone(PG_FUNCTION_ARGS)
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 */
resul t = 0 ; /* keep compiler quiet */
}
result = dt2local ( timestamp , tz ) ;
}
PG_RETURN_TIMESTAMPTZ ( result ) ;
@ -4185,60 +4188,63 @@ timestamptz_zone(PG_FUNCTION_ARGS)
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 */
resul t = 0 ; /* keep compiler quiet */
}
result = dt2local ( timestamp , tz ) ;
}
PG_RETURN_TIMESTAMP ( result ) ;