> 数据库 > Oracle >

ORACLE中的时区(time zone)

oracle对时区的支持比较完美了,有timestamp with time zone和timestamp with local time zone两种数据类型。所谓timestamp with time zone,也就是把时区信息保存在列数据中,而timestamp with local time zone,会将用户输入的时间转换为数据库服务器所在时区的时间,保存在列中,这样能稍稍减少一点保存的数据量。因为timestamp with local time zone中不会保存时区信息(时区与数据库服务器所在时区相同),所以当数据库中有表存在timestamp with local time zone 时,数据库不能更改时区。如果有可能将数据库跨时区迁移,最好还是用timestamp with time zone好了,该数据类型最具有扩展性。

说起时区,不得不提及几个关于timestamp的函数了:

systimestamp 数据库服务器当前的时间以及时区;

localtimestamp 客户端当前时间,不包含时区;

current_timestamp 客户端当前时区,包含客户端的时区。

 

说了这么多,下面看个例子,为了看到例子的效果,我们首先修改客户端的时区为西五区(美国东部时间),实验当前时间为北京时间2010年01月03日早晨11点左右。

alter session set TIME_ZONE='-5:00';

 

然后新建一个表

CREATE TABLE TEST(ID number(2), time_tz timestamp with time zone, time_lc_tz timestamp with local time zone);

 

表中插入几行看看:

insert into test values (1,localtimestamp,localtimestamp); insert into test values (2,systimestamp,systimestamp); insert into test values (3,current_timestamp,current_timestamp); insert into test values (3,current_timestamp,current_timestamp); insert into test values(4,to_timestamp('2010-01-03 11:09:00','YYYY-MM-DD HH24:MI:SS'), to_timestamp('2010-01-03 11:09:00','YYYY-MM-DD HH24:MI:SS')); insert into test values(5,to_timestamp_tz('2010-01-03 11:09:00 +0:00','YYYY-MM-DD HH24:MI:SS TZH:TZM'), to_timestamp_tz('2010-01-03 11:09:00 +0:00','YYYY-MM-DD HH24:MI:SS TZH:TZM'));

 

提交插入的数据:COMMIT;

 

在当前session查询看看:(当前session时区为-5:00)

select * from test;

 

ID TIME_TZ TIME_LC_TZ
1 02-1月 -10 09.58.45.106141 下午 -05:00 02-1月 -10 09.58.45.106141 下午
2 03-1月 -10 10.58.45.130013 上午 +08:00 02-1月 -10 09.58.45.130013 下午
3 02-1月 -10 09.58.45.146003 下午 -05:00 02-1月 -10 09.58.45.146003 下午
4 03-1月 -10 11.09.00.000000 上午 -05:00 03-1月 -10 11.09.00.000000 上午
5 03-1月 -10 11.09.00.000000 上午 +00:00 03-1月 -10 06.09.00.000000 上午

 

 

ID TIME_TZ TIME_LC_TZ 1 02-1月 -10 09.58.45.106141 下午 -05:00 02-1月 -10 09.58.45.106141 下午 (localtimestamp不带时区,所以这里将session时区加上去了。)

2 03-1月 -10 10.58.45.130013 上午 +08:00 02-1月 -10 09.58.45.130013 下午 (systimestamp带服务器所在时区,东八区)

3 02-1月 -10 09.58.45.146003 下午 -05:00 02-1月 -10 09.58.45.146003 下午 (current_timestamp 带session所在时区)

4 03-1月 -10 11.09.00.000000 上午 -05:00 03-1月 -10 11.09.00.000000 上午 (插入timestamp 不带时区,默认将session所在时区作为时区)5 03-1月 -10 11.09.00.000000 上午 +00:00 03-1月 -10 06.09.00.000000 上午 (插入timestamp with time zone带时区)

不管如何插入,TIME_LC_TZ都会转化为数据库所在的时区在表中保存,查询时会转化为session所在的时区时间进行显示。

 

 

打开另外一个客户端,查询test表,此时TIME_TZ列的显示不变,TIME_LC_TZ列的显示会转换为session所在的时区进行显示(目前为东八区)

select * from test;

 

 

ID TIME_TZ TIME_LC_TZ
1 02-1月 -10 09.58.45.106141 下午 -05:00 03-1月 -10 10.58.45.106141 上午
2 03-1月 -10 10.58.45.130013 上午 +08:00 03-1月 -10 10.58.45.130013 上午
3 02-1月 -10 09.58.45.146003 下午 -05:00 03-1月 -10 10.58.45.146003 上午
4 03-1月 -10 11.09.00.000000 上午 -05:00 04-1月 -10 12.09.00.000000 上午
5 03-1月 -10 11.09.00.000000 上午 +00:00 03-1月 -10 07.09.00.000000 下午

 

 

综上,如果不喜欢自己换算时间,则用timestamp with local time zone,这样只需将自己session所在的时区设置正确就OK了。如果喜欢保存原本的时区信息,则用timestamp with time zone。如果数据库可能跨时区迁移,或者需要根据时区统计一些信息,则要用timestamp with time zone。



(责任编辑:IT)