Partilhar via


Variantes locais, fixas e UTC das funções de hora atual

Quando trabalha com o Power Query em ferramentas como o Excel e o Power BI, é essencial lidar com valores de data e hora com precisão, especialmente quando as transformações de dados dependem da hora atual. O Power Query oferece várias funções para recuperar a data e hora atuais:

Este artigo explora as distinções entre essas funções e esclarece quando e por que usar cada uma. Além disso, destaca um detalhe crítico, mas muitas vezes negligenciado. O Power Query Online devolve sempre a hora UTC, mesmo quando utiliza uma função rotulada como "Local". Compreender essas nuances pode ajudá-lo a evitar resultados inesperados, especialmente ao criar relatórios sensíveis ao tempo ou automatizar atualizações de dados em aplicativos como o serviço Power BI ou o Power Apps.

Diferenças entre funções

Cada uma das funções de tempo atuais tem diferenças importantes. Essas funções variam em termos de reconhecimento de fuso horário, volatilidade (se o valor muda quando chamado várias vezes na mesma consulta) e como eles se comportam em ambientes diferentes (desktop versus online). A tabela a seguir contém um detalhamento de cada função.

Função Devoluções Volatilidade Comportamento da área de trabalho Comportamento online Caso de uso típico
DateTime.LocalNow A datetime que representa a hora local atual Dinâmico—retorna um novo valor cada vez que ele é invocado durante a avaliação da consulta Retorna a hora da máquina local Devolve o tempo UTC Carimbo de data/hora local rápido sem contexto de fuso horário
DateTimeZone.LocalNow Um datetimezone valor que representa a hora local atual com deslocamento de fuso horário Dinâmico—retorna um novo valor cada vez que ele é invocado durante a avaliação da consulta Retorna a hora local com compensação Retorna a hora UTC com o deslocamento de +00:00 Hora local com reconhecimento de fuso horário
DateTime.FixedLocalNow Um datetime valor que representa a hora local quando invocado pela primeira vez durante a avaliação da consulta Fixo — retorna o mesmo valor em uma única avaliação de consulta Captura a hora local quando chamado pela primeira vez Captura a hora UTC quando chamado pela primeira vez Instantâneo da hora local sem fuso horário
DateTimeZone.FixedLocalNow Um datetimezone valor que representa a hora local com deslocamento quando invocado pela primeira vez durante a avaliação da consulta Fixo — retorna o mesmo valor em uma única avaliação de consulta Captura a hora local com offset quando chamado pela primeira vez Captura o tempo UTC com +00:00 deslocamento quando chamado pela primeira vez Instantâneo do tempo local com fuso horário
DateTimeZone.UtcNow Um datetimezone valor que representa a hora UTC atual Dinâmico—retorna um novo valor cada vez que ele é invocado durante a avaliação da consulta Devolve a hora UTC atual Devolve a hora UTC atual Carimbo de data/hora UTC consistente para situações dinâmicas
DateTimeZone.FixedUtcNow Um datetimezone valor que representa a hora UTC quando invocado pela primeira vez durante a avaliação da consulta Fixo — retorna o mesmo valor em uma única avaliação de consulta Captura a hora UTC quando chamado pela primeira vez Captura a hora UTC quando chamado pela primeira vez Carimbo de data/hora UTC fixo para registo ou auditoria

No Power Query M, escolher entre a hora local e as funções de data e hora baseadas em UTC é uma decisão de design crítica que afeta a consistência, a precisão e a portabilidade das suas consultas. Funções como DateTime.LocalNow e DateTime.FixedLocalNow são úteis quando sua lógica depende da hora do sistema local, como filtrar registros que ocorreram "hoje" ou gerar carimbos de data/hora para relatórios voltados para o usuário. Essas funções refletem o fuso horário do ambiente no qual a consulta é executada, tornando-as adequadas para cenários do Power Query Desktop em que o contexto local é bem definido.

No entanto, em ambientes distribuídos ou baseados na nuvem, como o Power Query Online, essas mesmas funções retornam a hora UTC, não a hora local real do usuário. Essa discrepância pode levar a inconsistências sutis se sua lógica assumir um contexto de tempo local. Em contraste, DateTimeZone.UtcNow e DateTimeZone.FixedUtcNow fornecem um ponto de referência neutro de fuso horário que seja consistente entre ambientes e não seja afetado pelo horário de verão ou configurações regionais. Essas funções baseadas em UTC são a escolha preferida para cenários que envolvem integração de dados, registro, auditoria ou qualquer lógica que deve se comportar de forma idêntica, independentemente de onde ou quando a consulta é executada.

Diferenças entre as funções LocalNow e FixedLocalNow

O Power Query M fornece quatro funções para recuperar a hora local atual:

  • DateTime.LocalNow Retorna o local datetime atual cada vez que a expressão é avaliada.
  • DateTime.FixedLocalNow Retorna a avaliação local datetime uma vez por consulta, agindo como um instantâneo.
  • DateTimeZone.LocalNow Retorna o local datetimezone atual cada vez que a expressão é avaliada.
  • DateTimeZone.FixedLocalNow retorna a avaliação local datetimezone uma vez por consulta, agindo como um instantâneo

Para demonstrar a diferença, o exemplo a seguir gera uma tabela com várias linhas. Cada linha captura um novo DateTime.LocalNow valor usando um atraso para garantir que os carimbos de data/hora sejam distintos, enquanto cada DateTime.FixedLocalNow valor capturado permanece constante em todas as linhas.

Observação

Todas as datas e horas na saída dos exemplos neste artigo dependem de quando as funções são executadas. As datas e horas mostradas na saída são apenas para fins de demonstração.

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

A saída deste exemplo é:

Captura de ecrã da tabela criada por DateTime.LocalNow com datas e horas dinâmicas e DateTime.FixedLocalNow com datas e horas fixas.

Se olhar para a saída, poderá notar que, embora a função DateTime.LocalNow apareça primeiro no código, o valor retornado para DateTime.FixedLocalNow mostra um horário que ocorre antes do horário de DateTime.LocalTime. DateTime.LocalNow Apesar de estar listada em primeiro lugar na construção da tabela, não é garantido que a ordem de avaliação no Power Query M siga a ordem dos campos numa tabela. Em vez disso, o Power Query utiliza um modelo de avaliação preguiçoso. Usar esse modelo significa que os campos são avaliados apenas quando necessário e o mecanismo determina a ordem de avaliação, não a ordem em seu código. Nesse caso, a DateTime.FixedLocalNow função é avaliada primeiro, portanto, a primeira vez retornada para essa função ocorre antes da primeira vez retornada para DateTime.LocalNow.

O exemplo a seguir mostra como produzir resultados semelhantes usando DateTimeZone.LocalNow e 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

A saída deste exemplo no Power Query Desktop é:

Captura de ecrã da tabela criada por DateTimeZone.LocalNow com datas e horas dinâmicas e DateTimeZone.FixedLocalNow com datas e horas fixas.

Observação

Se executar este exemplo no Power Query Online, a hora tornada é sempre a hora UTC e a parte de fuso horário dos valores devolvidos é sempre +00:00.

Diferenças entre as funções UtcNow e FixedUtcNow

O Power Query M fornece duas funções para recuperar a hora UTC atual:

  • DateTimeZone.UtcNow retorna o UTC datetimezone atual cada vez que a expressão é avaliada.
  • DateTimeZone.FixedUtcNow Retorna a avaliação local datetimezone uma vez por consulta, agindo como um instantâneo.

As diferenças entre estas duas funções são semelhantes às funções LocalNow e FixedLocalNow. No entanto, quer as funções sejam executadas no Power Query Desktop ou no Power Query Online, os valores de retorno são sempre devolvidos como hora UTC. O exemplo a seguir demonstra as diferenças entre essas duas funções.

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

A saída deste exemplo no Power Query Desktop e no Power Query Online é:

Captura de ecrã da tabela criada por DateTimeZone.UtcNow com datas e horas dinâmicas e DateTimeZone.FixedUtcNow com datas e horas fixas.

Efeitos noutras funções

Outras funções do Power Query M que dependem da data e hora atuais também podem ser afetadas pela forma como a hora local é devolvida no Power Query Desktop ou no Power Query Online. Por exemplo, se utilizar a função DateTimeZone.ToLocal para converter a hora UTC em hora local, a função continua a devolver a hora UTC no Power Query Online.

Outro exemplo é qualquer função que possa usar a hora atual do sistema como parâmetro. Essas funções incluem Date.Month, Date.DayOfYear, DateTime.IsInCurrentYear, DateTimeZone.ZoneHoursou qualquer outra função que possa avaliar a data e hora atuais.

Em todas essas funções, se sua lógica depender se um valor está dentro do dia, hora, mês ou ano atual, os resultados podem diferir entre os ambientes. Essas diferenças entre ambientes são especialmente percetíveis se a consulta for executada perto de um limite (por exemplo, pouco antes ou depois da meia-noite, do início de um novo mês ou de um novo ano). Se a consistência for crucial em diferentes ambientes, use as funções DateTimeZone.UtcNow ou DateTimeZone.FixedUtcNow para recuperar a data e a hora.

Melhores práticas e recomendações

A escolha da função de hora certa no Power Query depende do seu caso de utilização específico, do ambiente em que a consulta é executada (ambiente de trabalho versus online) e da necessidade de um carimbo de data/hora dinâmico ou fixo. Aqui estão algumas práticas recomendadas para ajudar a orientar sua decisão:

  • Seja explícito sobre fusos horários: use as funções DateTimeZone em vez das funções DateTime quando o contexto de fuso horário for importante. Use DateTimeZone.UtcNow ou DateTimeZone.FixedUtcNow para consistência entre ambientes, especialmente em soluções baseadas em nuvem, como o serviço Power BI.
  • Use funções fixas para resultados repetíveis: Use as variantes fixas (como DateTimeZone.FixedUtcNow) quando quiser que a marca temporal permaneça constante nas avaliações de consulta. Esse método é especialmente útil para registrar, auditar ou capturar o tempo de ingestão de dados.
  • Evite funções locais no Power Query Online: funções como DateTime.LocalNow e DateTimeZone.LocalNow retornam a hora UTC em soluções baseadas na nuvem, como o serviço Power BI, o que pode levar a confusão ou suposições incorretas. Se você precisar da hora local real no serviço, considere ajustar o UTC manualmente usando deslocamentos conhecidos (embora esse ajuste possa ser frágil, por exemplo, devido ao horário de verão ou às configurações regionais).
  • Teste em ambientes de trabalho e online: Teste sempre as suas consultas no Power Query Desktop e no Power Query Online se a sua lógica depender do tempo atual. Esse teste ajuda a detetar discrepâncias antecipadamente, especialmente para cenários de atualização agendada.
  • Documente sua lógica de tempo: comente ou documente claramente por que uma função de hora específica é usada, especialmente se você estiver usando uma solução alternativa para manipulação de fuso horário. Essas informações ajudam os futuros colaboradores a entender a intenção por trás da lógica.
  • Use o UTC para fluxos de trabalho agendados: para atualizações agendadas ou pipelines automatizados, o UTC é a escolha mais segura e previsível. Evita a ambiguidade causada pelo horário de verão ou por mudanças de fuso horário regional.
  • Valores de tempo de cache quando necessário: se você precisar usar o mesmo carimbo de data/hora em várias etapas de uma consulta, atribua-o a uma variável na parte superior da consulta usando uma função fixa. Esta variável garante consistência em toda a lógica de transformação.