一般来说,时序数据就是带有时间序列属性的数据。在处理时序数据时,TDengine有着自己独特的方式。但是如果没有正确理解TDengine在写入和查询上的行为,极可能会因为配置了错误的时区(timezone),而导致写入和查询的时间出现错位。
如:用户执行的一条SQL写入了“2021-07-23 07:04:00.000"这个时刻的数据,可是在不同的客户端中,查询出的结果却相差了8个小时。
本文将日期时间、时间戳以及TDengine在写入和查询时处理时区的行为等描述清楚,并给出如何设置timezone参数的意见供参考。
一、 本地日期时间、时区、时间戳
关键词说明:
- 本地日期时间:表示当地的日期时间。12:00是中午吃饭的时间,8:00是早上上班的时间,这是人类习惯的一种表示时间的方式,是不带时区信息的日期和时间,可以当成一个String。例如:2021-07-21 12:00:00.000,表示2021年7月21日正午,时间精度以毫秒记,这个日期时间的表示方法,不带任何时区信息。
- 时区:地理概念,按照UTC/格林威治时区,把地球划分成向东和向西各12个时区,其中东12区和西12区是一个区。时区可以通过’Asia/shanghai’这样的’地区/城市’的方式表示,也可以用UTC偏移的方式表示。例如:UTC+8,代表东八区,当协调世界时(UTC)时间为凌晨2点的时候,当地的时间为2+8点,即早上10点。
- RFC 3339:一种表示日期时间的标准格式。RFC 3339是带时区信息的格式,即包含日期时间信息,也有时区信息。例如,以下两个时间在地球上是同一时刻:
2019-10-12T07:20:50+00:00,这个表示2019年10月12日,上午7点20分50秒(UTC+0时区),
2019-10-12T15:20:50+08:00,这个表示2019年10月12日,下午3点20分50秒(UTC+8时区)。- 时间戳:是机器存储和计算时间的方式。以Unix元年(UTC时区1970年1月1日0点0分0秒)开始经过的秒数计算,不同精度的计时方式,可以有不同的时间戳。例如:0,表示UTC时区1970年1月1日凌晨的时间。
- TDengine中用时间戳表示日期时间,以标准的Unix元年时间(UTC时区1970年1月1日0点0分0秒)为原点,支持毫秒、微秒、纳秒三种精度;
- 在写入时,如果SQL中是本地日期时间格式,TDengine的客户端使用当前生效的timezone配置,将SQL中的日期时间转换为timestamp;同时,也支持使用RFC-3339格式的日期时间进行写入;
- 在shell中查询时,客户端使用当前生效的timezone配置,将TDengine中存储的timestamp转换为日期时间格式进行显示。
二、查看/设置tdengine时区
2.1 查看时区
- 查看tdengine的时区信息,在shell命令下执行命令:
show variables;
2.2 设置时区
-
TDengine 客户端会自动读取当前系统时区,保证 Windows 和 Linux 时区正确即可,无需进行任何配置
。 -
若要配置,如何配置,如下所示:
(1)国内时区为东八区,ISO 8601 标准下表示为 UTC+8,POSIX标准下表示为 UTC-8。
(2)若要配置时区为东八区,在 Windows 下应配置 UTC+8,在 Linux 下应配置为 UTC-8 (这是因为 Windows 和 Linux 的时区标准不同)
在 Windows 下,客户端配置文件目录为 C:\TDengine\cfg\taos.cfg,修改 timezone 属性为 UTC+8
在 Linux 下,客户端配置文件目录为 /etc/taos/taos.cfg,修改 timezone 属性为 UTC-8
- 编辑配置文件:
vi /etc/taos/taos.cfg
根据需要,修改配置文件圈出部分的时区信息。 - 修改保存后,重新启动taos服务,使得修改生效:
systemctl restart taosd
参考链接:一文吃透TDengine上的时区设置
三、使用第三方工具查询时,返回时区不正确的处理
【node-red时区问题解决方案对比】