W3docs

Java LocalTime

Represente horários sem datas ou fusos horários em Java com LocalTime.

LocalTime é o espelho de LocalDate: uma hora do dia — hora, minuto, segundo, nanossegundo — com nenhuma data e nenhum fuso horário. Representa a mesma leitura de relógio de parede em todos os dias do calendário em qualquer lugar: LocalTime.of(9, 30) é nove e meia em qualquer dia em qualquer cidade.

Esse é o tipo certo para um horário recorrente do dia — loja abrindo às 09:30, um trabalho diário tipo cron às 03:15, uma reunião que começa às 14:00 independentemente da data. Não é o tipo certo para "o momento em que o usuário clicou em enviar às 14:30 hoje" — isso precisa de uma data e provavelmente de um fuso horário. Os dois combinados dão o LocalDateTime, o tema do próximo capítulo.

Criando

LocalTime now = LocalTime.now();                              // current time in the JVM default zone
LocalTime nine = LocalTime.of(9, 0);                          // hour, minute
LocalTime nineThirty = LocalTime.of(9, 30, 15);               // hour, minute, second
LocalTime nineThirtyNanos = LocalTime.of(9, 30, 15, 500_000_000);   // + nanosecond (0 ..999_999_999)
LocalTime parsed = LocalTime.parse("09:30:15");               // ISO-8601 HH:mm[:ss[.nnnnnnnnn]]

As constantes pré-definidas são úteis para condições de limite:

LocalTime.MIDNIGHT     // 00:00
LocalTime.NOON         // 12:00
LocalTime.MIN          // 00:00:00.000000000
LocalTime.MAX          // 23:59:59.999999999

MIN e MAX são especialmente úteis quando combinados com um LocalDate para abranger um dia inteiro: LocalDateTime.of(date, LocalTime.MIN) é "meia-noite no início da data"; LocalTime.MAX é o último nanossegundo representável do dia.

Resolução: nanossegundos

LocalTime é preciso até o nanossegundo — resolução equivalente a nove campos (1 segundo = 1.000.000.000 ns). Na maioria dos sistemas operacionais, a resolução real do relógio é de milissegundo (1.000.000 ns cada) ou microssegundo (1.000 ns cada); a precisão extra está lá para que o tipo não perca informações ao interagir com sistemas com relógios de maior resolução.

Acessores diretos:

time.getHour();           // 0-23
time.getMinute();         // 0-59
time.getSecond();         // 0-59
time.getNano();           // 0-999_999_999

Não há getMilli(); se você quiser milissegundos, divida o nano: time.getNano() / 1_000_000.

24 horas, sem AM/PM

LocalTime é internamente de 24 horas. LocalTime.of(13, 0) é "13h" e não há AM/PM no tipo. Analisar strings com "AM"/"PM" requer um DateTimeFormatter personalizado (o capítulo Análise de Datas cobre isso) — o parse padrão é apenas ISO-8601 de 24 horas.

Aritmética e modificações

Mesma forma fluente que LocalDate:

time.plusHours(2);
time.plusMinutes(30);
time.plusSeconds(45);
time.plusNanos(500_000);

time.withHour(14);                                            // replace one field
time.withMinute(0);

O comportamento de rotação: todo método plus/minus em LocalTime dá a volta na meia-noite silenciosamente. LocalTime.of(23, 0).plusHours(2) é 01:00, não "amanhã às 01:00" — não há "amanhã" em LocalTime. Se você precisar saber se ocorreu uma rotação, use LocalDateTime ou faça o cálculo você mesmo:

LocalTime late = LocalTime.of(23, 0);
LocalTime later = late.plusHours(2);                          // 01:00 — silently wrapped
// To detect wrap: compare the new value's getHour with what you expected, or use LocalDateTime.

Essa rotação é documentada e intencional, mas é um ponto perigoso se você esquecer. Para cálculos de "quando este turno termina?" que podem cruzar a meia-noite, o tipo certo é LocalDateTime, não LocalTime.

Comparando

time.isBefore(other);
time.isAfter(other);
time.compareTo(other);
time.equals(other);

Ordenação lexicográfica por hora:minuto:segundo:nano. LocalTime implementa Comparable<LocalTime>, então você pode ordenar uma lista de horários ou usá-lo como chave de TreeMap diretamente.

Distância

Duration.between e ChronoUnit.X.between funcionam ambos:

Duration d = Duration.between(start, end);
long minutes = ChronoUnit.MINUTES.between(start, end);
long seconds = ChronoUnit.SECONDS.between(start, end);

O sinal: positivo quando end é depois de start, negativo caso contrário. A mesma ressalva de rotação se aplica — Duration.between(LocalTime.of(23, 0), LocalTime.of(1, 0)) é −22 horas, não +2 horas; a API trata 01:00 como anterior a 23:00 do mesmo dia nocional. Para "o turno passou da meia-noite", a aritmética baseada em LocalDateTime é a ferramenta certa.

Combinando com LocalDate

Você frequentemente converterá para data com hora:

LocalDate date = LocalDate.of(2025, 11, 4);
LocalTime time = LocalTime.of(9, 30);

LocalDateTime dt = date.atTime(time);                         // 2025-11-04T09:30
LocalDateTime dt2 = time.atDate(date);                        // same thing

atTime / atDate são os métodos de ponte. O resultado é um LocalDateTime — ainda sem fuso horário, mas agora ancorado a um dia do calendário. O próximo capítulo aprofunda isso.

Um exemplo prático: um pequeno auxiliar de agendamento

O programa abaixo usa LocalTime para um tipo de tarefa de agenda diária: define uma janela de "horário de atendimento", verifica se um determinado momento cai dentro dela, calcula quanto tempo falta até a próxima abertura e demonstra o problema de rotação pela meia-noite.

java— editable, runs on the server

O que observar na execução:

  • LocalTime impresso como 09:00, 17:30, 12:30 — a forma canônica ISO-8601 de 24 horas. Sem AM/PM no tipo. Se você precisar exibir "5:30 PM" para um usuário, o capítulo Formatação de Datas tem o formatador para isso; o próprio tipo não conhece isso.
  • A verificação "o horário está dentro da janela" usou !isBefore(open) && !isAfter(close). Esse é o idioma de intervalo semi-aberto vs. fechado — ambos os extremos estão incluídos. Para "estritamente dentro", mude para as formas não negadas.
  • Duration.between(LocalTime.of(22, 0), LocalTime.of(2, 0)) retornou PT-20H, não PT4H. LocalTime não tem noção de "próximo dia" — quando end é anterior a start em termos de relógio, a duração fica negativa. Para um turno que cruza a meia-noite, mude as entradas para LocalDateTime e deixe as datas resolverem a ambiguidade. Esse é o maior ponto perigoso do LocalTime.
  • LocalTime.of(23, 30).plusHours(2) retornou 01:30. A rotação é silenciosa — sem exceção, sem sinalização, sem carry para a data. Se você precisar saber "isso deu a volta?", use LocalDateTime. Se você genuinamente quiser aritmética de relógio módulo 24 (uma agenda recorrente, por exemplo), a rotação é o comportamento correto.
  • date.atTime(time) foi a ponte canônica para LocalDateTime. O espelho time.atDate(date) produz o mesmo resultado. Você usará esses métodos constantemente ao ler um horário de uma fonte e uma data de outra, combinando-os no único objeto que a API downstream espera.

O que vem a seguir

O próximo capítulo, Java LocalDateTime, combina LocalDate e LocalTime no terceiro tipo "local": uma data e uma hora, ainda sem fuso horário anexado. Essa é a unidade natural para "isso aconteceu às 14:30 no dia 4 de novembro" quando o fuso horário é irrelevante ou registrado separadamente.

Prática

Prática
O que `LocalTime.of(23, 0).plusHours(3)` retorna e por quê?
O que `LocalTime.of(23, 0).plusHours(3)` retorna e por quê?
Was this page helpful?