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:
| Campo | Significado | Intervalo |
|---|---|---|
Calendar.YEAR | Ano | ano completo, ex.: 2026 |
Calendar.MONTH | Mês | 0–11 (Janeiro = 0) |
Calendar.DAY_OF_MONTH | Dia do mês | 1–31 |
Calendar.DAY_OF_WEEK | Dia da semana | 1–7 (Domingo = 1) |
Calendar.HOUR_OF_DAY | Hora | 0–23 |
Calendar.MINUTE | Minuto | 0–59 |
Calendar.SECOND | Segundo | 0–59 |
Calendar.MILLISECOND | Milissegundo | 0–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-03roll 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.
O que observar na execução:
Calendar.MONTHpara maio imprime4. 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 deDate, 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 parajava.time.GregorianCalendar.from(ZonedDateTime)permite passar umCalendarde 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.