偏移量有效,但如果您关心夏令时并有一个非常通用的解决方案,则不能简单地使用固定的时区偏移量。如果您正在做一些定期生成报告并且时区必须正确的事情,请继续阅读。
感觉有点像 hack,但我们实现这些目标的方法是创建一个包含如下列的时区表:
BeginOfDay: datetime(2020-01-01 00:00:00)
Timezone: "Africa/Addis_Ababa"
UTCStart: datetime(2020-01-01 00:00:00)-3h
UTCEnd: datetime(2020-01-02 00:00:00)-3h
每个时区和感兴趣日期的组合都应该有一行。我们填充了大约十年后的未来。如果您担心存储空间或速度,您只需要包含您关心的日期范围和时区,但即使使用“所有内容”,它也不是一个很大的表格。
每一行都包含“日”BeginOfDay,它始终是午夜,相当于“2020 年 1 月 1 日”,然后是当地一天的开始和结束,以 UTC 时间表示。当然,我们编写了一个程序来生成表格的内容。
之后,您可以执行以下操作:
let TimezoneDay = datatable (BeginOfDay:datetime, Timezone:string, UTCStart:datetime, UTCEnd:datetime)
[datetime(2020-01-01), "Africa/Addis_Ababa", datetime(2019-12-31 21:00:00), datetime(2020-01-01 21:00:00),
datetime(2020-01-02), "Africa/Addis_Ababa", datetime(2020-01-01 21:00:00), datetime(2020-01-02 21:00:00),
datetime(2020-01-03), "Africa/Addis_Ababa", datetime(2020-01-02 21:00:00), datetime(2020-01-03 21:00:00)
];
let TemperatureEvents = datatable (Timestamp:datetime, Device:string, Temperature:real)
[datetime(2020-01-01 05:00:00), "Device 1", 10.5,
datetime(2020-01-01 07:00:00), "Device 1", 30.5,
datetime(2020-01-02 01:50:00), "Device 1", 24.0,
datetime(2020-01-02 20:00:00), "Device 1", 20.5,
datetime(2020-01-02 23:50:00), "Device 1", 19.5,
datetime(2020-01-01 10:20:00), "Device 2", 0.5
];
TimezoneDay
| where Timezone == "Africa/Addis_Ababa"
// Use a dummy column to emulate a cross join
| extend dummy=1
| join kind=inner (TemperatureEvents | extend dummy = 1) on dummy
// Filter values into local time
| where Timestamp between (UTCStart .. UTCEnd)
| summarize AverageTemp=avg(Temperature) by BeginOfDay, Timezone, Device
如果您有一个大型数据集,交叉连接可能会有点贵,但这是一个起点 - 您也可以进行时间窗口连接以限制您考虑的每一天的事件数量。