Compartilhar via


Variantes locais, fixas e UTC das funções de tempo atuais

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

Este artigo explora as distinções entre essas funções e esclarece quando e por que usar cada uma delas. Além disso, destaca um detalhe crítico, mas muitas vezes negligenciado. O Power Query Online sempre retorna o tempo UTC mesmo ao usar uma função rotulada como "Local". Entender 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 do 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 Um datetime que representa a hora local atual Dinâmico – retorna um novo valor sempre que é invocado durante a avaliação da consulta Retorna a hora do computador local Retorna hora 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 sempre que é invocado durante a avaliação da consulta Retorna hora local com deslocamento de fuso horário Retorna a hora UTC com o deslocamento de horário +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 compensação de fuso horário quando é chamado pela primeira vez Captura a hora UTC com +00:00 de deslocamento quando é chamado pela primeira vez Instantâneo do horário local com o fuso horário
DateTimeZone.UtcNow Um datetimezone valor que representa a hora UTC atual Dinâmico – retorna um novo valor sempre que é invocado durante a avaliação da consulta Retorna a hora UTC atual Retorna a hora UTC atual Carimbo de data/hora UTC consistente para cenários dinâmicos
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 ajustado para registro de log 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 de 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 está bem definido.

No entanto, em ambientes distribuídos ou baseados em nuvem, como o Power Query Online, essas mesmas funções retornam 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 hora local. Por outro lado, DateTimeZone.UtcNow e DateTimeZone.FixedUtcNow fornecem um ponto de referência neutro de fuso horário que é consistente entre os ambientes e não é afetado pelo horário de verão ou pelas configurações regionais. Essas funções baseadas em UTC são a opção preferencial para cenários que envolvem integração de dados, registro em log, auditoria ou qualquer lógica que deve se comportar de forma idêntica, independentemente de onde ou quando a consulta for 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 sempre que a expressão é avaliada.
  • DateTime.FixedLocalNow retorna o local datetime uma vez por avaliação de consulta, agindo como um instantâneo.
  • DateTimeZone.LocalNow retorna o local datetimezone atual sempre que a expressão é avaliada.
  • DateTimeZone.FixedLocalNow retorna o resultado local datetimezone uma vez durante a avaliação da 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 valor de DateTime.LocalNow novo usando um atraso para garantir tempos distintos, enquanto cada valor capturado de DateTime.FixedLocalNow 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 tela da tabela criada DateTime.LocalNow com datas e horas dinâmicas e DateTime.FixedLocalNow com datas e horas fixas.

Se você examinar a saída, poderá observar que, embora a função DateTime.LocalNow apareça primeiro no código, o valor retornado de DateTime.FixedLocalNow mostra uma hora que ocorre antes do tempo de DateTime.LocalTime. Embora DateTime.LocalNow esteja listado primeiro na construção da tabela, a ordem de avaliação no Power Query M não é garantida para seguir a ordem dos campos em uma tabela. Em vez disso, o Power Query usa um modelo de avaliação lento. Usar esse modelo significa que os campos só são avaliados 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 tela da tabela criada DateTimeZone.LocalNow com datas e horas dinâmicas e DateTimeZone.FixedLocalNow com datas e horas fixas.

Observação

Se você executar este exemplo no Power Query Online, o tempo retornado será sempre hora UTC e a parte de fuso horário dos valores retornados será 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 sempre que a expressão é avaliada.
  • DateTimeZone.FixedUtcNow retorna o local datetimezone uma vez por avaliação de consulta, agindo como um instantâneo.

As diferenças entre essas duas funções são semelhantes às funções LocalNow e FixedLocalNow. No entanto, se as funções são executadas no Power Query Desktop ou no Power Query Online, os valores retornados sempre são retornados 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 tela da tabela criada DateTimeZone.UtcNow com datas e horas dinâmicas e DateTimeZone.FixedUtcNow com datas e horas fixas.

Efeitos em outras 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 é retornada no Power Query Desktop ou no Power Query Online. Por exemplo, se você usar a DateTimeZone.ToLocal função para converter a hora UTC em hora local, ela ainda retornará a hora UTC no Power Query Online.

Outro exemplo é qualquer função que possa usar o tempo atual do sistema como parâmetro. Essas funções incluem Date.Month, Date.DayOfYearDateTime.IsInCurrentYearDateTimeZone.ZoneHours ou qualquer outra função que possa avaliar a data e a hora atuais.

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

Melhores práticas e recomendações

Escolher a função de hora certa no Power Query depende do seu caso de uso específico, do ambiente em que a consulta é executada (área de trabalho versus online) e se você precisa 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 de funções DateTime quando o contexto de fuso horário for importante. Use DateTimeZone.UtcNow ou DateTimeZone.FixedUtcNow para consistência em ambientes, especialmente em soluções baseadas em nuvem, como o serviço do Power BI.
  • Use funções fixas para resultados repetíveis: use as variantes fixas (como DateTimeZone.FixedUtcNow) quando quiser que o carimbo de data/hora permaneça constante durante as avaliações de consultas. 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: as funções como DateTime.LocalNow e DateTimeZone.LocalNow retornam a hora UTC em soluções baseadas em nuvem, como o serviço do Power BI, o que pode levar a uma confusão ou suposições incorretas. Se você precisar de tempo 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 área de trabalho e online: Sempre teste suas consultas no Power Query Desktop e no Power Query Online se sua lógica depender do tempo atual. Esse teste ajuda a detectar discrepâncias antecipadamente, especialmente para cenários de atualização agendados.
  • 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 tratamento de fuso horário. Essas informações ajudam os futuros colaboradores a entender a intenção por trás da lógica.
  • Use UTC para fluxos de trabalho agendados: para atualizações agendadas ou pipelines automatizados, UTC é a opção mais segura e previsível. Ele evita a ambiguidade causada pelo horário de verão ou mudanças regionais de fuso horário.
  • Valores de tempo de cache quando necessário: se você precisar usar o mesmo carimbo de data/hora em várias etapas em uma consulta, atribua-o a uma variável na parte superior da consulta usando uma função fixa. Essa variável garante consistência em toda a lógica de transformação.