电源查询:日期时区操作

时间:2016-03-10 21:09:50

标签: powerbi powerquery

我正在根据来自SQL Server表User的数据构建Power BI报告,该表包含DateTypeOffset(7)类型的CreatedDate列。 我正在寻找相当于.NET [TimeZoneInfo.FindSystemTimeZoneById]的Power Query。我的报告数据有一个时区信息,存储为标准ID(如太平洋标准时间),我需要将我的DateTimeOffset列中的值转换为我上面讨论的时区,这是如何我在C#中这样做:

TimeSpan timeZoneOffsetSpan = TimeZoneInfo.FindSystemTimeZoneById(settings.TimeZ​one).GetUtcOffset(UserCreatedDateTime);

这使我在设置中存储的时区中的时间与UserCreatedDateTime的UTC之间存在差异。我正在为User表中的所有行执行一行代码,因为上面代码的目的是找出当前的偏移量,同时考虑到像DayLightSaving这样的时区的功能。

现在我可以简单地对我的User.CreateDateTime列中的每个值添加偏移量(可能是正数或负数),在C#中我通过使用[DateTimeOffset.ToOffset]来实现:

DateTimeOffset convertedOffset = UserCreatedDateTime.ToOffset(timeZoneOffsetSpan)

所以我需要能够在我的Power BI报告中进行相同的转换,但我找不到任何Power Query函数,它可以执行与[TimeZoneInfo.FindSystemTimeZoneById]相同的操作,如果该函数存在,它将覆盖我的第一行C#代码然后我需要找到[TimeZoneInfo.FindSystemTimeZoneById]的等价物。 [DateTimeZone.SwitchZone]可能就是我需要的东西,但我首先要知道对应于我的时区的偏移量,然后我就可以将该偏移量作为第二个和第三个参数提供给该函数。

因此,为了最终确定,我需要Power BI模拟[TimeZoneInfo.FindSystemTimeZoneById]。 有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

您可以向数据模型添加一个表,其中包含时区ID和时区偏移的列。在主查询中,您可以加入此表,然后创建计算以将偏移量添加或减去新列。之后,删除已连接的列。

请参阅此处How can I perform the equivalent of AddHours to a DateTime in Power Query?

或者您可以使用M内置的DateTimeZone functions

答案 1 :(得分:0)

您可以利用TSQL的AT TIME ZONE功能为每个时区创建每天的偏移量表(以分钟为单位),并将结果表导入PowerBI,以便您可以添加/减去相关抵消你的基准时间。

如果我处于OP的情况,我会一直导入(转换)为UTC,然后在PowerBI中添加偏移量,具体取决于您想要显示的时区。 (也许使用this方法?)

以下示例给出了澳大利亚时区对UTC的偏移量表。

如果我的目标表是UTC并且我想更改PowerBI中的时间,我只需要将特定的偏移量添加到我的时间......

+------------+-----------+----------+----------+----------+ 
| TargetDate | QLDOffset | NTOffset | SAOffset | WAOffset |
+------------+-----------+----------+----------+----------+ 
| 2018-04-02 |      -600 |     -570 |     -570 |     -480 | 
| 2018-04-01 |      -600 |     -570 |     -570 |     -480 | 
| 2018-03-31 |      -600 |     -570 |     -630 |     -480 | 
| 2018-03-30 |      -600 |     -570 |     -630 |     -480 |
+------------+-----------+----------+----------+----------+

您可以在4月1日看到SA的偏移量变化

WITH MostDays AS ( --MostDays is a table of 10 years worth of dates going back from today.  
               SELECT Today = CAST(DATEADD(DAY, -days, GETUTCDATE())  AS DATETIMEOFFSET)
               FROM (SELECT TOP 3650 Days = ROW_NUMBER() OVER (ORDER BY message_id )  -- this will give a rolling window of 10 years
                     FROM sys.messages
                    )x
            )
--  This section takes the datetime from above, and calculates how many minutes difference there is between each timezone for each date.
Select  TargetDate=CAST(Today AS DATE)
    ,QLDOffset = DATEDIFF(minute,CAST(Today at TIME ZONE 'UTC' AT TIME ZONE  'E. Australia Standard TIME' AS DateTime),CAST(Today at TIME ZONE 'UTC' AS DATETIME))
    ,NTOffset = DATEDIFF(minute,CAST(Today at TIME ZONE 'UTC' AT TIME ZONE  'AUS Central Standard Time' AS DateTime),CAST(Today at TIME ZONE 'UTC' AS DATETIME))
    ,SAOffset = DATEDIFF(minute,CAST(Today at TIME ZONE 'UTC' AT TIME ZONE  'Cen. Australia Standard TIME' AS DateTime),CAST(Today at TIME ZONE 'UTC' AS DATETIME))
    ,WAOffset = DATEDIFF(minute,CAST(Today at TIME ZONE 'UTC' AT TIME ZONE  'W. Australia Standard TIME' AS DateTime),CAST(Today at TIME ZONE 'UTC' AS DATETIME))
FROM MostDays 

如果你对日期或时区没有限制,显然表格会变得很大