由于数据存储在TIMESTAMP列中,因此您无法自动对其进行转换。您必须编写一些代码来告诉 Oracle 在哪个时区将数据视为存储在该GMT时区中,并告诉它您希望将其转换为会话的时区。TIMESTAMP WITH LOCAL TIME ZONE如果您改用数据类型,您将获得您正在寻找的自动行为。如果您使用TIMESTAMP WITH TIME ZONE数据类型,您将避免在编写转换时告诉数据库时间戳来自哪个时区。
SQL> ed
Wrote file afiedt.buf
1 create table foo(
2 ts timestamp,
3 ts_tz timestamp with time zone,
4* ts_local_tz timestamp with local time zone )
SQL> /
Table created.
SQL> ed
Wrote file afiedt.buf
1 insert into foo
2 values( sys_extract_utc( systimestamp ),
3 systimestamp,
4* systimestamp )
SQL> /
1 row created.
SQL> select from_tz( ts, 'GMT' ) at time zone sessiontimezone ,
2 ts_tz at time zone sessiontimezone,
3 ts_local_tz
4 from foo;
FROM_TZ(TS,'GMT')ATTIMEZONESESSIONTIMEZONE
---------------------------------------------------------------------------
TS_TZATTIMEZONESESSIONTIMEZONE
---------------------------------------------------------------------------
TS_LOCAL_TZ
---------------------------------------------------------------------------
02-MAY-13 01.59.03.171000 PM -08:00
02-MAY-13 01.59.03.171000 PM -08:00
02-MAY-13 01.59.03.171000 PM
针对 DylanKlomparens 的以下评论 - 您不能只将 a 应用于AT TIME ZONEaTIMESTAMP并期望得到正确的结果,所以我不确定我是否理解您所看到的。如果您只是AT TIME ZONE在一个普通TIMESTAMP的,时间戳被简单地视为具有您指定的时区。它不会改变时间。它也不依赖于会话时区。在所有这些情况下,如果ts表示UTC时间,则PST版本表示错误的时间——开始值和结束值之间应该有 8 小时的差异。
SQL> select ts from foo;
TS
---------------------------------------------------------------------------
02-MAY-13 09.59.03.171000 PM
SQL> select ts at time zone 'PST' from foo;
TSATTIMEZONE'PST'
---------------------------------------------------------------------------
02-MAY-13 09.59.03.171000 PM PST
SQL> alter session set time_zone = '-0:00';
Session altered.
SQL> select ts at time zone 'PST' from foo;
TSATTIMEZONE'PST'
---------------------------------------------------------------------------
02-MAY-13 09.59.03.171000 PM PST
SQL> alter session set time_zone = '-4:00';
Session altered.
SQL> select ts at time zone 'PST' from foo;
TSATTIMEZONE'PST'
---------------------------------------------------------------------------
02-MAY-13 09.59.03.171000 PM PST
作为对文森特评论的回应——TIMESTAMP WITH LOCAL TIME ZONE无论服务器的时区如何,A 都会自动调整到会话的时区。当我调整会话的时区时,结果也会发生变化。
SQL> select ts_local_tz from foo;
TS_LOCAL_TZ
---------------------------------------------------------------------------
02-MAY-13 05.59.03.171000 PM
Elapsed: 00:00:00.00
SQL> alter session set time_zone = '-0:00';
Session altered.
Elapsed: 00:00:00.00
SQL> select ts_local_tz from foo;
TS_LOCAL_TZ
---------------------------------------------------------------------------
02-MAY-13 09.59.03.171000 PM
Elapsed: 00:00:00.00
SQL> alter session set time_zone = '+4:00';
Session altered.
Elapsed: 00:00:00.00
SQL> select ts_local_tz from foo;
TS_LOCAL_TZ
---------------------------------------------------------------------------
03-MAY-13 01.59.03.171000 AM
Elapsed: 00:00:00.00
由于数据存储在
TIMESTAMP
列中,因此您无法自动对其进行转换。您必须编写一些代码来告诉 Oracle 在哪个时区将数据视为存储在该GMT
时区中,并告诉它您希望将其转换为会话的时区。TIMESTAMP WITH LOCAL TIME ZONE
如果您改用数据类型,您将获得您正在寻找的自动行为。如果您使用TIMESTAMP WITH TIME ZONE
数据类型,您将避免在编写转换时告诉数据库时间戳来自哪个时区。假设您的会话正确设置了时区
例如,会告诉 Oracle 当前会话是 GMT 前 8 小时(当前为太平洋时区),如果数据存储在
TIMESTAMP
列中,则需要类似如果数据存储在
TIMESTAMP WITH TIME ZONE
列中,您只需要如果数据存储在
TIMESTAMP WITH LOCAL TIME ZONE
列中,您只需选择该列。一个例子
针对 DylanKlomparens 的以下评论 - 您不能只将 a 应用于
AT TIME ZONE
aTIMESTAMP
并期望得到正确的结果,所以我不确定我是否理解您所看到的。如果您只是AT TIME ZONE
在一个普通TIMESTAMP
的,时间戳被简单地视为具有您指定的时区。它不会改变时间。它也不依赖于会话时区。在所有这些情况下,如果ts
表示UTC
时间,则PST
版本表示错误的时间——开始值和结束值之间应该有 8 小时的差异。作为对文森特评论的回应——
TIMESTAMP WITH LOCAL TIME ZONE
无论服务器的时区如何,A 都会自动调整到会话的时区。当我调整会话的时区时,结果也会发生变化。