處理日期時間,將方便您對日志后續查詢與可視化展示。本文檔主要介紹使用函數進行日期時間數據類型轉換和日期時間偏移。
概念解釋
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
本身,整體上向前或向后偏離一周。