W3docs

Java TemporalAdjusters

Calcule datas relativas em Java com TemporalAdjusters — firstDayOfMonth, next, previous.

plusDays(7) adiciona sete dias. withDayOfMonth(15) salta para o dia 15. Esses dois cobrem os casos simples. Um TemporalAdjuster é um objeto com formato de função que você passa para Temporal.with(adjuster) para lidar com os casos em que a nova data depende da data atual de forma mais complexa: "a primeira segunda-feira do próximo mês," "o último dia deste trimestre," "o Dia de Ação de Graças americano do próximo ano."

A interface tem um único método:

@FunctionalInterface
interface TemporalAdjuster {
  Temporal adjustInto(Temporal temporal);
}

Normalmente você não a implementa. A classe java.time.temporal.TemporalAdjusters (note o sAdjusters, plural) é um kit com cerca de uma dúzia de ajustadores integrados que cobrem os casos comuns, e LocalDate.with(adjuster) é como você os aplica.

O catálogo integrado

Importe estaticamente; o código fica mais legível assim:

import static java.time.temporal.TemporalAdjusters.*;

Em seguida:

AjustadorEfeito
firstDayOfMonth()dia → primeiro dia do mesmo mês
lastDayOfMonth()dia → último dia do mesmo mês
firstDayOfNextMonth()dia → primeiro dia do próximo mês
firstDayOfYear()dia → 1º de janeiro do mesmo ano
lastDayOfYear()dia → 31 de dezembro do mesmo ano
firstDayOfNextYear()dia → 1º de janeiro do próximo ano
next(DayOfWeek dow)o próximo dow estritamente após a data
nextOrSame(DayOfWeek dow)hoje se for dow, caso contrário o próximo dow
previous(DayOfWeek dow)o dow mais recente estritamente antes da data
previousOrSame(DayOfWeek dow)hoje se for dow, caso contrário o dow anterior
dayOfWeekInMonth(int ord, DayOfWeek dow)n-ésimo dia da semana do mês: dayOfWeekInMonth(3, MONDAY) → 3ª segunda-feira
firstInMonth(DayOfWeek dow)primeiro dow do mês (equivalente a dayOfWeekInMonth(1, dow))
lastInMonth(DayOfWeek dow)último dow do mês

As duas metades respondem "qual é o primeiro/último X" (metade superior) e "qual é o próximo/anterior X" (metade inferior). Encadeie-os quando a questão for mais complexa:

LocalDate firstMondayNextMonth = today.with(firstDayOfNextMonth()).with(nextOrSame(DayOfWeek.MONDAY));

Isso significa "a primeira segunda-feira em ou após o primeiro dia do próximo mês." Leia da esquerda para a direita; cada with é um passo.

Aplicar com with(adjuster)

LocalDate today = LocalDate.now();
LocalDate eom = today.with(lastDayOfMonth());
LocalDate nextMonday = today.with(next(DayOfWeek.MONDAY));
LocalDate thirdFriday = today.with(dayOfWeekInMonth(3, DayOfWeek.FRIDAY));

with existe em todo Temporal: LocalDate, LocalDateTime, ZonedDateTime, até OffsetDateTime. O ajustador toca apenas os componentes de data — aplicar lastDayOfMonth() a um LocalDateTime deixa o horário intacto.

Os ajustadores são totais: sempre retornam um resultado. Não há caminho de exceção "e se hoje não estiver no mês certo" — lastDayOfMonth() a partir de 31 de janeiro ainda é 31 de janeiro (o último dia é ele mesmo).

Ajustadores lambda

Como TemporalAdjuster é uma @FunctionalInterface, você pode escrever o seu próprio com uma lambda:

TemporalAdjuster nextWorkingDay = t -> {
  LocalDate d = LocalDate.from(t).plusDays(1);
  while (d.getDayOfWeek() == DayOfWeek.SATURDAY || d.getDayOfWeek() == DayOfWeek.SUNDAY) {
    d = d.plusDays(1);
  }
  return d;
};

LocalDate friday = LocalDate.of(2025, 11, 7);
LocalDate monday = friday.with(nextWorkingDay);                 // 2025-11-10

O padrão: converta o Temporal recebido para o tipo de data desejado (LocalDate.from(t)), calcule a nova data, retorne-a. O tipo de retorno é Temporal (a interface), mas o JDK aceita o retorno concreto.

Para uso pontual, isso é exagero — basta embutir a lógica próxima ao local da chamada. Para um cálculo que você usará em vários lugares (próximo dia útil, último dia do trimestre, feriado observado), encapsulá-lo como um ajustador mantém os locais de chamada legíveis.

ofDateAdjuster para o caso lambda simples

Se o seu ajustador funciona apenas com LocalDate (o caso comum), TemporalAdjusters.ofDateAdjuster(UnaryOperator<LocalDate>) é a fábrica mais limpa:

TemporalAdjuster nextWorkingDay = TemporalAdjusters.ofDateAdjuster(d -> {
  LocalDate result = d.plusDays(1);
  while (result.getDayOfWeek().getValue() > 5) {
    result = result.plusDays(1);
  }
  return result;
});

A lambda recebe e retorna um LocalDate. A fábrica o encapsula como um TemporalAdjuster. É isso que você usa em 90% das vezes ao escrever ajustadores personalizados.

Um exemplo trabalhado: datas comerciais, feriados, fim de período

O programa abaixo usa ajustadores para o calendário contábil: fim de mês para faturamento, último dia útil do mês para fechamento de caixa, a primeira segunda-feira do próximo mês para uma reunião regular de planejamento, um ajustador "próximo dia útil" com consciência de feriados, e cálculo de fim de trimestre.

java— editable, runs on the server

O que observar na execução:

  • Os ajustadores integrados cobriram os casos de limite (firstDayOfMonth, lastDayOfMonth, firstDayOfYear, etc.) sem nenhuma aritmética da sua parte. Para "esta data ajustada ao início/fim do seu mês ou ano," eles são a ferramenta certa — mais claros do que computações manuais no estilo withDayOfMonth(1), e imunes a surpresas com o comprimento do mês.
  • next(MONDAY) e previous(FRIDAY) retornaram datas estritamente diferentes; nextOrSame(TUESDAY) em uma terça-feira retornou hoje. Memorize a distinção estrito-vs-ou-mesmo; ela é a fonte da maioria dos bugs de "uma semana de diferença" quando a data de início cai no dia da semana alvo.
  • O encadeamento firstDayOfNextMonth().nextOrSame(MONDAY) expressou "a primeira segunda-feira em ou após o primeiro dia do próximo mês" em duas leituras. O encadeamento é uma linha; o equivalente manual são seis. Encadear ajustadores é a forma idiomática de compô-los.
  • NEXT_BUSINESS_DAY pulou o fim de semana e um feriado de uma vez. O conjunto HOLIDAYS foi um exemplo sintético de dois elementos; uma implementação real carregaria a partir de um serviço. A forma do ajustador é a mesma — envolva o laço em TemporalAdjusters.ofDateAdjuster(...) e você pode usar today.with(NEXT_BUSINESS_DAY) em qualquer lugar.
  • END_OF_QUARTER foi um ajustador personalizado de uma linha que selecionou o terceiro mês do trimestre da data e aplicou lastDayOfMonth(). O ponto: operações de domínio complexas pertencem a constantes nomeadas TemporalAdjuster, onde o local de chamada lê someDate.with(END_OF_QUARTER) em vez de embutir um bloco aritmético de seis linhas. Mantenha a lógica do calendário em um único lugar.

O que vem a seguir

TemporalAdjusters encerram a API moderna java.time. Os dois últimos capítulos desta parte cobrem os tipos legados que você encontrará em código mais antigo: Java Legacy Date Class para o java.util.Date original, e Java Calendar Class para java.util.Calendar. Ambos ainda existem por compatibilidade; ambos têm um caminho de conversão limpo para java.time.

Prática

Prática
Você precisa de 'a primeira segunda-feira do próximo mês' a partir de qualquer data fornecida. Qual expressão retorna esse valor de forma mais idiomática?
Você precisa de 'a primeira segunda-feira do próximo mês' a partir de qualquer data fornecida. Qual expressão retorna esse valor de forma mais idiomática?
Was this page helpful?