Quite a few people (Ken Puls, Reza Rad and today Chris Koester) have blogged about how the M date/time zone functions work in Power Query/Power BI, and the related problem of turning a UTC time into the actual time in any given location taking Daylight Saving Time changes into account. I don’t have much to add to what they have written, but I did learn something new about this subject from a customer last week: it is possible to do the conversion in pure M if the time zone you’re converting to is your PC’s own local time zone.
Here’s an example. In 2017 the clocks in the UK went forward at 1am on Sunday March 26th. Given the following table with two times in it, one of which is 1pm on Saturday March 25th and one of which is 1pm on Sunday March 26th:
…if you assume that these times are both UTC, here’s a query that returns the correct equivalent local time for me (because my PC is set to UK time) for both of them:
let //Read data from Excel table Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content], //Change the type of the column to datetime ChangeType1 = Table.TransformColumnTypes( Source, {{"Time", type datetime}}), //Turn this into a UTC time ConvertToUTC = Table.AddColumn( ChangeType1, "UTC", each DateTime.AddZone([Time],0)), //Change the data type to datetimezone ChangeType2 = Table.TransformColumnTypes( ConvertToUTC, {{"UTC", type datetimezone}}), //Convert to local PC time ConvertToLocal = Table.AddColumn( ChangeType2, "Local", each DateTimeZone.ToLocal([UTC])), //Change type to datetimezone ChangeType3 = Table.TransformColumnTypes( ConvertToLocal , {{"Local", type datetimezone}}) in ChangeType3
Here’s a brief explanation of what the query does:
- First it reads the times from the Excel table and sets the Time column to be datetime data type
- It then creates a new column called UTC and then takes the values in the Time column and converts them to datetimezone values, using the DateTime.AddZone() function to add a time zone offset of 0 hours, making them UTC times
- Finally it creates a column called Local and converts the UTC times to my PC’s local time zone using the DateTimeZone.ToLocal() function
As you can see from the output table, the DateTimeZone.ToLocal() function has correctly handled the UK Daylight Saving Time change by converting the UTC time 13:00 on March 25th 2017 to 13:00 UK time, and converting the UTC time 13:00 on March 26th 2017 to 14:00 UK time.
Frustratingly there doesn’t seem to be a way to convert a UTC time to the correct local time in any given time zone in M – the DateTimeZone.SwitchZone() function just adds/removes hours without taking Daylight Saving Time into account, so it’s not really very useful. Apart from all the blog posts linked to at the start of this post, when I posted this question on the Power Query forum I got a very helpful answer from Marcel Beug with a completely different approach to solving the problem here, although it’s still not a straightforward one. If anyone from Microsoft is reading, it would be great to have a new M function to handle this requirement!