Nascer e pôr do sol no horário de Brasília: datas e fuso no n8n

Muitas APIs devolvem datas e horas em UTC, o horário de referência mundial, que fica 3 horas à frente do horário de Brasília. Se você mostrar esse valor sem converter, a pessoa lê “o sol nasce às 08:55” quando, na verdade, ele nasce às 05:55. Neste tutorial você vai consultar uma API gratuita de nascer e pôr do sol no n8n e aprender a converter as datas para o horário de Brasília do jeito certo.

Usamos como exemplo um lugar público e conhecido, a Praça dos Três Poderes, em Brasília. São só três nós, e o que você aprende aqui vale para qualquer API que devolva datas: formatar, trocar o fuso e transformar segundos em horas e minutos.

O que você vai construir

Este é o workflow final no editor do n8n:

Editor do n8n com o workflow Nascer e pôr do sol em Brasília: nós When clicking Execute workflow, HTTP Request e Edit Fields ligados em sequência
O workflow final “Nascer e pôr do sol em Brasília” no editor do n8n (versão 2.40.7).
  • Manual Trigger (no canvas, “When clicking ‘Execute workflow’”): inicia o workflow quando você clica no botão.
  • HTTP Request: consulta a API sunrise-sunset.org com a latitude e a longitude do ponto.
  • Edit Fields: converte os horários de UTC para o horário de Brasília e deixa só os campos que interessam.

Versão usada: n8n 2.40.7. Os nomes de botões e campos aparecem em inglês, exatamente como na interface. As coordenadas usadas são as da Praça dos Três Poderes, um ponto público; troque pelas de qualquer lugar que quiser.

Pré-requisitos

  • Um n8n funcionando no seu computador. Se ainda não tem, siga antes o tutorial n8n do zero com Docker: instale e receba a cotação do dólar no e-mail. Nele, o n8n é configurado com o fuso America/Sao_Paulo (a variável GENERIC_TIMEZONE), que é o fuso de Brasília.
  • Acesso à internet a partir do n8n, para consultar a API.
  • Nenhuma conta, senha ou chave de API.

Montando o workflow, nó por nó

Crie um workflow novo e dê a ele o nome Nascer e pôr do sol em Brasília. Depois, adicione os três nós abaixo, nesta ordem, sempre pelo botão + que aparece à direita do nó anterior.

Nó 1: Manual Trigger (o botão de início)

Clique em Add first step e escolha Trigger manually. O nó entra no canvas com o nome When clicking ‘Execute workflow’.

Tela do nó When clicking Execute workflow, sem parâmetros para preencher
O Manual Trigger não tem nada para configurar.
CampoValorPor que assim
(nenhum)—Este nó não tem parâmetros. Ele só dispara o workflow quando você clica em Execute workflow.

Ao ser executado, ele entrega 1 item vazio para o próximo nó. É esse item que faz o HTTP Request rodar uma vez. Mais tarde, se quiser receber os horários todo dia, basta trocar este nó por um Schedule Trigger.

Nó 2: HTTP Request (consultar o nascer e o pôr do sol)

A API sunrise-sunset.org é gratuita e responde com os horários do sol para uma latitude e uma longitude. Esta é a URL base; os dados do lugar vão como parâmetros de consulta, que o n8n acrescenta ao endereço:

https://api.sunrise-sunset.org/json

Clique no + à direita do Manual Trigger, adicione um nó HTTP Request e ligue Send Query Parameters. Em Specify Query Parameters, deixe Using Fields Below e clique em Add Query Parameter quatro vezes. O valor do parâmetro date é uma expressão; digite-a com o campo em modo Expression:

{{ $today.toFormat('yyyy-MM-dd') }}
Tela do nó HTTP Request com Method GET, URL https://api.sunrise-sunset.org/json e quatro Query Parameters: lat -15.80083, lng -47.86139, formatted 0 e date com a expressão $today; à direita, a resposta com sunrise, sunset e day_length em UTC
HTTP Request com os quatro parâmetros. À direita (OUTPUT), a resposta com os horários em UTC.
CampoValorPor que assim
MethodGETVamos apenas consultar dados.
URLa URL do bloco acimaEndereço da API.
AuthenticationNoneA API é pública.
Send Query ParametersligadoPara enviar o lugar e as opções no endereço.
Specify Query ParametersUsing Fields BelowUm campo Name e um campo Value para cada parâmetro.
Parâmetro lat-15.80083Latitude da Praça dos Três Poderes. O sinal de menos indica o hemisfério sul.
Parâmetro lng-47.86139Longitude do mesmo ponto. O sinal de menos indica oeste.
Parâmetro formatted0Pede as datas no formato ISO 8601 completo, com data e fuso, que o n8n entende. Veja o que acontece com 1 nos erros comuns.
Parâmetro datea expressão do bloco acimaA data de hoje no fuso do n8n, no formato ano-mês-dia que a API espera.
Send Headers / Send BodydesligadosNão são necessários.

Por que mandar a data, se a API já usa “hoje” quando ela não é informada? Porque o “hoje” da API é contado em UTC. Das 21h à meia-noite no horário de Brasília, em UTC já é o dia seguinte. Numa consulta sem date, feita às 23h58 do dia 26/09 no horário de Brasília, a API devolveu os horários do dia 27. Com $today, que usa o fuso do n8n, a data é sempre o dia de hoje em Brasília. Na prévia abaixo do campo, a expressão aparece resolvida como 2026-09-27, a data do nosso teste.

Clique em Execute step. A resposta tem um objeto results com sunrise (nascer do sol), sunset (pôr do sol), solar_noon (meio-dia solar), day_length (duração do dia, em segundos) e os horários dos crepúsculos. Também vêm status com OK e tzid com UTC, que confirma o fuso das datas. No teste, o nascer do sol veio como 2026-09-27T08:55:45+00:00. O +00:00 no final indica UTC, e day_length veio como 43994.

Nó 3: Edit Fields (converter para o horário de Brasília)

Para trabalhar com datas, o n8n traz a biblioteca Luxon, disponível em qualquer expressão. Três peças resolvem quase tudo:

  • DateTime.fromISO(texto) transforma um texto no formato ISO, como o que a API devolveu, numa data que o n8n entende.
  • .setZone('America/Sao_Paulo') mostra essa mesma data no fuso de Brasília. O instante é o mesmo; muda só o jeito de exibir.
  • .toFormat('HH:mm') escreve a data no formato que você escolher: dd/MM/yyyy para dia/mês/ano, HH:mm para hora e minuto no formato de 24 horas.

Clique no + à direita do HTTP Request e adicione um nó Edit Fields (Set). Em Mode, deixe Manual Mapping e clique em Add Field quatro vezes. Estas são as quatro expressões, na ordem dos campos:

{{ DateTime.fromISO($json.results.sunrise).setZone('America/Sao_Paulo').toFormat('dd/MM/yyyy') }}
{{ DateTime.fromISO($json.results.sunrise).setZone('America/Sao_Paulo').toFormat('HH:mm') }}
{{ DateTime.fromISO($json.results.sunset).setZone('America/Sao_Paulo').toFormat('HH:mm') }}
{{ Duration.fromObject({ seconds: $json.results.day_length }).toFormat("h'h'mm'min'") }}
Tela do nó Edit Fields em Manual Mapping com quatro campos String: data, nascer_do_sol, por_do_sol e duracao_do_dia; à direita, a saída com 27/09/2026, 05:55, 18:08 e 12h13min
Edit Fields com as quatro conversões. À direita (OUTPUT), o resultado no horário de Brasília.
CampoValorPor que assim
ModeManual MappingCriamos cada campo à mão.
data (String)1ª expressão do bloco acimaA data do nascer do sol, no fuso de Brasília, no formato dia/mês/ano.
nascer_do_sol (String)2ª expressão do bloco acimaHora e minuto do nascer do sol em Brasília.
por_do_sol (String)3ª expressão do bloco acimaA mesma conversão, usando sunset.
duracao_do_dia (String)4ª expressão do bloco acimaTransforma os segundos em horas e minutos.
Include Other Input FieldsdesligadoA saída fica só com os quatro campos novos.

A última expressão usa Duration, outra peça do Luxon, que representa uma quantidade de tempo. Duration.fromObject({ seconds: ... }) cria uma duração a partir dos segundos, e toFormat("h'h'mm'min'") escreve as horas, a letra h, os minutos com dois dígitos e o texto min. As letras entre aspas simples aparecem do jeito que estão; por isso a expressão inteira usa aspas duplas por fora. Com 43994 segundos, o resultado é 12h13min.

Clique em Execute step. A saída mostra 27/09/2026, 05:55, 18:08 e 12h13min: os horários da API menos 3 horas, que é a diferença entre UTC e Brasília. O Brasil não tem horário de verão desde 2019, mas o setZone cuidaria disso sozinho, porque usa as regras do fuso e não um número fixo de horas.


O workflow completo e o teste

Feche o nó e clique em Execute workflow. Os três nós ficam verdes, com 1 item em cada ligação:

Workflow executado com os três nós em verde e 1 item em cada ligação
O workflow completo depois do teste.

No painel Logs, na barra inferior, selecione o nó Edit Fields para ver o resultado final:

Painel Logs com o nó Edit Fields selecionado mostrando data 27/09/2026, nascer_do_sol 05:55, por_do_sol 18:08 e duracao_do_dia 12h13min
Resultado do teste: em 27/09/2026, o sol nasceu às 05:55 e se pôs às 18:08 na Praça dos Três Poderes.

A partir daqui, você pode mandar esses campos por e-mail, como no tutorial do dólar, ou usá-los em qualquer outro nó.

Por que usar setZone se o n8n já está no fuso de Brasília?

No nosso teste, apagamos o .setZone('America/Sao_Paulo') das expressões e o resultado continuou o mesmo. Isso acontece porque o n8n já exibe as datas no fuso configurado para ele. O problema aparece quando o fuso muda: cada workflow tem, no menu … → Settings, um campo Timezone. Com ele em UTC e sem setZone, os horários voltaram para UTC (veja os erros comuns). Com setZone, o resultado continuou certo:

Edit Fields com as expressões usando setZone e a saída 27/09/2026, 05:55, 18:08 e 12h13min, mesmo com o workflow em UTC
Com o workflow em UTC, as expressões com setZone continuam mostrando o horário de Brasília.

Deixar o fuso explícito na expressão deixa o workflow independente de configuração: ele funciona igual no seu computador, num servidor em outro país ou depois de uma importação.

Erros comuns

Os horários aparecem 3 horas adiantados (08:55 em vez de 05:55). Aconteceu com o Timezone do workflow em UTC e as expressões sem setZone. O n8n mostrou os horários em UTC, exatamente como a API mandou. A solução é usar .setZone('America/Sao_Paulo'), como no Nó 3.

Edit Fields com expressões sem setZone e a saída nascer_do_sol 08:55 e por_do_sol 21:08, horários em UTC
Erro real: sem setZone e com o workflow em UTC, os horários ficam 3 horas adiantados.

“Invalid DateTime” nos campos e null na duração. Aconteceu quando trocamos o parâmetro formatted para 1. Nesse modo, a API devolve horários como 8:55:45 AM, sem data e sem fuso, e day_length como o texto 12:13:14. O DateTime.fromISO não reconhece esse formato, e a duração não sai. Volte formatted para 0.

Edit Fields com a entrada sunrise 8:55:45 AM e day_length 12:13:14; a saída mostra Invalid DateTime em data, nascer_do_sol e por_do_sol e null em duracao_do_dia
Erro real com formatted=1: as datas não são reconhecidas.

JSON do workflow para importar

Se preferir, importe o workflow pronto. Baixe o arquivo abaixo ou copie o JSON. No n8n, crie um workflow novo e escolha uma das opções: abra o menu … (três pontinhos) no topo do editor, vá em Import e depois em From file; ou cole o JSON direto no canvas com Ctrl+V.

O download é um arquivo .zip com o nascer-por-do-sol-brasilia.json dentro. Descompacte antes de importar (ou copie o JSON do bloco abaixo).

{
  "name": "Nascer e pôr do sol em Brasília",
  "nodes": [
    {
      "parameters": {},
      "id": "4e7b1d31-1111-4a2c-9d05-110000000001",
      "name": "When clicking ‘Execute workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "url": "https://api.sunrise-sunset.org/json",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "lat",
              "value": "-15.80083"
            },
            {
              "name": "lng",
              "value": "-47.86139"
            },
            {
              "name": "formatted",
              "value": "0"
            },
            {
              "name": "date",
              "value": "={{ $today.toFormat('yyyy-MM-dd') }}"
            }
          ]
        },
        "options": {}
      },
      "id": "4e7b1d31-2222-4a2c-9d05-110000000002",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.5,
      "position": [
        260,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "4e7b1d31-a001-4a2c-9d05-1100000000a1",
              "name": "data",
              "value": "={{ DateTime.fromISO($json.results.sunrise).setZone('America/Sao_Paulo').toFormat('dd/MM/yyyy') }}",
              "type": "string"
            },
            {
              "id": "4e7b1d31-a002-4a2c-9d05-1100000000a2",
              "name": "nascer_do_sol",
              "value": "={{ DateTime.fromISO($json.results.sunrise).setZone('America/Sao_Paulo').toFormat('HH:mm') }}",
              "type": "string"
            },
            {
              "id": "4e7b1d31-a003-4a2c-9d05-1100000000a3",
              "name": "por_do_sol",
              "value": "={{ DateTime.fromISO($json.results.sunset).setZone('America/Sao_Paulo').toFormat('HH:mm') }}",
              "type": "string"
            },
            {
              "id": "4e7b1d31-a004-4a2c-9d05-1100000000a4",
              "name": "duracao_do_dia",
              "value": "={{ Duration.fromObject({ seconds: $json.results.day_length }).toFormat(\"h'h'mm'min'\") }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "4e7b1d31-3333-4a2c-9d05-110000000003",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        520,
        0
      ]
    }
  ],
  "connections": {
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  }
}

O workflow não usa credenciais, então funciona logo depois de importado. Para outro lugar, troque só os valores de lat e lng no HTTP Request.

Recapitulando

  • A API sunrise-sunset.org devolve os horários do sol em UTC; com formatted em 0, eles vêm no formato ISO.
  • O parâmetro date com $today garante o dia de hoje em Brasília, e não em UTC.
  • DateTime.fromISO, setZone e toFormat convertem e formatam datas; Duration transforma segundos em horas e minutos.
  • Deixar o fuso explícito com setZone protege o workflow de mudanças no Timezone.

Essas mesmas expressões servem para qualquer data que chegue de uma API ou planilha. Nos próximos tutoriais, vamos continuar usando datas para agendar e filtrar automações.