本节,我会引入很多概念,慢慢的一个一个的消化。。。。。。。
CET
欧洲中部时间(英語:Central European Time,CET)是比世界标准时间(UTC)早一个小时的时区名称之一。它被大部分欧洲国家和部分北非国家采用。冬季时间为UTC+1,夏季欧洲夏令时为UTC+2。
参考:http://zh.wikipedia.org/zh/%E6%AC%A7%E6%B4%B2%E4%B8%AD%E9%83%A8%E6%97%B6%E9%97%B4
CST
北京时间,China Standard Time,又名中国标准时间,是中国的标准时间。在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8,与中华民国国家标准时间(旧称“中原标准时间”)、香港时间和澳门时间和相同。當格林威治時間為凌晨0:00時,中國標準時間剛好為上午8:00。
参考:http://zh.wikipedia.org/zh/CSThttp://zh.wikipedia.org/wiki/%E5%8C%97%E4%BA%AC%E6%97%B6%E9%97%B4
关系
CET=UTC/GMT + 1小时
CST=UTC/GMT +8 小时
CST=CET+9
DST夏令时:
DST是Daylight Saving Time的缩写,称为阳光节约时,在我国称为夏时制,又称夏令时,是一种为节约能源而人为调整地方时间的制度。有些国家DST的使用时间较长,(如美国长达7个月)跨越了春夏秋等三个季节,因此简单地用夏时制的概念已经不能完全表达DST的确切含义了,所以有人也称其为节能时。本文统一使用“DST”这一说法。所谓的DST,就是利用夏季天亮得早这一自然现象,人为地将时间提前一小时。这样就可以使人们早起早睡,以充分利用光照资源,减少照明时间,从而节约照明用电。
timezone offset 和 named timezone:
所谓offset就是指偏移,位移,比如我们东八区就会用 UTD/GMT +8 这个偏移量来表示;而named表示方法一般是这样:(example: Canada/Eastern ,Asia/Shanghai or GMT) ,直接用地区来表示这个timezone。那么既然有了这种offset的表示方法,何必再有用named的表示方法呢?原因就是因为上文提到的DST夏令时,有些非常注重环保节约的国家,会在夏季统一把时钟调快一个小时,比如伦敦冬天时UTC/GMT+0,但是到了夏天就成了UTC/GMT+1了。这样,偏移量表示就没法了,到底用哪个还得根据不同季节来回变,但是这个named timezone就好啦,不管怎么样,我就是伦敦timezone。
DATABASE timezone:参考文档:Timestamps & time zones - Frequently Asked Questions (文档 ID 340512.1)
数据库的时区并不像听起来那么重要。首先,它不影响像SYSDATE,或SYSTIMESTAMP功能,这些功能把他们的内容(日期和时间,并在SYSTIMESTAMP也时区的情况下)完全取决于操作系统。没有任何“oracle”产品的影响。
数据库时区的唯一功能是:它作为一个时区标准,“TIMESTAMP WITH LOCAL TIME ZONE”(TSLTZ)数据类型的值都被格式化并存储成当前数据库时区的格式。然而,在回话的检索或者插入式,这些存储的值将被转换成当前会话端的时区,所以数据库时区的实际设置是或多或少的不重要。
用于会话的时区是会话的时区,并在客户端的定义,而不是数据库端
该DBTIMEZONE应设置为一个偏移量(+00:00,-05:00或+09:00例如),或不会受DST(如UTC或GMT)静态时区,而不是一个命名时区是由DST(像欧洲/布鲁塞尔或美国/中部)的影响。
如何查看数据库当前的timezone呢?可以用如下命令:
select dbtimezone from dual;
这个dbtimezone只是用来格式化TSLTZ的数据,没有任何别的用处,会在数据库创建的时候有个sql( CREATE DATABASE... SET TIME_ZONE='+00:00';)可以去指定,如果不指定,就会用os server上的timezone offset。
After database creation the ALTER DATABASE SET TIME_ZONE statement can be used to change the database time zone. This will only work if there are no TSLTZ values already stored in the database or an ORA-02231 (9i) or ORA-30079 will be seen:
<code>SQL> ALTER DATABASE SET TIME_ZONE = '+00:00';</code>
The change will not take effect until the database is restarted.
You can only change the database time zone if you have no TIMESTAMP WITH LOCAL TIME ZONE columns in the database otherwise ORA-02231: missing or invalid option to ALTER DATABASE (in 9i) or ORA-30079: cannot alter database timezone when database has TIMESTAMP WITH LOCAL TIME ZONE columns (in 10g and up) will be seen.
To change the DBTIMEZONE for an database that has already TIMESTAMP WITH LOCAL TIME ZONE columns one need to
a) export all tables that have TIMESTAMP WITH LOCAL TIME ZONE columns
select c.owner || '.' || c.table_name || '(' || c.column_name || ') -' || c.data_type || ' ' col
from dba_tab_cols c, dba_objects o
where c.data_type like '%WITH LOCAL TIME ZONE'
and c.owner=o.owner
and c.table_name = o.object_name
and o.object_type = 'TABLE'
order by col
/
b) truncate or drop those tables
c) change the DBTIMEZONE making sure the are no tables with TSLTZ in the RECYCLEBIN and restart the database
<code>SQL>PURGE DBA_RECYCLEBIN / SQL> ALTER DATABASE SET TIME_ZONE = '+00:00'; SQL> SHUTDOWN</code>
d) import the exported table again.
They all depend on the session timezone, which is defined on the CLIENT side, not server side.
CURRENT_DATE returns the current date and time in the session time zone in a value of datatype DATE.
LOCALTIMESTAMP returns the current date and time in the session time zone in a value of datatype TIMESTAMP.
CURRENT_TIMESTAMP returns the current date and time in the session time zone, in a value of datatype TIMESTAMP WITH TIME ZONE.
The sessions NLS_DATE_FORMAT defines the output format of a DATE, NLS_TIMESTAMP_FORMAT defines the output format of a TIMESTAMP, the NLS_TIMESTAMP_TZ_FORMAT defines the output format of a TIMESTAMP WITH TIME ZONE.
ALTER SESSION SET TIME_ZONE = '-05:00';
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT ='DD/MM/YYYY HH24:MI:SS TZR TZD' NLS_TIMESTAMP_FORMAT ='DD*MM*YYYY HH24:MI:SS' NLS_DATE_FORMAT ='DD-MM-YYYY HH24:MI:SS';
SELECT SESSIONTIMEZONE, CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP FROM DUAL;
-- gives for example:
SQL> SELECT SESSIONTIMEZONE, CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP FRO
M DUAL;
SESSIONTIMEZONE
---------------------------------------------------------------------------
CURRENT_DATE
-------------------
CURRENT_TIMESTAMP
LOCALTIMESTAMP
-05:00
28-10-2009 06:47:19
28/10/2009 06:47:18 -05:00
28*10*2009 06:47:18
-- and when doing an alter of the session timezone
ALTER SESSION SET TIME_ZONE = '-08:00';
-- gives for example:
-08:00
28-10-2009 03:47:49
28/10/2009 03:47:49 -08:00
28*10*2009 03:47:49
2、概述
商业和数据库很多时候必须跨时区工作,从9i开始,oracle环境开始有了时区意识,通过指定数据库的时区和使用如下两种数据类型来存储时区:
TIMESTAMP WITH TIME ZONE和TIMESTAMP WITH LOCAL TIME ZONE。
TIMESTAMP WITH TIME ZONE(TSTZ):,存储了时间和真实的时区(用offset/name的形式表示),存储了现在的时间,时区是东八区。但是不会存储数据库的时区。这个数据类型的格式是由数据库参数NLS_TIMESTAMP_TZ_FORMAT来决定的,如下:
nls_timestamp_tz_format string DD-MON-RR HH.MI.SSXFF AM TZR
当涉及到时区的时候,TSTZ通常是最好的存储时区信息的数据类型。通过下面这个查询,会查出你数据库中所有TSTZ的列:
select c.owner || '.' || c.table_name || '(' || c.column_name || ') -'
|| c.data_type || ' ' col
from dba_tab_cols c, dba_objects o
where c.data_type like '%WITH TIME ZONE'
and c.owner=o.owner
and c.table_name = o.object_name
and o.object_type = 'TABLE'
order by col
TIMESTAMP WITH LOCAL TIME ZONE(TSLTZ):会同时存储数据库时区,并且会根据查询客户端的时区进行相应的转换。
数据库时区可以在创建时在create database命令中设置,也可以使用alter database set TIME_ZONE=...来修改。如果没有特别的指定,默认的,数据库将遵从主机操作系统时区设置,或者取自环境变量ORA_STDZ。所有支持的时区记录在V$TIMEZONE_NAMES动态性能表中。时区有三种表示方法,全名、缩写和相对于标准时间(格林威治时间)的固定偏移,比如标准时间相应的三种表示方法分别为:Etc/Greenwich、GMT和+00:00。
select c.owner || '.' || c.table_name || '(' || c.column_name || ') -' || c.data_type || ' ' col
where c.data_type like '%WITH LOCAL TIME ZONE'
Oracle 9i 开始多了 3 个关于时间的数据类型:TIMESTAMP [(precision)] TIMESTAMP [(precision)] WITH TIME ZONE TIMESTAMP [(precision)] WITH LOCAL TIME ZONE,其中 TIMESTAMP [(precision)] WITH TIME ZONE 保存了时区信息。