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 下午 (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;
综上,如果不喜欢自己换算时间,则用timestamp with local time zone,这样只需将自己session所在的时区设置正确就OK了。如果喜欢保存原本的时区信息,则用timestamp with time zone。如果数据库可能跨时区迁移,或者需要根据时区统计一些信息,则要用timestamp with time zone。 (责任编辑:IT) |