Oracle 时区
Table of Contents
1 简介
由于地球经纬度及地球自转引起的经度方向,不同的经度的地方,所感受到的昼夜是不同 的。有关国际会议决定将地球表面按经线从东到西,每隔经度15度划分一个时区,并且规定 相邻区域的时间相差1小时。
这就是时区的由来。
而实际使用中,往往不是严格按照这个标准来做的。国家的存在,为了行政工作的方便,一 个国家都有一个本国的标准时,大部分国家以首都所在的时区作为国家的标准时。比如, 我大中国以北京所在时区(东八区)作为中国的标准时。在IT领域,很多时候我们都会涉及 到时区的问题。很不幸的是,很多计算机方面的标准都是西欧、北美这些发达国家定制 的.比如东八区的时区名,并不是Beijing,而是Shanghai,当然,完整的时区名应该是 "Asia/Shanghai".
1884年在华盛顿召开的国际经度会议决定以经过格林尼治的经线为本初子午线,是世界计 算时间和地理经度的起点,也是世界标准时,又称其为格林尼治标准时, 其时区名为 UT. 而由于世界原子时(纳秒为基础)与世界时(毫秒为基础)的计算单位不同,两者之间的差别会 越来越大,各政府更倾向于以自然时间UT为标准,因此世界原子时需要向世界时靠拢,于 1972年,世界上达成一致解决方案即为:协调世界时,即UTC。随后UTC,即成为了各个领 域特别是IT行业的时间标准。
而UTC的由来,不过是国力强弱之争妥协的产物。英文(CUT)和法文(TUC)的缩写不同, 作为妥协,简称UTC。
很多同仁在工作时,不会特别关注时区问题,即使用默认的时间配置,而在处理实际数据 的时候才发现,操作时间或者系统显示时间与本地时间相差了几个小时,在我大中国,一 般就是相差8个小时。只要你遇到了反馈时间与实际时间相差8个小时的情况,你就往时区 方面去考虑,这个方向基本上是正确的。
2 Oracle TimeZone
2.1 时区文件
Oracle 将支持的时区信息,比如时区名,时区缩写名都保存在文件中。文件的默认存储 路径为$ORACLE_HOME/oracore/zoneinfo/ 及其子路径中(big和little). 这些路径中中的 同名文件,其实是一样的。都是二进制文件,但是从文件大小来看,可以判断,同名文件 虽然在不同的路径中,但是文件内容是一样的。
文件的内容,在数据库启动时,会自动加载,并呈现在视图"V$TIMEZONE_FILE" 中,告知我 们, 数据库现在使用的是哪个文件。
文件分为两种类型:timezlrg__version.dat和timezone__version.dat .
2.2 时区名字
关于Oracle支持的时区,基本上涵盖了已知的常用的时区。
数据库启动时通过文件加载的内容,呈现在视图:V$TIMEZONE_NAMES 中。
SQL> col tzname for a20 SQL> col tzabbrev for a10 SQL> select * from V$TIMEZONE_NAMES where tzname = ‘Asia/Shanghai‘; TZNAME TZABBREV -------------------- ---------- Asia/Shanghai LMT Asia/Shanghai CST Asia/Shanghai CDT
可以看到查到了三个值,
- LMT(Local Mean Time)
- 全球标准时间,UTC的前身, 这个基本不用了。
- CST(China Standard Time)
- 中国标准时间, 有其他的解释
- CDT(Central Daylight Time)
- 中部夏令时间,主要用于北美,比UTC晚5小时。另外,还可以理解成(Cuba Daylight Time)古巴夏令时。
更多的时区查询可以去:https://datetime360.com/cn/worldwide-city-list/ 查询。
由于缩写中有很多同名的,为了避免冲突,我们一般使用全名。
2.3 查询数据库或者会话时区
-
会话
select sessiontimezone from dual; SESSIONTIMEZONE --------------------------------------------------------------------------- +08:00
-
数据库
select dbtimezone from dual; DBTIME ------ +00:00 SELECT property_name, property_value FROM database_properties WHERE property_name=‘DBTIMEZONE‘; SELECT name, value$ FROM sys.props$ WHERE name=‘DBTIMEZONE‘;
2.4 调整时区
- 会话级别
-
SQL 命令
ALTER SESSION SET TIME_ZONE = local; ALTER SESSION SET TIME_ZONE = dbtimezone; ALTER SESSION SET TIME_ZONE = ‘+08:00‘; ALTER SESSION SET TIME_ZONE = ‘Asia/Shanghai‘;
-
环境变量
$ ORA_SDTZ=‘-05:00‘ $ export ORA_SDTZ
-
-
数据库级别 需要重启
ALTER DATABASE SET TIME_ZONE = ‘-05:00‘; ALTER DATABASE SET TIME_ZONE = ‘Europe/Lisbon‘;
-
创建数据库时指定时区
CREATE DATABASE ... SET TIME_ZONE=‘Asia/Shanghai‘;
2.5 查询在指定时区的当地时间
SELECT TZ_OFFSET(‘Europe/London‘) FROM DUAL;