次の方法で共有


現在の時刻関数のローカル、固定、および UTC のバリアント

Excel や Power BI などのツールで Power Query を使用する場合、日付と時刻の値を正確に処理することが不可欠です。特に、データ変換が現在の時刻に依存する場合です。 Power Query には、現在の日付と時刻を取得するためのさまざまな関数が用意されています。

この記事では、これらの関数の違いについて説明し、各関数を使用するタイミングと理由を明らかにします。 さらに、重要ですが、見過ごされることが多い詳細が強調表示されています。 Power Query Online では、"Local" というラベルの付いた関数を使用している場合でも、常に UTC 時刻が返されます。これらの違いを理解すると、特に時間の影響を受けやすいレポートを作成したり、Power BI サービスや Power Apps などのアプリでデータ更新を自動化したりする場合に、予期しない結果を回避するのに役立ちます。

関数の違い

現在の時刻関数にはそれぞれ重要な違いがあります。 これらの関数は、タイム ゾーンの認識、ボラティリティ (同じクエリで複数回呼び出されたときに値が変化するかどうか)、および異なる環境 (デスクトップとオンライン) での動作によって異なります。 次の表に、各関数の内訳を示します。

機能 返品ポリシー 揮発度 デスクトップの動作 オンライン動作 一般的なユース ケース
DateTime.LocalNow 現在の現地時刻を表すdatetime 動的 - クエリの評価中に呼び出されるたびに新しい値を返します ローカル コンピューター時刻を返します UTC 時刻を返します。 タイム ゾーン コンテキストのないクイック ローカル タイムスタンプ
DateTimeZone.LocalNow タイム ゾーン オフセットを持つ現在の現地時刻を表す datetimezone 動的 - クエリの評価中に呼び出されるたびに新しい値を返します オフセット付きの現地時刻を返します +00:00 オフセットを含む UTC 時刻を返します。 タイム ゾーン認識を使用した現地時刻
DateTime.FixedLocalNow クエリの評価中に最初に呼び出されたときのローカル時刻を表す datetime 修正済み - 1 つのクエリ評価全体で同じ値を返します 最初に呼び出されたときの現地時刻をキャプチャします 最初に呼び出されたときの UTC 時刻をキャプチャします タイム ゾーンのないローカル時刻のスナップショット
DateTimeZone.FixedLocalNow クエリの評価中に最初に呼び出されたときのオフセットを持つローカル時刻を表す datetimezone 修正済み - 1 つのクエリ評価全体で同じ値を返します 最初に呼び出したときにオフセット付きのローカル時刻を取得します 最初に呼び出されたときに、 +00:00 オフセットを使用して UTC 時刻をキャプチャします タイム ゾーンを使用したローカル時刻のスナップショット
DateTimeZone.UtcNow 現在の UTC 時刻を表す datetimezone 動的 - クエリの評価中に呼び出されるたびに新しい値を返します 現在の UTC 時刻を返します 現在の UTC 時刻を返します 動的シナリオの一貫性のある UTC タイムスタンプ
DateTimeZone.FixedUtcNow クエリの評価中に最初に呼び出された UTC 時刻を表す datetimezone 修正済み - 1 つのクエリ評価全体で同じ値を返します 最初に呼び出されたときの UTC 時刻をキャプチャします 最初に呼び出されたときの UTC 時刻をキャプチャします ログ記録または監査の UTC タイムスタンプを修正しました

Power Query M では、ローカル時刻と UTC ベースの日付と時刻の関数のいずれかを選択することは、クエリの一貫性、精度、移植性に影響を与える重要な設計上の決定です。 DateTime.LocalNowDateTime.FixedLocalNowなどの関数は、"今日" に発生したレコードのフィルター処理や、ユーザー向けレポートのタイムスタンプの生成など、ロジックがローカル システム時刻に依存する場合に便利です。 これらの関数は、クエリが実行される環境のタイム ゾーンを反映しているため、ローカル コンテキストが明確に定義されている Power Query Desktop シナリオに適しています。

ただし、Power Query Online などの分散型またはクラウドベースの環境では、これらの同じ関数はユーザーの実際の現地時刻ではなく UTC 時刻を返します。 この不一致により、ロジックがローカル時刻コンテキストを想定している場合、微妙な不整合が発生する可能性があります。 これに対し、 DateTimeZone.UtcNowDateTimeZone.FixedUtcNow は、環境間で一貫性があり、夏時間や地域の設定の影響を受けない、タイム ゾーンに依存しない参照ポイントを提供します。 これらの UTC ベースの関数は、データ統合、ログ記録、監査、またはクエリの実行場所やタイミングに関係なく同じように動作する必要があるロジックを含むシナリオに適しています。

LocalNow 関数と FixedLocalNow 関数の違い

Power Query M には、現在の現地時刻を取得するための 4 つの関数が用意されています。

  • DateTime.LocalNow は、式が評価されるたびに現在のローカル datetime を返します。
  • DateTime.FixedLocalNow は、クエリ評価ごとに 1 回、スナップショットとして機能するローカル datetime を返します。
  • DateTimeZone.LocalNow は、式が評価されるたびに現在のローカル datetimezone を返します。
  • DateTimeZone.FixedLocalNow は、クエリ評価ごとに 1 回、スナップショットとして機能するローカル datetimezone を返します

この違いを示すために、次の例では複数の行を含むテーブルを生成します。 各行は、遅延を使用して新しい DateTime.LocalNow 値をキャプチャして個別のタイムスタンプを確保します。一方、キャプチャされた各 DateTime.FixedLocalNow 値はすべての行で一定のままです。

この記事の例の出力のすべての日付と時刻は、関数が実行されるタイミングによって異なります。 出力に表示される日付と時刻は、デモンストレーションのみを目的としています。

let
    // Create a table with LocalNow and FixedLocalNow columns 
    TableWithTimes = Table.FromList(
        {1..5},
        each {
            _,
            Function.InvokeAfter(() => DateTime.LocalNow(), #duration(0, 0, 0, 0.2)),
            Function.InvokeAfter(() => DateTime.FixedLocalNow(), #duration(0, 0, 0, 0.2))
        },
        {"Index", "LocalNow", "FixedLocalNow"}
    ),

    // Format both datetime columns
    FormatLocalNow = Table.TransformColumns(TableWithTimes, 
        {{"LocalNow", each DateTime.ToText(_, "yyyy-MM-ddThh:mm:ss.fff")}}),
    FormatFixedNow = Table.TransformColumns(FormatLocalNow, 
        {{"FixedLocalNow", each DateTime.ToText(_, "yyyy-MM-ddThh:mm:ss.fff")}}),

    // Change the table types
    FinalTable =  Table.TransformColumnTypes(FormatFixedNow, {{"Index", Int64.Type}, 
        {"LocalNow", type text}, {"FixedLocalNow", type text}})

in
    FinalTable

出力は次のとおりです。

動的な日付と時刻を含む DateTime.LocalNow と、固定の日付と時刻を含む DateTime.FixedLocalNow によって作成されたテーブルのスクリーンショット。

出力を見ると、 DateTime.LocalNow 関数がコードの最初に表示されていても、 DateTime.FixedLocalNow に返される値には、 DateTime.LocalTime 時刻より前の時刻が表示されます。 テーブルの構築で最初に DateTime.LocalNow が一覧表示されている場合でも、Power Query M での評価の順序がテーブル内のフィールドの順序に従う保証はありません。 代わりに、Power Query では遅延評価モデルが使用されます。 このモデルを使用すると、フィールドは必要なときにのみ評価され、エンジンはコード内の順序ではなく評価順序を決定することを意味します。 この場合、 DateTime.FixedLocalNow 関数は最初に評価されるため、この関数に対して最初に返された時刻は、 DateTime.LocalNowに対して初めて返される前に発生します。

次の例は、 DateTimeZone.LocalNowDateTimeZone.FixedLocalNowを使用して同様の結果を生成する方法を示しています。

let
    // Create a table with LocalNow and FixedLocalNow columns 
    TableWithTimes = Table.FromList(
        {1..5},
        each {
            _,
            Function.InvokeAfter(() => DateTimeZone.LocalNow(), #duration(0, 0, 0, 0.2)),
            Function.InvokeAfter(() => DateTimeZone.FixedLocalNow(), #duration(0, 0, 0, 0.2))
        },
        {"Index", "LocalNow", "FixedLocalNow"}
    ),

    // Format both datetimezone columns
    FormatLocalNow = Table.TransformColumns(TableWithTimes, 
        {{"LocalNow", each DateTimeZone.ToText(_, "yyyy-MM-ddThh:mm:ss.fff:zzz")}}),
    FormatFixedNow = Table.TransformColumns(FormatLocalNow, 
        {{"FixedLocalNow", each DateTimeZone.ToText(_, "yyyy-MM-ddThh:mm:ss.fff:zzz")}}),

    //  Change the table types
    FinalTable =  Table.TransformColumnTypes(FormatFixedNow, 
        {{"Index", Int64.Type}, {"LocalNow", type text}, {"FixedLocalNow", type text}})
in
    FinalTable

Power Query Desktop でのこの例の出力は次のとおりです。

動的な日付と時刻を含む DateTimeZone.LocalNow と、固定の日付と時刻を含む DateTimeZone.FixedLocalNow によって作成されたテーブルのスクリーンショット。

Power Query Online でこの例を実行すると、返される時刻は常に UTC 時刻になり、返される値のタイム ゾーン部分は常に +00:00

UtcNow 関数と FixedUtcNow 関数の違い

Power Query M には、現在の UTC 時刻を取得するための 2 つの関数が用意されています。

  • DateTimeZone.UtcNow は、式が評価されるたびに現在の UTC datetimezone を返します。
  • DateTimeZone.FixedUtcNow は、クエリ評価ごとに 1 回、スナップショットとして機能するローカル datetimezone を返します。

これら 2 つの関数の違いは、 LocalNow 関数と FixedLocalNow 関数に似ています。 ただし、関数が Power Query Desktop または Power Query Online のいずれで実行されている場合でも、戻り値は常に UTC 時刻として返されます。 次の例では、これら 2 つの関数の違いを示します。

let
    // Create a table with UtcNow and FixedUtcNow columns 
    TableWithTimes = Table.FromList(
        {1..5},
        each {
            _,
            Function.InvokeAfter(() => DateTimeZone.UtcNow(), #duration(0, 0, 0, 0.2)),
            Function.InvokeAfter(() => DateTimeZone.FixedUtcNow(), #duration(0, 0, 0, 0.2))
        },
        {"Index", "UtcNow", "FixedUtcNow"}
    ),

    // Format both datetimezone columns
    FormatLocalNow = Table.TransformColumns(TableWithTimes, 
        {{"UtcNow", each DateTimeZone.ToText(_, "yyyy-MM-ddThh:mm:ss.fff:zzz")}}),
    FormatFixedNow = Table.TransformColumns(FormatLocalNow, 
        {{"FixedUtcNow", each DateTimeZone.ToText(_, "yyyy-MM-ddThh:mm:ss.fff:zzz")}}),

    //  Change the table types
    FinalTable =  Table.TransformColumnTypes(FormatFixedNow, 
        {{"Index", Int64.Type}, {"UtcNow", type text}, {"FixedUtcNow", type text}})
in
    FinalTable

Power Query Desktop と Power Query Online の両方でのこの例の出力は次のとおりです。

動的な日付と時刻を含む DateTimeZone.UtcNow と、固定の日付と時刻を含む DateTimeZone.FixedUtcNow によって作成されたテーブルのスクリーンショット。

その他の関数への影響

現在の日付と時刻に依存する他の Power Query M 関数は、Power Query Desktop または Power Query Online でローカル時刻を返す方法によっても影響を受ける可能性があります。 たとえば、 DateTimeZone.ToLocal 関数を使用して UTC 時刻を現地時刻に変換した場合でも、Power Query Online では UTC 時刻が返されます。

もう 1 つの例は、現在のシステム時刻をパラメーターとして使用できる任意の関数です。 これらの関数には、 Date.MonthDate.DayOfYearDateTime.IsInCurrentYearDateTimeZone.ZoneHours、または現在の日時を評価できるその他の関数が含まれます。

これらのすべての関数で、値が現在の日、時、月、または年内にあるかどうかによってロジックが依存している場合、結果は環境によって異なる可能性があります。 これらの環境の違いは、クエリが境界の近くで実行される場合に特に顕著です (たとえば、午前 0 時の直前または直後、新しい月の始まり、新年など)。 異なる環境で整合性が重要な場合は、 DateTimeZone.UtcNow または DateTimeZone.FixedUtcNow 関数を使用して日付と時刻を取得します。

ベスト プラクティスとレコメンデーション

Power Query で適切な時刻関数を選択するかどうかは、特定のユース ケース、クエリを実行する環境 (デスクトップとオンライン)、動的タイムスタンプと固定タイムスタンプのどちらを必要とするかによって異なります。 決定を導くために役立つベスト プラクティスを次に示します。

  • タイム ゾーンについて明示的にする: タイム ゾーン コンテキストが重要な場合は、DateTime 関数の代わりに DateTimeZone 関数を使用します。 DateTimeZone.UtcNowまたはDateTimeZone.FixedUtcNowを使用して、環境間の整合性を確保します。特に、Power BI サービスなどのクラウドベースのソリューションで使用します。
  • 反復可能な結果に固定関数を使用する: クエリ評価全体でタイムスタンプを一定に保つ場合は、固定バリアント ( DateTimeZone.FixedUtcNow など) を使用します。 この方法は、データ インジェストの時刻のログ記録、監査、キャプチャに特に役立ちます。
  • Power Query Online でローカル関数を回避する: DateTime.LocalNowDateTimeZone.LocalNow などの関数は、Power BI サービスなどのクラウドベースのソリューションで UTC 時刻を返します。これは、混乱や誤った想定につながる可能性があります。 サービスで実際の現地時刻が必要な場合は、既知のオフセットを使用して UTC を手動で調整することを検討してください (ただし、夏時間や地域設定などによって、この調整は脆弱になる可能性があります)。
  • デスクトップ環境とオンライン環境の両方でテストする: ロジックが現在の時刻に依存している場合は、常に Power Query Desktop と Power Query Online の両方でクエリをテストします。 このテストは、特にスケジュールされた更新シナリオで、不一致を早期にキャッチするのに役立ちます。
  • 時間ロジックを文書化する: タイム ゾーン処理の回避策を使用している場合は特に、特定の時間関数が使用される理由を明確にコメントまたは文書化します。 この情報は、将来のコラボレーターがロジックの背後にある意図を理解するのに役立ちます。
  • スケジュールされたワークフローに UTC を使用する: スケジュールされた更新または自動パイプラインの場合、最も安全で予測可能な選択は UTC です。 夏時間または地域のタイム ゾーンのシフトによって生じるあいまいさを回避します。
  • 必要に応じてキャッシュ時間の値: クエリ内の複数のステップで同じタイムスタンプを使用する必要がある場合は、固定関数を使用してクエリの上部にある変数に割り当てます。 この変数により、変換ロジック全体の一貫性が確保されます。