Udostępnij przez


Warianty lokalne, stałe i UTC dla bieżących funkcji czasu

Podczas pracy z usługą Power Query w narzędziach, takich jak Excel i Power BI, dokładne obsługiwanie wartości daty i godziny jest niezbędne — szczególnie wtedy, gdy przekształcenia danych zależą od bieżącego czasu. Dodatek Power Query oferuje różne funkcje umożliwiające pobranie bieżącej daty i godziny:

W tym artykule omówiono różnice między tymi funkcjami i wyjaśniono, kiedy i dlaczego należy używać poszczególnych funkcji. Ponadto wyróżnia krytyczne, ale często pomijane szczegóły. Usługa Power Query Online zawsze zwraca czas UTC nawet w przypadku używania funkcji oznaczonej jako "Lokalne". Zrozumienie tych niuansów może pomóc uniknąć nieoczekiwanych wyników, zwłaszcza podczas tworzenia raportów z uwzględnieniem czasu lub automatyzowania aktualizacji danych w aplikacjach, takich jak usługa Power BI lub Power Apps.

Różnice między funkcjami

Każda z bieżących funkcji czasu ma ważne różnice. Te funkcje różnią się pod względem świadomości strefy czasowej, zmienności (czy wartość zmienia się w przypadku wywołania wiele razy w tym samym zapytaniu) i jak zachowują się w różnych środowiskach (pulpit a online). Poniższa tabela zawiera podział każdej funkcji.

Funkcja Zwraca Lotność Zachowanie pulpitu Zachowanie online Typowy przypadek użycia
DateTime.LocalNow datetime reprezentujący bieżący czas lokalny Dynamiczne — zwraca nową wartość za każdym razem, gdy jest wywoływana podczas oceny zapytania Zwraca czas komputera lokalnego Zwraca czas UTC Szybki znacznik czasu lokalnego bez kontekstu strefy czasowej
DateTimeZone.LocalNow datetimezone Wartość reprezentująca bieżący czas lokalny z przesunięciem strefy czasowej Dynamiczne — zwraca nową wartość za każdym razem, gdy jest wywoływana podczas oceny zapytania Zwraca czas lokalny z przesunięciem Zwraca czas UTC z przesunięciem +00:00 Czas lokalny z rozpoznawaniem strefy czasowej
DateTime.FixedLocalNow datetime Wartość reprezentująca czas lokalny podczas pierwszego wywołania podczas oceny zapytania Naprawiono — zwraca tę samą wartość w ramach pojedynczej oceny zapytania Przechwytuje czas lokalny po pierwszym wywołaniu Przechwytuje czas UTC po pierwszym wywołaniu Migawka czasu lokalnego bez strefy czasowej
DateTimeZone.FixedLocalNow datetimezone Wartość reprezentująca lokalny czas z przesunięciem przy pierwszym wywołaniu podczas przetwarzania zapytania Naprawiono — zwraca tę samą wartość w ramach pojedynczej oceny zapytania Przechwytuje czas lokalny z przesunięciem podczas pierwszego wywołania. Przechwytuje czas UTC z przesunięciem +00:00 przy pierwszym wywołaniu Zrzut czasu lokalnego ze strefą czasową
DateTimeZone.UtcNow datetimezone Wartość reprezentująca bieżącą godzinę UTC Dynamiczne — zwraca nową wartość za każdym razem, gdy jest wywoływana podczas oceny zapytania Zwraca bieżącą godzinę UTC Zwraca bieżącą godzinę UTC Spójny znacznik czasu UTC dla scenariuszy dynamicznych
DateTimeZone.FixedUtcNow datetimezone Wartość reprezentująca czas UTC podczas pierwszego wywołania podczas oceny zapytania Naprawiono — zwraca tę samą wartość w ramach pojedynczej oceny zapytania Przechwytuje czas UTC po pierwszym wywołaniu Przechwytuje czas UTC po pierwszym wywołaniu Skorygowano znacznik czasu UTC na potrzeby rejestrowania lub audytowania.

W Power Query M wybór między funkcjami daty i czasu opartymi na czasie lokalnym i UTC jest krytyczną decyzją projektową, która wpływa na spójność, dokładność i przenośność zapytań. Funkcje takie jak DateTime.LocalNow i DateTime.FixedLocalNow są przydatne, gdy logika zależy od czasu systemu lokalnego, takiego jak filtrowanie rekordów, które wystąpiły "dzisiaj" lub generowanie sygnatur czasowych dla raportów użytkowników. Te funkcje odzwierciedlają strefę czasową środowiska, w którym jest wykonywane zapytanie, dzięki czemu są odpowiednie dla scenariuszy programu Power Query Desktop, w których kontekst lokalny jest dobrze zdefiniowany.

Jednak w środowiskach rozproszonych lub opartych na chmurze, takich jak Power Query Online, te same funkcje zwracają czas UTC, a nie rzeczywisty czas lokalny użytkownika. Ta rozbieżność może prowadzić do subtelnych niespójności, jeśli logika zakłada kontekst czasu lokalnego. Z kolei DateTimeZone.UtcNow i DateTimeZone.FixedUtcNow zapewniają neutralny dla strefy czasowej punkt odniesienia, który jest spójny w różnych środowiskach i nie ma to wpływu na ustawienia czasu letniego lub regionalnego. Te funkcje oparte na utc są preferowanym wyborem dla scenariuszy obejmujących integrację danych, rejestrowanie, inspekcję lub dowolną logikę, która musi zachowywać się identycznie niezależnie od tego, gdzie lub kiedy jest uruchamiane zapytanie.

Różnice między funkcjami LocalNow i FixedLocalNow

Dodatek Power Query M udostępnia cztery funkcje pobierania bieżącego czasu lokalnego:

  • DateTime.LocalNow Zwraca bieżący lokalny datetime za każdym razem, gdy wyrażenie jest obliczane.
  • DateTime.FixedLocalNow Zwraca wartość lokalną datetime raz podczas oceny zapytania, tworząc migawkę.
  • DateTimeZone.LocalNow Zwraca bieżący lokalny datetimezone za każdym razem, gdy wyrażenie jest obliczane.
  • DateTimeZone.FixedLocalNow zwraca lokalną wartość datetimezone raz na ewaluację zapytania, działając jak migawka

Aby zademonstrować różnicę, poniższy przykład generuje tabelę z wieloma wierszami. Każdy wiersz przechwytuje nową DateTime.LocalNow wartość przy użyciu opóźnienia, aby zapewnić odrębne znaczniki czasu, podczas gdy każda przechwycona DateTime.FixedLocalNow wartość pozostaje stała we wszystkich wierszach.

Uwaga / Notatka

Wszystkie daty i godziny w danych wyjściowych przykładów w tym artykule zależą od czasu uruchomienia funkcji. Daty i godziny wyświetlane w danych wyjściowych są przeznaczone tylko do celów demonstracyjnych.

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

Dane wyjściowe tego przykładu to:

Zrzut ekranu przedstawiający tabelę utworzoną przy użyciu DateTime.LocalNow dynamicznych dat i godzin oraz DateTime.FixedLocalNow stałych dat i godzin.

Jeśli spojrzysz na dane wyjściowe, możesz zauważyć, że mimo iż funkcja DateTime.LocalNow pojawiła się jako pierwsza w kodzie, wartość zwracana przez DateTime.FixedLocalNow pokazuje czas, który występuje przed czasem DateTime.LocalTime. Mimo że DateTime.LocalNow jest wymieniony jako pierwszy w konstrukcji tabeli, kolejność oceny w Power Query M nie jest gwarantowana, aby odpowiadała kolejności pól w tabeli. Zamiast tego dodatek Power Query używa leniwego modelu oceny. Użycie tego modelu oznacza, że pola są oceniane tylko w razie potrzeby, a aparat określa kolejność oceny, a nie kolejność w kodzie. Funkcja DateTime.FixedLocalNow jest oceniana w pierwszej kolejności, dlatego po raz pierwszy zwrócony czas dla tej funkcji występuje przed czasem zwróconym po raz pierwszy dla funkcji DateTime.LocalNow.

W poniższym przykładzie pokazano, jak wygenerować podobne wyniki przy użyciu elementów DateTimeZone.LocalNow i DateTimeZone.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

Dane wyjściowe tego przykładu w programie Power Query Desktop to:

Zrzut ekranu przedstawiający tabelę utworzoną przy użyciu DateTimeZone.LocalNow dynamicznych dat i godzin oraz DateTimeZone.FixedLocalNow stałych dat i godzin.

Uwaga / Notatka

Jeśli uruchomisz ten przykład w usłudze Power Query Online, zwracany czas to zawsze czas UTC, a część strefy czasowej zwracanych wartości jest zawsze +00:00.

Różnice między funkcjami UtcNow i FixedUtcNow

Dodatek Power Query M udostępnia dwie funkcje pobierania bieżącej godziny UTC:

  • DateTimeZone.UtcNow zwraca bieżący czas UTC datetimezone za każdym razem, gdy wyrażenie jest obliczane.
  • DateTimeZone.FixedUtcNow Zwraca wartość lokalną datetimezone raz podczas oceny zapytania, tworząc migawkę.

Różnice między tymi dwiema funkcjami są podobne do funkcji LocalNow i FixedLocalNow. Jednak niezależnie od tego, czy funkcje są uruchamiane w programie Power Query Desktop, czy w usłudze Power Query Online, zwracane wartości są zawsze zwracane jako czas UTC. W poniższym przykładzie przedstawiono różnice między tymi dwiema funkcjami.

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

Dane wyjściowe tego przykładu w programie Power Query Desktop i dodatku Power Query Online to:

Zrzut ekranu przedstawiający tabelę utworzoną przy użyciu DateTimeZone.UtcNow dynamicznych dat i godzin oraz DateTimeZone.FixedUtcNow stałych dat i godzin.

Wpływ na inne funkcje

Inne funkcje dodatku Power Query M, które zależą od bieżącej daty i godziny, mogą również mieć wpływ na sposób zwracania czasu lokalnego w programie Power Query Desktop lub w usłudze Power Query Online. Jeśli na przykład używasz funkcji do konwertowania DateTimeZone.ToLocal czasu UTC na czas lokalny, nadal zwraca czas UTC w usłudze Power Query Online.

Innym przykładem jest dowolna funkcja, która może używać bieżącego czasu systemowego jako parametru. Te funkcje obejmują Date.Month, Date.DayOfYear, DateTime.IsInCurrentYear, DateTimeZone.ZoneHourslub dowolną inną funkcję, która może ocenić bieżącą datę i godzinę.

We wszystkich tych funkcjach, jeśli logika zależy od tego, czy wartość mieści się w ciągu bieżącego dnia, godziny, miesiąca lub roku, wyniki mogą się różnić między środowiskami. Te różnice między środowiskami są szczególnie zauważalne, jeśli zapytanie działa w pobliżu granicy (na przykład tuż przed lub po północy, początku nowego miesiąca lub nowego roku). Jeśli spójność ma kluczowe znaczenie w różnych środowiskach, użyj funkcji DateTimeZone.UtcNow lub DateTimeZone.FixedUtcNow do pobrania daty i godziny.

Najlepsze wskazówki i rekomendacje

Wybór odpowiedniej funkcji czasu w dodatku Power Query zależy od konkretnego przypadku użycia, środowiska, w którym jest uruchamiane zapytanie (pulpit i online) oraz czy potrzebujesz dynamicznego, czy stałego znacznika czasu. Oto kilka najlepszych rozwiązań, które pomogą Ci w podjęciu decyzji:

  • Należy jawnie określać strefy czasowe: użyj funkcji DateTimeZone zamiast funkcji DateTime, gdy kontekst strefy czasowej ma znaczenie. Używaj DateTimeZone.UtcNow lub DateTimeZone.FixedUtcNow w celu zapewnienia spójności w różnych środowiskach, szczególnie w rozwiązaniach opartych na chmurze, takich jak usługa Power BI.
  • Użyj stałych funkcji dla powtarzalnych wyników: użyj stałych wariantów (takich jak DateTimeZone.FixedUtcNow), jeśli znacznik czasu ma pozostać stały w ocenach zapytań. Ta metoda jest szczególnie przydatna w przypadku rejestrowania, audytowania lub przechwytywania czasu wprowadzania danych.
  • Unikaj lokalnych funkcji w usłudze Power Query Online: funkcje takie jak DateTime.LocalNow i DateTimeZone.LocalNow zwracają czas UTC w rozwiązaniach opartych na chmurze, takich jak usługa Power BI, co może prowadzić do nieporozumień lub nieprawidłowych założeń. Jeśli potrzebujesz rzeczywistego czasu lokalnego w usłudze, rozważ ręczne dostosowanie czasu UTC przy użyciu znanych przesunięć (chociaż ta korekta może być krucha, na przykład ze względu na czas letni lub ustawienia regionalne).
  • Testowanie zarówno w środowiskach klasycznych, jak i online: zawsze testuj zapytania zarówno w programie Power Query Desktop, jak i w usłudze Power Query Online, jeśli logika zależy od bieżącego czasu. Te testy ułatwiają wczesne przechwytywanie rozbieżności, szczególnie w przypadku scenariuszy zaplanowanego odświeżania.
  • Udokumentuj swoją logikę czasową: jasno skomentuj lub udokumentuj, dlaczego używasz konkretnej funkcji czasowej, zwłaszcza jeśli stosujesz obejście dla obsługi stref czasowych. Te informacje pomagają przyszłym współpracownikom zrozumieć intencję logiki.
  • Użyj UTC dla zaplanowanych przepływów pracy: W przypadku zaplanowanych odświeżeń lub zautomatyzowanych procesów UTC jest najbezpieczniejszym i najbardziej przewidywalnym wyborem. Pozwala uniknąć niejednoznaczności spowodowanej zmianą czasu letniego lub regionalnych zmian strefy czasowej.
  • Buforuj wartości czasu w razie potrzeby: jeśli musisz użyć tego samego znacznika czasu w wielu krokach zapytania, przypisz go do zmiennej w górnej części zapytania przy użyciu stałej funkcji. Ta zmienna zapewnia spójność w całej logice przekształcania.