六月婷婷AV,国产偷窥猎奇福利二区,日韩三级片。,好吊色网站,日韩成人中文在线视频,国产亚洲午夜啪啪,亚洲欧美另类国产精品,国产成人av1,任你艹在线观看

一文吃透 TDengine 上的時區(qū)設(shè)置

小 T 導(dǎo)讀:很多新用戶在配置TDengine的時候,偶爾會因為配置了錯誤的時區(qū)(timezone),而導(dǎo)致寫入和查詢的時間出現(xiàn)錯位。今天希望這篇文章,能將日期時間、時間戳以及TDengine在寫入和查詢時處理時區(qū)的行為等描述清楚。

TDengine是濤思數(shù)據(jù)專為物聯(lián)網(wǎng)、車聯(lián)網(wǎng)、工業(yè)互聯(lián)網(wǎng)、IT運維等設(shè)計和優(yōu)化的大數(shù)據(jù)平臺,核心的時序數(shù)據(jù)庫在處理時序數(shù)據(jù)上有著十分優(yōu)異的性能。

一般來說,時序數(shù)據(jù)就是帶有時間序列屬性的數(shù)據(jù)。在處理時序數(shù)據(jù)時,TDengine有著自己獨特的方式。但是如果你沒有正確理解TDengine在寫入和查詢上的行為,極可能會因為配置了錯誤的時區(qū)(timezone),而導(dǎo)致寫入和查詢的時間出現(xiàn)錯位。

下面是一個真實用戶的例子:

一文吃透 TDengine 上的時區(qū)設(shè)置 - TDengine Database 時序數(shù)據(jù)庫

從上圖中可以看到,用戶執(zhí)行的一條SQL寫入了“2021-07-23 07:04:00.000″這個時刻的數(shù)據(jù),可是在不同的客戶端中,查詢出的結(jié)果卻相差了13個小時。

今天希望通過這篇文章,將日期時間、時間戳以及TDengine在寫入和查詢時處理時區(qū)的行為等描述清楚,并給出如何設(shè)置timezone參數(shù)的意見,供大家參考。

在開始之前,你需要先了解以下這三點

1. TDengine中用時間戳表示日期時間,以標準的Unix元年時間(UTC時區(qū)1970年1月1日0點0分0秒)為原點,支持毫秒、微秒、納秒三種精度;

2. 在寫入時,如果SQL中是本地日期時間格式,TDengine的客戶端使用當前生效的timezone配置,將SQL中的日期時間轉(zhuǎn)換為timestamp;同時,也支持使用RFC-3339格式的日期時間進行寫入;

3. 在shell中查詢時,客戶端使用當前生效的timezone配置,將TDengine中存儲的timestamp轉(zhuǎn)換為日期時間格式進行顯示。

本文所用相關(guān)概念

  • 本地日期時間:表示當?shù)氐娜掌跁r間。12:00是中午吃飯的時間,8:00是早上上班的時間,這是人類習(xí)慣的一種表示時間的方式,是不帶時區(qū)信息的日期和時間,可以當成一個String。例如:2021-07-21 12:00:00.000,表示2021年7月21日正午,時間精度以毫秒記,這個日期時間的表示方法,不帶任何時區(qū)信息。
  • 時區(qū):地理概念,按照UTC/格林威治時區(qū),把地球劃分成向東和向西各12個時區(qū),其中東12區(qū)和西12區(qū)是一個區(qū)。時區(qū)可以通過’Asia/shanghai’這樣的’地區(qū)/城市’的方式表示,也可以用UTC偏移的方式表示。例如:UTC+8,代表東八區(qū),當協(xié)調(diào)世界時(UTC)時間為凌晨2點的時候,當?shù)氐臅r間為2+8點,即早上10點。
  • RFC 3339:一種表示日期時間的標準格式。RFC 3339是帶時區(qū)信息的格式,即包含日期時間信息,也有時區(qū)信息。例如,以下兩個時間在地球上是同一時刻:2019-10-12T07:20:50+00:00,這個表示2019年10月12日,上午7點20分50秒(UTC+0時區(qū)),2019-10-12T15:20:50+08:00,這個表示2019年10月12日,下午3點20分50秒(UTC+8時區(qū))。
  • 時間戳:是機器存儲和計算時間的方式。以Unix元年(UTC時區(qū)1970年1月1日0點0分0秒)開始經(jīng)過的秒數(shù)計算,不同精度的計時方式,可以有不同的時間戳。例如:0,表示UTC時區(qū)1970年1月1日凌晨的時間。

本地日期時間、時區(qū)信息、時間戳的關(guān)系可以參考下面這張圖:

一文吃透 TDengine 上的時區(qū)設(shè)置 - TDengine Database 時序數(shù)據(jù)庫

TDengine如何處理日期時間?

寫入

如果在insert語句中,用一個String表示日期時間,插入到TDengine,存在著將這個String解析成timestamp的過程。這個String存在不同的格式,合法的格式包括:

(1)RFC 3339標準的表示方式

(2)yyyy-MM-dd hh:mm:ss

第1種情況——采用RFC 3339標準,那么這個String是帶時區(qū)信息的,可以明確地將其轉(zhuǎn)換成timestamp。例如:

這里,介紹一個小技巧:使用-r參數(shù)啟動taos shell時,timestamp類型的數(shù)據(jù),將會以時間戳(long值)的形式顯示。

# taos -r 
taos> drop table test.weather;
Query OK, 0 of 0 row(s) in database (0.004202s) 

taos> create table test.weather(ts timestamp, f1 float) ;
Query OK, 0 of 0 row(s) in database (0.012690s) 

taos> insert into test.weather values('1970-01-01T08:00:00.000+08:00',22.00) ;
Query OK, 1 of 1 row(s) in database (0.002363s) 

taos> select * from test.weather;
       ts       |     f1      |
========================================
              0        |     22.00000 |
Query OK, 1 row(s) in set (0.001476s)

可以看到,1970-01-01T08:00:00.000+08:00,代表UTC+8時區(qū)1970年1月1日上午8:00,這正好對應(yīng)UTC時區(qū)的凌晨,所以在timestamp是0。

第2種情況——在insert語句中使用yyyy-MM-dd hh:mm:ss格式的時間字符串,不含時區(qū)信息。這時,taos客戶端會采用當前timezone信息,將字符串轉(zhuǎn)化成timestamp。例如:

可以看到,1970-01-01T08:00:00.000+08:00,代表UTC+8時區(qū)1970年1月1日上午8:00,這正好對應(yīng)UTC時區(qū)的凌晨,所以在timestamp是0。

第2種情況——在insert語句中使用yyyy-MM-dd hh:mm:ss格式的時間字符串,不含時區(qū)信息。這時,taos客戶端會采用當前timezone信息,將字符串轉(zhuǎn)化成timestamp。例如:

taos> show variables;
           name           |             value              |
============================================================
timezone                 |  (CST, +0800)                  |  

taos> insert into test.weather(ts, f1) values('1970-01-01 00:00:00.000', 22.00);
Query OK, 1 of 1 row(s) in database (0.001290s) 

taos> select * from test.weather;
       ts       |          f1          |
========================================
 -28800000 |             22.00000 |
Query OK, 1 row(s) in set (0.002220s)

可以看到,insert語句使用了配置文件中的時區(qū)信息,和insert語句中的日期時間信息,即“1970-01-01 00:00:00+08:00”,這個值在時間戳中正好代表-28800000。

由此可見,在TDengine中,時間原點是國際通用的Unix元年(UTC時區(qū)1970年1月1日凌晨)。

查詢

# 在taos.cfg內(nèi)配置timezone
# cat /etc/taos/taos.cfg | grep timezonetimezone    UTC+0 

# 在shell中查詢timezonetaos
> show variables;
           name           |             value              |
============================================================
timezone                 |  (CST, +0800)                  | 

# taos -s "select * from test.weather" -r
Welcome to the TDengine shell from Linux, Client Version:2.0.20.11
Copyright (c) 2020 by TAOS Data, Inc. All rights reserved.
taos> select * from test.weather
       ts       |          f1          |
========================================
            -28800000 |             22.00000 |
Query OK, 1 row(s) in set (0.002564s) 

# taos -s "select * from test.weather"
Welcome to the TDengine shell from Linux, Client Version:2.0.20.11
Copyright (c) 2020 by TAOS Data, Inc. All rights reserved.
taos> select * from test.weather;
           ts            |          f1        |
================================================= 
1969-12-31 16:00:00.000 |             22.00000 |
Query OK, 1 row(s) in set (0.002306s)

可以看到,select語句在查詢時,依然存在著從ts轉(zhuǎn)換為一個string串的情況,Tdengine會將ts轉(zhuǎn)換成當前taos client中的時區(qū)。

Timezone配置為UTC-8

有些用戶不理解,為什么在TDengine中timezone會被配置為UTC-8?原因是,在POSIX標準中,表示時區(qū)偏移量的方式和地理的表示方式不一致。參考Wikipedia中的定義,在ISO 8601中,UTC+8為東八區(qū),該時區(qū)是以中文為主的時區(qū)。那在Unix中,東八區(qū)又應(yīng)該如何表示?請參考下面這個例子:

# date --help
用法:date [選項]... [+格式] 
或:date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
Display the current time in the given FORMAT, or set the system date.%z +hhmm        
數(shù)字時區(qū)(例如,-0400)%:z +hh:mm      
數(shù)字時區(qū)(例如,-04:00)%Z              
按字母表排序的時區(qū)縮寫 (例如,EDT)
Examples:Show the time on the west coast of the US (use tzselect(1) to find TZ)  
$ TZ='America/Los_Angeles' date 

# 使用TZ='UTC-8'查看當前時間
# TZ='UTC-8' date +'%Y-%m-%d %H:%M:%S %Z %z'
2021-08-01 22:31:29 UTC +0800 

# 使用TZ='UTC'查看當前時間
# TZ='UTC' date +'%Y-%m-%d %H:%M:%S %Z %z'
2021-08-01 14:31:51 UTC +0000 

# 使用TZ='UTC+8'查看當前時間
# TZ='UTC+8' date +'%Y-%m-%d %H:%M:%S %Z %z'
2021-08-01 06:32:06 UTC -0800

可見,在POSIX標準中,UTC-8代表東八區(qū),UTC+8代表西八區(qū)。這里與地理上表示時區(qū)的習(xí)慣是不一致的。在taos.cfg中,TDengine使用的是POSIX Timezone標準。

在JDBC中設(shè)置Timezone

在使用JDBC Connector連接TDengine時,可以通過3個途徑設(shè)置timezone參數(shù),分別為:url、properties和taos.cfg配置文件。

// url
Connection conn = DriverManager.getConnection("jdbc:TAOS://taosdemo.com:6030/test?timezone=UTC-8", "root", "taosdata"); 

// properties
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");

// 當url和properties中都沒有制定timezone的情況下,會使用本地配置文件taos.cfg中timezone的配置參數(shù)
Connection conn = DriverManager.getConnection("jdbc:TAOS://taosdemo.com:6030/test", connProps); 

參考文檔: https://tdengine.com/docs/cn/v2.0/connector/java

總結(jié)

最后,我們再回顧一下前文中描述的用戶問題:“為什么在不同的客戶端中,日期時間會相差13個小時?”執(zhí)行的insert語句SQL為:

INSERT INTO n802344030600001_w21003 USING mnt_factor_item_data TAGS ("N802344030600001", 'w21003') VALUES ('2021-7-23 07:04:00:000',3, 999,'N802344030600002','w21003',19,'COD','mg/L',4,2,'大空港片區(qū)',1,'龍翔北路監(jiān)測控制站',1,'龍翔北路水監(jiān)測設(shè)備',3,'龍翔北路監(jiān)測終端');

SQL中是以本地日期時間的格式表示時間戳的,客戶端使用了本地的timezone,將這個“2021-7-23 07:04:00:000”轉(zhuǎn)換為timestamp;在查詢時,Windows上的shell和Linux的shell都會將timestamp,根據(jù)當前生效的timezone,轉(zhuǎn)換成日期時間格式。

參考文獻

1. 為什么用UTC+8變成了美國時區(qū)?

2. 理解RFC 3339標準

3. RFC 3339標準

4. UTC+8時區(qū)的定義