處理日期時間,將方便您對日誌後續查詢與可視化展示。本文檔主要介紹使用函數進行日期時間資料類型轉換和日期時間位移。
概念解釋
SLS DSL文法中的日期時間處理主要涉及三種資料類型:日期時間字串、日期時間對象和Unix時間戳記。
日期時間字串
日期時間字串的主要用途是為了便於展示以及提升使用者可讀性。SLS DSL文法中的日期時間字串主要分為兩種形式:
帶有時區資訊的日期時間字串,如
2019-06-02 18:41:26+08:00
。不帶時區資訊的日期時間字串,如
2019-06-02 10:41:26
。
帶有時區資訊的日期時間字串通過在日期時間後添加額外的時差資訊來表達時區:
2019-06-02 18:41:26+08:00
表示該時間是東8區
時區下的2019-06-02 18:41:26
。2019-06-02 18:41:26-07:00
表示該時間是西7區
時區下的2019-06-02 18:41:26
。
日期時間對象
執行個體化的日期時間,專指Datetime類型的資料。日期時間對象的主要用途是為了便於展示以及提升使用者可讀性。
Unix時間戳記
從1970年1月1日(UTC/GMT的午夜)開始所經過的秒數。Unix時間戳記的主要應用情境有:
表示系統時間。
日誌事件中表示日誌產生時間的元欄位
__time__
,表示日誌接收時間的欄位__receive_time__
等,這些欄位的值都使用Unix時間戳記來表示對應的系統時間,如下例所示。__source__: 192.0.2.1 __tag__:__receive_time__: 1562741899 __topic__: __time__: 1562731122
時間相關的計算。
Unix時間戳記是從1970年1月1日開始所經過的秒數,因此在很多情境下便於直接進行日期時間相關的計算,例如如下樣本。
原始日誌
time1: 1562741899 time2: 1562731122
SLS DSL編排
e_set("time_diff", op_sub(v("time1"), v("time2")))
加工結果
time1: 1562741899 time2: 1562731122 time_diff: 10777
資料類型轉換和轉換函式
日期時間字串、日期時間對象和Unix時間戳記的相互轉換方式和對應轉換函式如下圖所示。 上圖所示的轉換情境和對應的轉換函式具體描述如下表所示。
轉換情境 | 轉換函式 | |
日期時間對象和Unix時間戳記的相互轉換 | 日期時間對象轉為Unix時間戳記 |
|
Unix時間戳記轉為日期時間對象 |
| |
日期時間對象和日期時間字串的相互轉換。 | 日期時間對象轉為日期時間字串。 |
|
日期時間字串轉為日期時間對象。 |
| |
日期時間字串和Unix時間戳記的相互轉換。 | 日期時間字串轉為Unix時間戳記。 |
|
Unix時間戳記轉為日期時間字串。 |
|
上圖和上表揭示了三種資料類型之間的六種轉換,轉換過程涉及兩種方式,一種使用智能轉換函式,另一種使用該轉換的專用函數。
智能轉換函式
以
dt_parse
函數為代表的智能轉換函式可以接收Unix時間戳記、日期時間對象以及日期時間字串等不同類型的參數,實現智能轉換。專用函數
智能轉換函式無法滿足使用者的全部需求。如對於使用者自訂的特殊日期格式,
dt_parse
等智能轉換函式無法自動解析日誌,需要使用dt_strptime
函數來進行解析指定格式。
日期時間對象和Unix時間戳記的相互轉換
處理函數
推薦
dt_parsetimestamp
智能轉換函式,將日期時間對象或日期時間字串轉換為Unix時間戳記。e_set
函數中的tz參數設定會將不帶時區的日期時間對象處理為帶時區的,或將原時區的轉換為目標時區。
Unix時間戳記轉換成帶時區的時間字串對象。
原始日誌
time: 1562741899
SLS DSL編排
e_set("new_time", dt_parse(v("time"), tz="Asia/Shanghai"))
加工結果
time: 1562741899 new_time: 2019-07-10 06:58:19+08:00
日期時間字串和Unix時間戳記的相互轉換
處理函數
dt_str
智能轉換函式,可以將Unix時間戳記、日期時間對象和日期時間字串轉化為指定格式的日期時間字串。dt_strftimestamp
函數只支援將Unix時間戳記轉化為日期時間字串。dt_parsetimestamp
智能轉換函式,可以將日期時間字串或日期時間對象轉換為Unix時間戳記。
情境1:不帶時區資訊的日期時間字串類型轉換為Unix時間戳記。
對於不帶時區資訊的日期時間字串如
2019-06-02 18:41:26
,將日期時間轉化為Unix時間戳記,需要指定該日期時間的時區,不同的時區轉化得到的Unix時間戳記的值不一樣。原始日誌
time: 2019-06-02 18:41:26
SLS DSL編排
e_set("Shanghai_timestamp", dt_parsetimestamp(v("time"), tz="Asia/Shanghai")) e_set("Los_Angeles_timestamp", dt_parsetimestamp(v("time"), tz="America/Los_Angeles")) e_set("UTC_timestamp", dt_parsetimestamp(v("time")))
加工結果
Shanghai_timestamp: 1559472086 Los_Angeles_timestamp: 1559526086 UTC_timestamp: 1559500886 time: 2019-06-02 18:41:26
說明tz="Asia/Shanghai"
表示time
欄位表示的時間是上海所在時區對應的時間。如果不指定時區,預設將給定日期時間當做UTC時區下的日期時間。
時區參數
tz=時區字串
中所有可選時區字串請參見時區列表
情境2:帶有時區資訊的日期時間字串轉換為Unix時間戳記。
對帶時區資訊的日期時間字串如
2019-06-02 18:41:26+08:00
,則無須指定時區參數。原始日誌
China_time : 2019-06-02 18:41:26+08:00 America_time: 2019-06-02 3:41:26-07:00 UTC_time : 2019-06-02 10:41:26+00:00
SLS DSL編排
e_set("timestamp1", dt_parsetimestamp(v("China_time"))) e_set("timestamp2", dt_parsetimestamp(v("America_time"))) e_set("timestamp3", dt_parsetimestamp(v("UTC_time")))
加工結果
America_time:2019-06-02 3:41:26-07:00 China_time:2019-06-02 18:41:26+08:00 UTC_time:2019-06-02 10:41:26+00:00 timestamp1: 1559472086 timestamp2: 1559472086 timestamp3: 1559472086
子情境3:自訂的不帶時區的特殊日期格式轉換成Unix時間戳記。
原始日誌
time1: 2019-07-10 06:58:19 time2: 2019/07/10 06-58-19
SLS DSL編排
e_set("time3", dt_parsetimestamp(v("time1"))) e_set("time4", dt_parsetimestamp(dt_strptime(v("time2"), "%Y/%m/%d %H-%M-%S")))
加工結果
time1: 2019-07-10 06:58:19 time2: 2019/07/10 06-58-19 time3: 1562741899 time4: 1562741899
日期時間對象和日期時間字串的相互轉換
處理函數
dt_parse
智能轉換函式可以將日期時間字串或Unix時間戳記轉換為日期時間對象。dt_astimezone
函數返回一個帶新時區資訊的日期時間對象。
情境1:不帶時區資訊的日期時間字串轉換成指定時區的日期時間對象。
對於不帶時區資訊的日期時間字串
2019-06-02 18:41:26
,可以通過Unix時間戳記,實現不同時區下的日期時間的相互轉換。將洛杉磯時區的日期時間轉換為上海時區的日期時間,如下例所示。原始日誌
#已知time欄位的值的時間是洛杉磯時間 time : 2019-06-04 2:41:26
SLS DSL編排
e_set("timestamp", dt_parsetimestamp(v("time"), tz="America/Los_Angeles")) e_set("Shanghai_time", dt_parse(v("timestamp"), tz="Asia/Shanghai"))
加工結果
Shanghai_time : 2019-06-04 17:41:26+08:00 time : 2019-06-04 2:41:26 timestamp:1559641286
情境2:不帶時區的日期時間字串轉換成帶時區的日期時間對象。
原始日誌
time : 2019-07-10 06:58:19
SLS DSL編排
e_set("new_time", dt_parse(v("time"), tz="Asia/Shanghai"))
加工結果
time: 2019-07-10 06:58:19 new_time: 2019-07-10 06:58:19+08:00
情境3:帶時區的日期時間字串轉換為目標時區的日期時間對象。
原始日誌
time : 2019-06-04 2:41:26+08:00
SLS DSL編排
e_set("new_time", dt_astimezone(v("time"), tz="America/Los_Angeles"))
加工結果
new_time : 2019-06-03 11:41:26-07:00 time : 2019-06-04 2:41:26+08:00
日期時間位移
處理函數
dt_add
函數的參數如下:dt_add(欄位名, dt1=None, dt2=None, year(s)=None, month(s)=None, day(s)=None, hour(s)=None, minute(s)=None, second(s)=None, microsecond(s)=None, weeks(s)=None, weekday=None)
year(s)
、month(s)
、day(s)
等參數的後面都帶有s,表示這些參數可以有兩種形式,即year
和years
,month
和months
等。以year
和years
為例,如果參數傳遞的是year
,表示在年份粒度上覆蓋為year
參數的值;如果傳遞的是years
,表示在年份粒度上增加years
參數的值。同時要一起組合使用的dt_add
函數支援在特定時間粒紋上修改(增加、減少、覆蓋)日期時間的值。dt_add
中weekday
參數通常和dt_MO
、dt_TU
等參數一起使用,表示特定星期幾的位移,如下例所示。具體請參見dt_MO。
情境1:按年和月進行日期位移。
按年和月進行日期位移如下例所示。
原始日誌
time1 : 2019-06-04 2:41:26
SLS DSL編排1
e_set("time2", dt_add(v("time1"), year=2018))
加工結果1
time1 : 2019-06-04 2:41:26 time2 : 2018-06-04 02:41:26
SLS DSL編排2
e_set("time2", dt_add(v("time1"), years=2018))
加工結果2
time1 : 2019-06-04 2:41:26 time2 : 4037-06-04 02:41:26
情境2:按周進行日期位移。
按周進行日期位移如下例所示:
原始日誌
#2019-06-04是周二 time1 : 2019-06-04 2:41:26
SLS DSL編排
#time1的下一個星期一對應的日期 e_set("nex_Monday", dt_add(v("time1"), weekday=dt_MO(1))) #time1的上一個星期二對應的日期 e_set("previous_Tuesday", dt_add(v("time1"), weekday=dt_TU(op_neg(1)))) #time1的下下一個星期六對應的日期 e_set("nex_next_Saturday", dt_add(v("time1"), weekday=dt_SA(2))) #time1的上上一個星期日對應的日期 e_set("previous_previous_Sunday", dt_add(v("time1"), weekday=dt_SU(op_neg(2))))
加工結果
next_Monday : 2019-06-10 02:41:26 next_next_Saturday : 2019-06-15 02:41:26 previous_Tuesday : 2019-06-04 2:41:26 previous_previous_Sunday : 2019-05-26 02:41:26 time1 : 2019-06-04 2:41:26
說明如果
time1
對應周二,那麼它的上一個周二和下一個周二都會是time1
本身,整體上向前或向後偏離一周。