[20150708]关于时区的问题.txt
--昨天被一个时区的问题搞糊涂了。
SELECT *
FROM ( SELECT log_date
,owner
,job_name
,status
,req_start_date
FROM DBA_SCHEDULER_JOB_RUN_DETAILS
WHERE job_name LIKE 'PURGE_LOG'
ORDER BY 1 DESC)
WHERE ROWNUM
LOG_DATE OWNER JOB_NAME STATUS REQ_START_DATE RUN_DURATION
--------------------------- ------ ---------- --------- --------------------------- --------------
2015-07-07 18:00:01.320954 SYS PURGE_LOG SUCCEEDED 2015-07-07 03:00:00.400000 +000 00:00:01
2015-07-06 18:00:01.102518 SYS PURGE_LOG SUCCEEDED 2015-07-06 03:00:00.300000 +000 00:00:01
--什么会相差什么大呢?LOG_DATE,REQ_START_DATE。
SELECT *
FROM ( SELECT log_date
,owner
,job_name
,status
,req_start_date
,run_duration
,log_date - req_start_date
FROM DBA_SCHEDULER_JOB_RUN_DETAILS
WHERE job_name LIKE 'PURGE_LOG'
ORDER BY 1 DESC)
WHERE ROWNUM
LOG_DATE OWNER JOB_NAME STATUS REQ_START_DATE RUN_DURATION LOG_DATE-REQ_START_DATE
--------------------------- ------ ---------- ---------- --------------------------- ------------- --------------------------
2015-07-07 18:00:01.320954 SYS PURGE_LOG SUCCEEDED 2015-07-07 03:00:00.400000 +000 00:00:01 +000000000 00:00:00.920954
2015-07-06 18:00:01.102518 SYS PURGE_LOG SUCCEEDED 2015-07-06 03:00:00.300000 +000 00:00:01 +000000000 00:00:00.802518
--LOG_DATE-REQ_START_DATE 很小的。
@desc DBA_SCHEDULER_JOB_RUN_DETAILS
--发现这个类型TIMESTAMP(6) WITH TIME ZONE。
--在toad下查看发现,显示的时间是:2015/7/7 18:00:01.320954 +08:00,2015/7/7 3:00:00.400000 -07:00。
--看来是时区的问题。
$ echo $NLS_TIMESTAMP_TZ_FORMAT
YYYY-MM-DD HH24:MI:SS.FF
$ export NLS_TIMESTAMP_TZ_FORMAT=
LOG_DATE OWNER JOB_NAME STATUS REQ_START_DATE RUN_DURATION LOG_DATE-REQ_START_DATE
------------------------------------ ------ ---------- ---------- ---------------------------------------- -------------------- --------------------------
07-JUL-15 06.00.01.320954 PM +08:00 SYS PURGE_LOG SUCCEEDED 07-JUL-15 03.00.00.400000 AM PST8PDT +000 00:00:01 +000000000 00:00:00.920954
06-JUL-15 06.00.01.102518 PM +08:00 SYS PURGE_LOG SUCCEEDED 06-JUL-15 03.00.00.300000 AM PST8PDT +000 00:00:01 +000000000 00:00:00.802518
--看来不能定义NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF'。这样很容易存在歧义性。
SCOTT@test> select * from NLS_DATABASE_PARAMETERS where parameter='NLS_TIMESTAMP_TZ_FORMAT';
PARAMETER VALUE
------------------------------ ----------------------------
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
$ export NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZR'
SCOTT@test> /
LOG_DATE OWNER JOB_NAME STATUS REQ_START_DATE RUN_DURATION LOG_DATE-REQ_START_DATE
---------------------------------- ------ ---------- ---------- ---------------------------------------- -------------------- --------------------------------
2015-07-07 18:00:01.320954 +08:00 SYS PURGE_LOG SUCCEEDED 2015-07-07 03:00:00.400000 PST8PDT +000 00:00:01 +000000000 00:00:00.920954
2015-07-06 18:00:01.102518 +08:00 SYS PURGE_LOG SUCCEEDED 2015-07-06 03:00:00.300000 PST8PDT +000 00:00:01 +000000000 00:00:00.802518
--奇怪toad下能显示-07:00,而我这里仅仅显示PST8PDT,如果显示数字呢?google发现定义如下:
$ export NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM'
SCOTT@test> /
LOG_DATE OWNER JOB_NAME STATUS REQ_START_DATE RUN_DURATION LOG_DATE-REQ_START_DATE
---------------------------------------- ------ ---------- ---------- ---------------------------------------- -------------------- ---------------------------
2015-07-07 18:00:01.320954 +08:00 SYS PURGE_LOG SUCCEEDED 2015-07-07 03:00:00.400000 -07:00 +000 00:00:01 +000000000 00:00:00.920954
2015-07-06 18:00:01.102518 +08:00 SYS PURGE_LOG SUCCEEDED 2015-07-06 03:00:00.300000 -07:00 +000 00:00:01 +000000000 00:00:00.802518
--剩下的问题是如何看2015-07-07 18:00:01.320954 +08:00,2015-07-07 03:00:00.400000 -07:00是差不多一致的时间。
SCOTT@test> alter session set time_zone = '+0:00';
Session altered.
SCOTT@test> select systimestamp,current_timestamp from v$database ;
SYSTIMESTAMP CURRENT_TIMESTAMP
---------------------------------- ----------------------------------
2015-07-08 11:20:27.070505 +08:00 2015-07-08 03:20:27.070513 +00:00
--如果时间取格林尼治时间时区是+0:00,使用当前时间-减去8小时。相对8时区的情况。(哎,小学生的数学都忘记了)。
--这样上面2015-07-07 18:00:01.320954 +08:00 (减小8小时)= 2015-07-07 10:00:01.320954 +00:00(格林尼治时间)
2015-07-07 03:00:00.400000 -07:00 (加上7小时)= 2015-07-07 10:00:00.400000 +00:00(格林尼治时间)
--这样就差不多了,补充1点小常识:
PST8PDT是什么时区?
PST-Pacific Standard Time太平洋标准时间[加拿大及美国太平洋标准时间.PST是美国西部城市通用的标准时间,以旧金山的时间为准.
PDT太平洋夏季时间.美国西海岸(旧金山 洛杉矶西雅图波特兰)在夏时制时用这一时间. 夏时制结束后就是PST.
以UTC(Coordinated Universal Time 国际协调时间)为准:PST为UTC-8,即比UTC慢8个小时;
PDT
PDT 是 Pacific Daylight Time 的缩写,译为中文为"太平洋夏令时间",比 UTC 时间晚 7 小时。
其实除了 PDT 时间,北美地区还有很多时间:
美国夏季始于每年4月的第1个周日,止于每年10月的最后一个周日。夏令时比正常时间早一小时,与PDT时间相对应的是PST , Pacific
Standard Time 。 夏时制结束后就是PST