由于世界各国家与地区所处经度不同,地方时也不同,因此会划分为不同的时区。本文将会为你介绍在Hologres中时区的相关信息。
时区介绍
为了克服时间上的混乱,正式的时区划分包括二十四个时区(东、西各十二个时区),其中英国(格林尼治天文台旧址)为中时区(零时区)、东1~12区(正数,
+
),西1~12区(负数,-
)。每个时区横跨经度十五度,时间正好是一小时。在国际上有两种时区的表达,分别为GMT和UTC。
- GMT 0:00
是指格林尼治标准时间,这是以英国格林尼治天文台观测结果得出的时间,这是英国格林尼治当地时间,这个地方的当地时间过去被当成世界标准时间。
- UTC +00:00
是指协调世界时。因为地球自转越来越慢,每年都会比前一年多出零点几秒,每隔几年协调世界时组织都会给世界时加一秒,让基于原子钟的世界时和基于天文学(人类感知)的格林尼治标准时间相差不至于太大。并将得到的时间称为UTC,这是现在使用的世界标准时间。
说明
- 协调世界时不与任何地区位置相关,也不代表此刻某地的时间,所以在说明某地时间时要加上时区也就是说GMT并不等于UTC,而是等于
UTC+0
,即GMT = UTC+0
,只是格林尼治刚好在零时区上。 +08
是指时区为东八区,比零时区快八个小时。
Hologres兼容PostgreSQL协议。PostgreSQL遵循POSIX时区规范,在使用GMT、UTC表达时区时,其偏移量符号与上述符号相反,即负号表示东时区。在Hologres中所有日期和时间都用全球统一时间UTC格式存储,所有Region默认是
UTC-08
(中国东八区时间),比世界协调时间(UTC)和格林尼治时间(GMT)快八小时的时区。同时Hologres提供两种存储时间戳的数据类型:不带时区的TIMESTAMP和带时区的TIMESTAMPTZ。
说明 带有时区的数据建议都使用TIMESTAMPTZ类型存储。
名称 | 说明 | 精度 | 数据显示示例 |
---|---|---|---|
TIMESTAMP | 格式为日期+时间 ,不带时区信息。
存储的数据与写入的数据一样,当修改了客户端的时区时,里面存储的数据的值不会改变,即客户端展示的是写入的原始数据,没有时区偏移。 |
微秒 | 2022-01-01 01:01:01.123456 |
TIMESTAMP WITH TIME ZONE(TIMESTAMPTZ) | 格式为日期+时间 ,带时区信息。
Hologres使用UTC时区的值来存储TIMESTAMPTZ 数据。在向TIMESTAMPTZ字段插入值的时候, Hologres会自动将客户端时区的值转换成UTC时区,在展示查询结果的时候,根据客户端TimeZone配置参数声明的时区转换为客户端时间。 |
毫秒 | 2022-02-01 10:33:20.125+08 |
查看默认的时区
通过以下命令语句查看当前客户端的时区。
说明
- 在Holoweb中执行的结果为实例的默认时区(PRC),对应
UTC-08
(东八区)。 - 如果使用其他开发工具,查询结果不是默认时区,则说明更改过客户端时区配置。
show timezone;
修改客户端时区
- 系统表
在Postgres中通过系统表pg_timezone_names存储不同地区的默认时区信息,可以通过如下命令查询系统表查看每个地区对应的时区。
系统表参数说明如下。select * from pg_timezone_names;
参数 类型 描述 name text 时区名称。 abbrev text 时区缩写。 utc_offset interval UTC偏移时区,正数(+)表示格林威治以西,负数(-)表示格林威治以东。 is_dst boolean 如果当前正在观察夏令时,则为真(t),否则为否(f)。 - 完整的时区名称(name):例如America/New_York。
- UTC时区的偏移(utc_offset):例如06:00:00,其中正数(+)表示格林威治以西,负数(-)表示格林威治以东。
说明 除以上几种形式外,不支持用UTC+8
或者GMT+8
这种格式指定时区。地域 时区 完整时区名 UTC时区的偏移 - 中国
- 新加坡
- 马来西亚(吉隆坡)
东八区 - PRC
- Asia/Shanghai
- Asia/Singapore
- Asia/Kuala_Lumpur
UTC-08 日本(东京) 东九区 Asia/Tokyo UTC-09 印度尼西亚(雅加达) 东七区 Asia/Jakarta UTC-07 印度(孟买) 东五区 - Asia/Calcutta
- Asia/Kolkata
UTC-05:30 德国(法兰克福) 东一区 Europe/Berlin UTC-01 美国(硅谷) 西五区 - US/Eastern
- America/New_York
UTC+05 美国(弗吉尼亚) 西八区 - US/Pacific
- America/Los_Angeles
UTC+08 - 修改客户端时区
Hologres的时区默认按照UTC存储,所有Region默认为
UTC-08
(中国东八区)。可以通过修改客户端时区参数达到客户端显示不同时区的目的。通过以下命令进行修改客户端显示时区。说明- 修改时区是修改客户端展示时区,并不是修改底层存储的真实时区信息。
- HoloWeb的时区显示默认都是
UTC-08
。
- Session级别
通过set命令可以在Session级别设置GUC参数。Session级别的参数只在当前Session生效,当连接断开之后将会失效,建议加在SQL前一起执行,使用方法如下。
--修改为加拿大/东部时区 set timezone ='Canada/Eastern'; --修改为东五区 set timezone ='05:00:00';
- 数据库级别
可以通过
alter database <db_name> set <value>;
命令来DB级别设置GUC参数。说明 此命令执行完成后:- 在整个数据库级别生效,设置完成后当前连接需要重新断开连接才能生效。
- 新建数据库不会生效,需要重新手动设置。
--DB级别修改时区为'UTC'零时区 alter database <db_name> set timezone = 'UTC-0'; --DB级别修改时区为'UTC'西五时区 alter database <db_name> set timezone = 'UTC+05';
不同数据源与Hologres的时间类型映射
不同数据源与Hologres有关时间的数据类型映射如下表,建议按照推荐映射关系进行映射,否则会出现数据不一致/时区偏差的情况。
数据源 | 数据源数据类型 | 源数据示例 | Hologres数据类型 | 映射Hologres数据示例 | 说明 |
---|---|---|---|---|---|
MySQL | DATETIME | 2001-07-14 02:14:19 | TIMESTAMP | 2001-07-14 02:14:19 | MySQL的DATETIME存储的是没有时区的时间(可以理解为字符串的时间格式),取值范围为'1000-01-01 00:00:00' to '9999-12-31 23:59:59' 。
数据存储时,会按照原始的时间格式存储,不进行任何转换,因此在Hologres中映射为TIMESTAMP类型。 |
TIMESTAMP | 2019-02-23 05:21:16 | TIMESTAMPTZ | 2019-02-23 05:21:16+08 | MySQL的TIMESTAMP默认是UTC时间,带时区,取值范围为'1970-01-01 00:00:01' UTC to ‘2038-01-19 03:14:07' UTC 。
数据存储前会根据数据库软件设置的时区(默认随系统),将写入的时间数据转化为UTC时间后,再进行存储。因此在Hologres映射为TIMESTAMPTZ类型。 |
|
MaxCompute | DATETIME | 2021-11-29 00:01:00 | TIMESTAMPTZ | 2021-11-29 00:01:00.000+08 | MaxCompute的DATETIME默认是UTC时间,取值范围为‘0000-1-1’ to ‘9999-12-31’ ,精确到毫秒 。因此在Hologres中映射为TIMESTAMPTZ类型。
|
TIMESTAMP | 2021-01-11 00:00:00.123456789 | TIMESTAMPTZ | 2021-01-11 00:00:00.123+08 | MaxCompute的TIMESTAMP默认是UTC时间,取值范围为'0000-01-01 00:00:00.000000000' to '9999-12-31 23.59:59.999999999' ,精确到纳秒。因此在Hologres中映射为TIMESTAMPTZ类型。
说明 说明:Hologres底层会将纳秒转换为毫秒,无需关心精度问题。
|
|
Flink | TIMESTAMP | 2007-04-30 13:10:02.047 | TIMESTAMPTZ | 2007-04-30 13:10:02.047+08 | Flink的TIMESTAMP类型默认是UTC时间,精确到毫秒,因此在Hologres中映射为TIMESTAMPTZ类型。 |
DataHub | TIMESTAMP | 2020-03-05 10:10:00.123456+08 | TIMESTAMPTZ | 2020-03-05 10:10:00.123+08 | DataHub的TIMESTAMP精确到微秒,使用UTC时间,Hologres Connecotr在写入过程中会自动将数据时区变为零时区,因此在Hologres中映射为TIMESTAMPTZ类型。 |
常见问题
- DataHub实时同步数据至Hologres,Hologres的字段类型为TIMESTAMP,DataHub字段类型为TIMESTAMP,写入后Hologres中时间比实际少八个小时。
- 可能原因:Hologres Connecotr在写入过程中,会自动将数据时区变为零时区。如果Hologres字段设置为TIMESTAMP,不会带时区,写入后还是零时区,因此会少八个小时。
- 解决方法:重新建表,将Hologres中的字段改成TIMESTAMPTZ。
- DataHub实时同步数据至Hologres,Hologres的字段类型为TIMESTAMPTZ,Tableau展示的时候与Hologres的时间差八个小时。
- 可能原因:Tableau前端时区展示问题。
- 解决方法:HoloWeb的时区默认为UTC+08(东八区),可以通过HoloWeb查看是否符合真实数据,然后在Tableau建立连接的时候,可以在Initial SQL(初始 SQL)里修改时区,命令示例如下。
--修改为按照东八区显示 set timezone to 'Asia/Shanghai';
- MySQL数据同步到Hologres后时间显示为什么会出现
+08
?- 可能原因:
+08
代表的是当前客户端展示的是东八区时区,并不是数据是东八区。 - 解决方法:通过修改客户端时区为指定的时区。
- 可能原因:
- JDBC里面如何设置时区?
JDBC的时区显示默认同JVM时区,如果需要修改JDBC的时区显示,需要连接JDBC后,执行以下SQL进行修改。
-- 修改为东七区 set timezone = '+07';