#タイムゾーンとは
タイムゾーンとは、協定世界時 (UTC)を元にして、各国の標準時間とのずれを表示したものです。日本標準時はJSTと呼ばれ、UTCに9時間プラス(UTC+9:00)します。
表記の仕方は、日時の表記が各国で異なりますが、通常、日時表記の後にUTCとのずれの時間を表記し、2021/03/17 10:00:00 +09:00などと書きます。
表示形式を統一するために、ISO8601のYYYY-MM-DDThh:mm:ss.sTZD形式を採用するAPIもあります。TZDは、タイムゾーンオフセットを表し、通常は+09:00などとなりますが、UTCの場合は特別に Z の1文字で表記されます。つまり、YouTubeなどのAPIから取得するデータの日時は、2021-03-07T01:46:44Zのような表記になります。この形式のデータは、Power Queryで「日付/時刻/タイムゾーン」型に変換することができます。
#Power Queryのタイムゾーンの扱い
Power QueryのM式の日時の関数は、Date、DateTime、DateTimeZoneの3段階で操作することができます。Date関数は年月日、DateTimeは年月日時分秒、DateTimeZoneは年月日時分秒に加えてオフセット時分を記述します。
以下のような、UTCとJSTデータを用意しました。このテストを行っているのが3月17日9時過ぎなので、4番目のデータ(5行目)と6番目のデータ(7行目)の日時が、現時点から大きい値になります。
これをPower BIのPower Queryで読み込ませ、Power Queryに用意された関数、DateTimeZone.LocalNowとDateTimeZone.UtcNowとの比較をさせてみました。(※ 「日時」の値が今の時間より大きければ True、小さければ Falseとなる)
タイムゾーンを判断して、UTC、JSTいずれも4番目、6番目のデータが True となり、同じ結果になることがわかります。
このままレポートに表示させても、比較はPower Queryで行っているので、上記と同じ結果となります。
ただし、これをPower BIサービスに発行し、データセットを更新してからレポートを見ると、以下のようにDateTimeZone.LocalNowの値がUTCと同じ値になってしまいます。
DateTimeZone.LocalNow関数とDateTime.LocalNow関数は、Power BI DesktopではPCの日時を返しますが、Power BIサービスに発行した後はUTCの日時を返すようになります。失敗しないために、Power Queryの中で現在の日時を使って計算する場合は、**DateTimeZone.UtcNow()**で取得し、他のデータの日時と同じタイムゾーンに変換して使うのが良いと思います。
#DAXのタイムゾーンの扱い
一方で、Power Queryエディターで見ると、以下の通り、タイムゾーンを含んで表示されていますが、
Power BIのデータビューでは、以下の通りタイムゾーン情報が消えてしまいます。
Power Query以降の処理では、タイムゾーンを扱うデータ型、関数いずれも今のところありませんので、タイムゾーンの情報は削除され、「日付と時刻」の型に変換されてしまうものと思われます。
このまま、DAXのUTCNOW関数(NOW関数でも同じ)と比較を行うと、以下のようにUTC同士の比較は正しくできますが、JSTとの比較ではタイムゾーンは考慮してもらえず、正しい結果となりません。
つまり、Power BIで日時データにタイムゾーンが含まれているときは、Power Queryの時点でタイムゾーンを意識して統一しておいた方がいいでしょう。
Power Queryでタイムゾーンを変更する
Power Queryでタイムゾーンを変更するには、DateTimeZone.SwitchZoneを使用します。Power BIのレポートでTimeZone情報は消えてしまうのですが、潔癖症な方は意図的にDateTimeZone.RemoveZoneを使ってTimeZone情報を消してDateTime型にしておきます。以下、UTCからJSTへ変更するサンプルです。
発行日の型を日時に変更 =
Table.TransformColumns(
#"展開された default",
{
{
"publishedAt",
each DateTimeZone.RemoveZone(DateTimeZone.SwitchZone(DateTimeZone.From(_), 9)),
type datetime
}
}
),
DAXでUTCを使うには
データの日時を日本標準時(JST)にしておけば、レポートにも日本標準時(JST)で表示されます。これで困るのは、UTCNOWを使って、今時点の日時とデータの日時を比較したいときです。UTCNOW、NOWいずれもUTC時間を取得しますので、そのままだとJSTと比較できません。
そこで、比較の前にUTCNOWにTIMEVALUE関数を使って9時間プラスしてやる作業が必要です。以下、サンプルです。
UTC NOWに9時間加算との比較 = [日時] > UTCNOW() + TIMEVALUE("9:00")
これで、以下ようにUTCNOWに9時間を足して比較すれば、JSTの日時と正しく比較できるようになります。
まとめ
- APIで取得するデータは日時がUTCになっている場合があるので、タイムゾーン情報には注意して、Power Queryで統一しておきましょう。
- Power Queryでタイムゾーンを変更するには、DateTimeZone.SwitchZoneを使用しましょう。
- Power Queryで取得するDateTimeZone.LocalNowとDateTime.LocalNowは、Power Query Desktopでの値はPCの日時ですが、発行してデータセットの更新をするとUTCの日時になるので注意しましょう。
- DAXでUTCNOWを使用する場合は、TIMEVALUEでデータの日時のタイムゾーンに合わせましょう。
以上