Hora HTML: formato de 24 horas, min, max, step e segundos

HTML input type="time" aceita uma hora do dia. Mesmo que a interface exiba AM/PM, o valor geralmente é uma string de 24 horas, como 09:30, ou 13:10:20 quando os segundos são incluídos. min/max definem limites, e step define intervalos em segundos.

Diferencie o formato de exibição do valor

A interface de entrada varia de acordo com o sistema operacional, navegador e idioma do usuário. Não espere que cada lista suspensa ou seletor tenha a mesma aparência. Coloque uma string válida, como 13:30, no valor inicial, e não texto de exibição localizado, como 1:30 PM. Defina o valor inicial com o atributo value e leia a seleção atual do usuário através de input.value.

Um valor de hora não possui data nem fuso horário. Ele não consegue informar se 9h significa Seul ou outro local. Para uma reserva que identifica um instante real, colete também a data e o fuso horário de referência e os interprete consistentemente no servidor. Para uma duração, como 90 minutos, escolha um formato adequado, como uma contagem numérica de minutos, em vez de reutilizar um controle de hora do dia.

Defina limites e intervalos

Atributo Exemplo Significado
value 09:30 Tempo inicial; deve se adequar ao intervalo e ao passo, bem como ao formato.
min, max 09:00, 18:00 Limites inclusivos para os horários permitidos.
step 900 900 segundos são 15 minutos. O padrão 60 é um minuto; 1 é um segundo.
required Atributo booleano Bloqueia o envio normal quando vazio.
name meeting Nome do campo enviado; um id sozinho não cria um nome de dado.

A base é um min válido; se não houver, o atributo HTML value válido; na ausência de ambos, 00:00:00. Para min="09:00" step="900", 09:00, 09:15 e 09:30 são válidos, mas 09:10 não se encaixa. Isso não determina horários de reserva disponíveis ou dias fechados; implemente regras de serviço separadamente.

Exemplo completo: intervalos de 15 minutos e segundos

Salve este código como time.html e abra em um navegador. Nenhum servidor é necessário para verificar a validação e os valores enviados. O segundo input usa explicitamente step="1" para permitir segundos.

<!doctype html>
<html lang="pt">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Intervalos de horário e segundos</title>
  <style>
    body { margin: 24px; font-family: sans-serif; }
    label { display: block; margin: 16px 0 6px; }
    input { max-width: 100%; box-sizing: border-box; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Escolha um horário</h1>
  <form id="demo">
    <label for="meeting">Reunião (09:00–18:00, passos de 15 minutos)</label>
    <input id="meeting" name="meeting" type="time"
      min="09:00" max="18:00" step="900" value="09:30" required>
    <label for="checkpoint">Verificação (13:00–15:00, passos de um segundo)</label>
    <input id="checkpoint" name="checkpoint" type="time"
      min="13:00:00" max="15:00:00" step="1" value="13:10:20" required>
    <p><button type="submit">Mostrar valores enviados</button>
      <button type="reset">Redefinir</button></p>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.querySelector('#demo');
    const result = document.querySelector('#result');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      result.textContent = JSON.stringify([...new FormData(form).entries()], null, 2);
    });
    form.addEventListener('input', () => { result.textContent = ''; });
    form.addEventListener('reset', () => { result.textContent = ''; });
  </script>
</body>
</html>
  1. Envie inicialmente: meeting é 09:30 e checkpoint é 13:10:20. A saída está no formato de 24 horas mesmo que a interface use AM/PM.
  2. Defina a hora da reunião para 08:45 para falhar na validação de intervalo. 09:10 está dentro do intervalo, mas falha no passo de 15 minutos. 09:45 envia com sucesso.
  3. Limpe completamente a hora da reunião e envie para verificar a validação obrigatória. Restaure um horário válido e, em seguida, altere os segundos na segunda entrada para comparar a saída em nível de segundos.
  4. Altere apenas o step="1" do ponto de verificação para step="60" e reabra o arquivo. O inicial 13:10:20 está 20 segundos fora dos passos de um minuto de 13:00:00 e é inválido. Restaure o passo para 1 depois.
  5. O reset restaura a reunião para 09:30 e o ponto de verificação para 13:10:20.

Intervalos que atravessam a meia-noite e validação do servidor

As entradas de horário podem expressar um intervalo que passa pela meia-noite. Por exemplo, min="22:00" max="02:00" significa das 22h até a meia-noite e depois até as 2h. Não é um intervalo contendo datas reais, portanto não seleciona automaticamente a data do dia seguinte. Verifique o suporte para essa validação nos navegadores-alvo e implemente as mesmas regras no servidor.

O seletor e as mensagens de validação do navegador não substituem a validação no servidor. O servidor deve verificar o formato, o intervalo e o passo da string recebida e combiná-los com a data necessária, o fuso horário e a disponibilidade de reserva. %3A em uma URL GET é dois pontos codificados; ao analisar o valor do formulário normalmente, obtém-se uma string como 09:30.

Se também precisar de uma data, consulte os valores e limites de date. Para formatos de horário e atributos, consulte a referência de time na MDN.