W3docs

Classe Calendar do Java

A classe legada java.util.Calendar e GregorianCalendar — como se relacionam com java.time.

java.util.Calendar é a segunda metade do par legado de data/hora. Onde java.util.Date é apenas um wrapper em torno de um long de milissegundos de época, Calendar é o que sabe em que ano, mês e dia esse milissegundo cai. Foi adicionado no Java 1.1 para remover a aritmética de calendário do Date — é por isso que a maioria dos acessores de campo do Date está depreciada.

No código moderno, você deve recorrer ao java.time. Mas Calendar ainda aparece: em caminhos de código antigos, em bibliotecas escritas antes do Java 8 e em drivers JDBC que não foram atualizados. Você precisa lê-lo, fazer a ponte e seguir em frente. Esta página explica como criar um Calendar, ler seus campos com segurança (cuidado com o mês base zero), fazer aritmética de calendário e — o mais importante — conectá-lo à API moderna.

Calendar é abstrato

Calendar em si é uma classe abstrata. Você nunca chama new Calendar(...). Você obtém uma instância por meio da fábrica:

Calendar cal = Calendar.getInstance();

Isso retorna uma subclasse concreta — quase sempre GregorianCalendar — pré-carregada com a hora atual, o fuso horário padrão e o locale padrão. Você pode ser explícito se precisar:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);

GregorianCalendar também tem construtores públicos, mas a fábrica é a convenção.

Constantes de campo

Calendar expõe tudo por meio de constantes de campo inteiras e um get(int field) genérico:

CampoSignificadoIntervalo
Calendar.YEARAnoano completo, ex.: 2026
Calendar.MONTHMês0–11 (Janeiro = 0)
Calendar.DAY_OF_MONTHDia do mês1–31
Calendar.DAY_OF_WEEKDia da semana1–7 (Domingo = 1)
Calendar.HOUR_OF_DAYHora0–23
Calendar.MINUTEMinuto0–59
Calendar.SECONDSegundo0–59
Calendar.MILLISECONDMilissegundo0–999

Dois perigos estão nessa tabela: MONTH é base zero (Calendar.JANUARY == 0) e DAY_OF_WEEK começa no domingo. Erros de off-by-one em código legado quase sempre rastreiam de volta aqui.

Definição e aritmética

set recebe um campo e um valor; add faz aritmética consciente de calendário que propaga o estouro para campos maiores:

Calendar cal = Calendar.getInstance();
cal.set(2026, Calendar.MAY, 29);   // Y, M, D — month is zero-based
cal.add(Calendar.DAY_OF_MONTH, 5); // → 2026-06-03

roll faz o mesmo campo a campo, mas não propaga para campos maiores — roll(DAY_OF_MONTH, 5) em 30 de maio dá 4 de maio, não 4 de junho. Raramente é o que você quer.

Instâncias de Calendar são mutáveis, portanto passar uma para um método significa entregar um handle ativo. Clone antes de expor, da mesma forma que faria com um Date.

A ponte para java.time

O único motivo de tocar em Calendar hoje é para sair dele. Dois métodos fazem isso:

Instant when = cal.toInstant();
ZoneId  zone = cal.getTimeZone().toZoneId();
ZonedDateTime zdt = when.atZone(zone);

A partir de ZonedDateTime você tem toda a API moderna. Fazendo o caminho inverso:

Calendar cal = GregorianCalendar.from(zdt); // Java 8+

GregorianCalendar.from(ZonedDateTime) é a conversão suportada. Evite fazer round-trip por meio de Date.

Exemplo prático

O exemplo abaixo mostra as duas coisas que você fará com Calendar em código real: ler campos de uma instância legada e fazer a ponte para java.time para qualquer coisa não trivial.

java— editable, runs on the server

O que observar na execução:

  • Calendar.MONTH para maio imprime 4. Meses base zero são a maior fonte de bugs em código legado de datas.
  • getInstance(TimeZone) vincula a instância a um fuso horário — diferente de Date, que não tem nenhum.
  • add(MONTH, 1) entende o comprimento do mês; você obtém o dia correto no mês seguinte mesmo que os meses não tenham todos 30 dias.
  • cal.toInstant().atZone(cal.getTimeZone().toZoneId()) é a ponte de uma linha para java.time.
  • GregorianCalendar.from(ZonedDateTime) permite passar um Calendar de volta para uma API antiga sem perder o fuso horário.

O que vem a seguir

Isso encerra a Parte 14 — Data e Hora. A próxima é a Parte 15, Multithreading e Concorrência, começando com Multithreading em Java — o modelo que moldou todas as outras APIs deste livro.

Prática
Um Calendar definido para 29 de maio de 2026 reporta cal.get(Calendar.MONTH). Qual valor é retornado?
Um Calendar definido para 29 de maio de 2026 reporta cal.get(Calendar.MONTH). Qual valor é retornado?
Was this page helpful?