文档

时区

更新时间:

由于世界各国家与地区所处经度不同,地方时也不同,因此会划分为不同的时区。本文将会为你介绍在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)。

    通过如上的系统表,在Hologres中允许使用以下几种形式指定时区。

    • 完整的时区名称(name):例如America/New_York。

    • UTC时区的偏移(utc_offset):例如06:00:00,其中正数(+)表示格林威治以西,负数(-)表示格林威治以东。

    说明

    除以上几种形式外,不支持用UTC+8或者GMT+8这种格式指定时区。

    Hologres中的常用时区及其对应参数值如下所示。

    地域

    时区

    完整时区名

    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 Connecotor在写入过程中会自动将数据时区变为零时区,因此在Hologres中映射为TIMESTAMPTZ类型。

常见问题

  • DataHub实时同步数据至Hologres,Hologres的字段类型为TIMESTAMP,DataHub字段类型为TIMESTAMP,写入后Hologres中时间比实际少八个小时。

    • 可能原因:Hologres Connecotor在写入过程中,会自动将数据时区变为零时区。如果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';
  • 本页导读 (1)
文档反馈