[英]Convert UTC time to specific time zone in Azure ADX Kusto query
我在 Azure 數據資源管理器中有數百萬條記錄。 每條記錄都有一個與之關聯的時間戳值。 我希望能夠在特定時區轉換此時間戳值。
例如在 SQL 我使用 AT TIME ZONE 將時間戳值從一個區域轉換為另一個 -
Select CONVERT(datetime, timestampvalueColumn) AT TIME ZONE 'UTC' AT TIME ZONE 'US Eastern Standard Time' as 'TimeInEST' from Table;
我不願意使用偏移值,因為它不支持夏令時更改。
如何使用 ADX 中的 Kusto 查詢語言做到這一點?
幸運的是,美國東部時間是一個相對簡單的例子。
下面的代碼適用於 2007 年及以后范圍內的日期。
在美國,夏令時從 3 月的第二個星期日當地時間凌晨 2:00 開始。
在 11 月的第一個星期日,夏令時地區的凌晨 2:00 恢復為標准時間
當美國開始夏令時時,將時鍾提前一小時。 在夏令時結束時,將時鍾撥回一小時。
https://www.timetemperature.com/tzus/daylight_saving_time.shtml
// Sample generation. Not part of the solution
let t = materialize(range i from 1 to 15 step 1 | extend dt_utc = ago(rand()*365d*10));
// Solution Starts here
let et2utc_mar_2nd_sun_2am = (dt_utc:datetime){make_datetime(getyear(dt_utc),3,1,2,0,0) + (7d - dayofweek(make_datetime(getyear(dt_utc),3,1)))%7d + 7d + 5h};
let et2utc_nov_2nd_sun_2am = (dt_utc:datetime){make_datetime(getyear(dt_utc),11,1,2,0,0) + (7d - dayofweek(make_datetime(getyear(dt_utc),3,1)))%7d + 4h};
let EasternTimeOffset = (dt_utc:datetime){iff(dt_utc between (et2utc_mar_2nd_sun_2am(dt_utc) .. et2utc_nov_2nd_sun_2am(dt_utc)), -4h, -5h)};
t
| extend EasternTimeOffset = EasternTimeOffset(dt_utc)
| extend EasternTime = dt_utc + EasternTimeOffset
一世 | dt_utc | 東部時間偏移 | 東部時間 |
---|---|---|---|
2 | 2013-01-02T09:46:21.2553241Z | -05:00:00 | 2013-01-02T04:46:21.2553241Z |
12 | 2013-04-29T19:53:51.3170521Z | -04:00:00 | 2013-04-29T15:53:51.3170521Z |
1 | 2013-09-03T18:31:31.2211331Z | -04:00:00 | 2013-09-03T14:31:31.2211331Z |
11 | 2013-09-25T13:45:33.3380811Z | -04:00:00 | 2013-09-25T09:45:33.3380811Z |
8 | 2013-10-02T23:44:54.8682621Z | -04:00:00 | 2013-10-02T19:44:54.8682621Z |
15 | 2014-03-30T12:44:47.6381621Z | -04:00:00 | 2014-03-30T08:44:47.6381621Z |
10 | 2015-02-21T15:34:46.8657901Z | -05:00:00 | 2015-02-21T10:34:46.8657901Z |
9 | 2016-06-16T19:44:31.0144371Z | -04:00:00 | 2016-06-16T15:44:31.0144371Z |
3 | 2016-10-21T04:03:51.0185641Z | -04:00:00 | 2016-10-21T00:03:51.0185641Z |
5 | 2017-11-11T01:50:21.6729811Z | -05:00:00 | 2017-11-10T20:50:21.6729811Z |
14 | 2017-12-02T01:02:18.3206731Z | -05:00:00 | 2017-12-01T20:02:18.3206731Z |
7 | 2018-11-06T06:00:52.4156001Z | -05:00:00 | 2018-11-06T01:00:52.4156001Z |
13 | 2019-11-18T14:05:15.4887631Z | -05:00:00 | 2019-11-18T09:05:15.4887631Z |
4 | 2021-02-16T01:02:37.7791421Z | -05:00:00 | 2021-02-15T20:02:37.7791421Z |
6 | 2021-07-28T04:16:18.3716831Z | -04:00:00 | 2021-07-28T00:16:18.3716831Z |
基於Python插件
熊貓相關文檔: tz_localize 、 tz_convert和strftime
// Sample generation. Not part of the solution
let t = materialize(range i from 1 to 15 step 1 | extend dt_utc = bin(ago(rand()*365d*10), 1s));
// Solution Starts here
let p_schema = typeof(*, dt_et:datetime);
let p_arguments = dynamic({"TZ" : "US/Eastern"});
let p_script =
```
iso_fmt = "%Y-%m-%d %H:%M:%S"
result = df
result["dt_et"] = df["dt_utc"].dt.tz_localize("UTC").dt.tz_convert(kargs["TZ"]).dt.strftime(iso_fmt)
```;
t
| evaluate python(p_schema, p_script, p_arguments)
| extend offset = dt_et - dt_utc
一世 | dt_utc | dt_et | 抵消 |
---|---|---|---|
5 | 2013-03-20T02:43:54Z | 2013-03-19T22:43:54Z | -04:00:00 |
11 | 2013-03-20T04:29:50Z | 2013-03-20T00:29:50Z | -04:00:00 |
15 | 2013-05-12T06:03:49Z | 2013-05-12T02:03:49Z | -04:00:00 |
8 | 2014-02-21T22:23:32Z | 2014-02-21T17:23:32Z | -05:00:00 |
13 | 2015-12-26T08:55:41Z | 2015-12-26T03:55:41Z | -05:00:00 |
2 | 2016-06-09T10:53:04Z | 2016-06-09T06:53:04Z | -04:00:00 |
4 | 2016-12-17T21:19:15Z | 2016-12-17T16:19:15Z | -05:00:00 |
10 | 2017-06-23T06:54:48Z | 2017-06-23T02:54:48Z | -04:00:00 |
7 | 2017-07-25T21:12:58Z | 2017-07-25T17:12:58Z | -04:00:00 |
1 | 2019-12-05T16:43:48Z | 2019-12-05T11:43:48Z | -05:00:00 |
3 | 2019-12-18T17:20:17Z | 2019-12-18T12:20:17Z | -05:00:00 |
12 | 2019-12-30T02:51:46Z | 2019-12-29T21:51:46Z | -05:00:00 |
14 | 2021-01-31T08:36:00Z | 2021-01-31T03:36:00Z | -05:00:00 |
6 | 2021-04-25T13:31:14Z | 2021-04-25T09:31:14Z | -04:00:00 |
9 | 2021-07-15T11:20:58Z | 2021-07-15T07:20:58Z | -04:00:00 |
站點http://web.cs.ucla.edu/~eggert/tz/tz-link.htm指向站點https://timezonedb.com/download ,該站點具有https://www.iana.org/ csv 格式的時區站點數據。
它包含所有時區的夏令時更改的過去和未來(盡可能多)。
下面對演示的幾點說明:
// Sample data generation. Not part of the solution
let t =
materialize(range i from 1 to 15 step 1 | extend dt_utc = bin(ago(rand()*365d*10), 1s))
;
// Solution Starts here
let time_zone =
externaldata(zone_name:string, country_code:string, tz_abbreviation:string, unixtime_start:long, gmt_offset_seconds:int, is_dst:bool)
[
h"https://dumarkovadlsgen2.dfs.core.windows.net/mycontainer/TimeZoneDB/time_zone.csv;impersonate"
]
with (format=csv)
| where zone_name == "America/New_York"
| extend gmt_offset = gmt_offset_seconds * 1s
| extend datetime_start = unixtime_seconds_todatetime(unixtime_start)
| project datetime_start, gmt_offset
;
let time_zone_dst_range =
time_zone
| order by datetime_start asc
| extend next_datetime_start = next(datetime_start, 1, datetime(9999))
| mv-expand year = range(getyear(datetime_start), getyear(next_datetime_start)) to typeof(long)
;
t
| extend year = getyear(dt_utc)
| lookup time_zone_dst_range on year
| where dt_utc >= datetime_start and dt_utc < next_datetime_start
| extend et_utc = dt_utc + gmt_offset
一世 | dt_utc | 年 | 日期時間開始 | gmt_offset | next_datetime_start | et_utc |
---|---|---|---|---|---|---|
10 | 2014-05-12T02:03:38Z | 2014 | 2014-03-09T07:00:00Z | -04:00:00 | 2014-11-02T06:00:00Z | 2014-05-11T22:03:38Z |
13 | 2014-12-26T21:46:29Z | 2014 | 2014-11-02T06:00:00Z | -05:00:00 | 2015-03-08T07:00:00Z | 2014-12-26T16:46:29Z |
11 | 2015-01-04T03:04:33Z | 2015 | 2014-11-02T06:00:00Z | -05:00:00 | 2015-03-08T07:00:00Z | 2015-01-03T22:04:33Z |
4 | 2016-12-02T13:34:42Z | 2016 年 | 2016-11-06T06:00:00Z | -05:00:00 | 2017-03-12T07:00:00Z | 2016-12-02T08:34:42Z |
12 | 2017-03-13T04:20:32Z | 2017 | 2017-03-12T07:00:00Z | -04:00:00 | 2017-11-05T06:00:00Z | 2017-03-13T00:20:32Z |
2 | 2017-10-18T01:52:22Z | 2017 | 2017-03-12T07:00:00Z | -04:00:00 | 2017-11-05T06:00:00Z | 2017-10-17T21:52:22Z |
9 | 2018-08-15T06:00:49Z | 2018 | 2018-03-11T07:00:00Z | -04:00:00 | 2018-11-04T06:00:00Z | 2018-08-15T02:00:49Z |
7 | 2018-10-03T00:56:55Z | 2018 | 2018-03-11T07:00:00Z | -04:00:00 | 2018-11-04T06:00:00Z | 2018-10-02T20:56:55Z |
5 | 2018-12-09T08:02:56Z | 2018 | 2018-11-04T06:00:00Z | -05:00:00 | 2019-03-10T07:00:00Z | 2018-12-09T03:02:56Z |
6 | 2018-12-31T19:41:15Z | 2018 | 2018-11-04T06:00:00Z | -05:00:00 | 2019-03-10T07:00:00Z | 2018-12-31T14:41:15Z |
15 | 2019-02-07T01:19:59Z | 2019 | 2018-11-04T06:00:00Z | -05:00:00 | 2019-03-10T07:00:00Z | 2019-02-06T20:19:59Z |
1 | 2020-03-06T06:18:07Z | 2020 | 2019-11-03T06:00:00Z | -05:00:00 | 2020-03-08T07:00:00Z | 2020-03-06T01:18:07Z |
14 | 2020-04-03T21:52:31Z | 2020 | 2020-03-08T07:00:00Z | -04:00:00 | 2020-11-01T06:00:00Z | 2020-04-03T17:52:31Z |
8 | 2021-03-27T00:15:46Z | 2021 | 2021-03-14T07:00:00Z | -04:00:00 | 2021-11-07T06:00:00Z | 2021-03-26T20:15:46Z |
3 | 2021-09-23T01:17:10Z | 2021 | 2021-03-14T07:00:00Z | -04:00:00 | 2021-11-07T06:00:00Z | 2021-09-22T21:17:10Z |
通常答案是“不要在 Kusto 中執行”,在從 Kusto 讀取結果的客戶端中執行,這肯定會有“utc-to-local-time”或“utc-to-this-時區”功能。
好吧,Kusto 團隊正在快速行動:-)
添加了對時區轉換的支持:
// Sample generation. Not part of the solution
let t = materialize(range i from 1 to 15 step 1 | extend dt_utc = ago(rand()*365d*10));
// Solution Starts here
t
| extend dt_et = datetime_utc_to_local(dt_utc, "US/Eastern")
| extend offset = dt_et - dt_utc
一世 | dt_utc | dt_et | 抵消 |
---|---|---|---|
5 | 2012-12-03T17:24:51.6057076Z | 2012-12-03T12:24:51.6057076Z | -05:00:00 |
14 | 2012-12-10T05:04:17.8507406Z | 2012-12-10T00:04:17.8507406Z | -05:00:00 |
10 | 2013-03-23T14:42:00.4276416Z | 2013-03-23T10:42:00.4276416Z | -04:00:00 |
15 | 2013-10-01T06:28:36.4665806Z | 2013-10-01T02:28:36.4665806Z | -04:00:00 |
11 | 2017-07-18T06:10:30.9963876Z | 2017-07-18T02:10:30.9963876Z | -04:00:00 |
3 | 2017-11-17T21:57:58.4443366Z | 2017-11-17T16:57:58.4443366Z | -05:00:00 |
6 | 2018-05-09T03:36:24.7533896Z | 2018-05-08T23:36:24.7533896Z | -04:00:00 |
12 | 2018-06-05T17:36:41.7970716Z | 2018-06-05T13:36:41.7970716Z | -04:00:00 |
4 | 2018-08-03T16:25:19.9323686Z | 2018-08-03T12:25:19.9323686Z | -04:00:00 |
8 | 2019-02-21T17:33:52.9957996Z | 2019-02-21T12:33:52.9957996Z | -05:00:00 |
2 | 2020-09-24T18:37:08.0049776Z | 2020-09-24T14:37:08.0049776Z | -04:00:00 |
1 | 2020-12-09T19:57:23.7480626Z | 2020-12-09T14:57:23.7480626Z | -05:00:00 |
7 | 2021-01-17T13:42:55.0632136Z | 2021-01-17T08:42:55.0632136Z | -05:00:00 |
9 | 2021-03-04T23:44:01.7192366Z | 2021-03-04T18:44:01.7192366Z | -05:00:00 |
13 | 2022-06-04T16:26:57.8826486Z | 2022-06-04T12:26:57.8826486Z | -04:00:00 |
您可以使用下面給出的 function 的類似想法構建一個方便的 function。 請注意,轉換也適用於 DST(夏令時)。 您只需要一種方法將 map 放置到其時區字符串中。 在隨后的 function 中,映射是從巴西 state 縮寫到其時區字符串。 有關可用時區的列表,請參閱文檔。
.create-or-alter function with (
docstring = 'Dada uma UF e um datetime (UTC), retorna o horário local. Não é tratado o GMT-5 ao oeste de AM.' ) ToLocalDatetime(state: string, dtutc: datetime) {
let selected_tz = materialize(datatable(states:string, tz:string) [
'GO,DF,MG,ES,RJ,SP,PR,SC,RS', 'America/Sao_Paulo',
'MA,PI,CE,RN,PB', 'America/Fortaleza',
'AL,SE', 'America/Maceio',
'BA', 'America/Bahia',
'RR', 'America/Boa_Vista',
'MS', 'America/Campo_Grande',
'MT', 'America/Cuiaba',
'AM', 'America/Manaus',
'PA,AP', 'America/Belem',
'AC', 'America/Rio_Branco',
'RO', 'America/Porto_Velho',
'PE', 'America/Recife',
'TO', 'America/Araguaina'
]
| where states has state | project tz);
let localdt = datetime_utc_to_local(dtutc, toscalar(selected_tz));
format_datetime(localdt, "yyyy-MM-dd HH:mm:ss") }
幾個測試:
print(ToLocalDatetime('DF', datetime('2019-02-17 01:00:00')))
print(ToLocalDatetime('DF', datetime('2019-02-17 02:00:00')))
Z78E6221F6393D135681DB398F14CE6DZ在兩種情況下均為2019-02-16 23:00:00
(本地DF Z9ED39E2EA9E2EA9E2EA931586B6B6A985A6942EF573EZ TIME),因為DST11191913913919913919191919191911911191191919191191191199119911991191191191199119919913991391.1A991391390AN39999性小小士范站范文發發 /設2019-02-17 02:00:00Z
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.