Introdução ao trabalho com datas e horas em Java
Trabalhar com datas e horas é uma das tarefas mais comuns no desenvolvimento. Seja para registro de eventos, cálculo de prazos, filtragem de dados ou exibição de calendários — não é possível prescindir de um domínio seguro das APIs temporais. Em Java, por muito tempo, foram usadas as classes java.util.Date e java.util.Calendar, mas elas tinham muitas desvantagens: mutabilidade, API não intuitiva, problemas com threads.
A partir do Java 8, um novo pacote java.time foi adicionado à linguagem, baseado no padrão ISO-8601. Ele oferece classes immutable (imutáveis) e thread-safe, que são muito mais convenientes de usar. Neste artigo, vamos abordar tanto as abordagens antigas quanto as novas, além de mostrar exemplos práticos de código.
1. Classes legadas: Date e Calendar
Apesar de o uso de Date e Calendar não ser recomendado em novos projetos, você pode encontrá-los em código legado. Vamos analisar os pontos principais.
Classe java.util.Date
A classe Date representa um momento específico no tempo com precisão de milissegundos. Ela tem muitos métodos obsoletos.
import java.util.Date;
public class DateExample { public static void main(String[] args) { // Data e hora atuais Date now = new Date(); System.out.println("Hora atual: " + now);
// Construtor com milissegundos (desde 1 de janeiro de 1970) Date specificDate = new Date(1000000000000L); System.out.println("Data: " + specificDate);
// Comparação de datas boolean after = now.after(specificDate); System.out.println("now depois de specificDate? " + after); }}Classe java.util.Calendar
Calendar é uma classe mais flexível, mas ainda inconveniente para manipulação de datas.
import java.util.Calendar;
public class CalendarExample { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); // Definindo uma data específica cal.set(2025, Calendar.MARCH, 15, 10, 30, 0); System.out.println("Data definida: " + cal.getTime());
// Obtendo campos individuais int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH) + 1; // Meses começam em 0 int day = cal.get(Calendar.DAY_OF_MONTH); System.out.println("Ano: " + year + ", Mês: " + month + ", Dia: " + day);
// Adicionando dias cal.add(Calendar.DAY_OF_MONTH, 10); System.out.println("Daqui a 10 dias: " + cal.getTime()); }}Desvantagens: mutabilidade (os métodos alteram o próprio objeto), complexidade ao trabalhar com fusos horários, confusão com índices de meses.
2. API moderna: java.time (Java 8+)
O pacote java.time resolve todos os problemas das classes antigas. Principais classes:
- LocalDate — data sem hora (ano, mês, dia);
- LocalTime — hora sem data (horas, minutos, segundos, nanossegundos);
- LocalDateTime — data e hora sem fuso horário;
- ZonedDateTime — data e hora com fuso horário;
- Instant — momento no tempo em UTC;
- Duration e Period — para trabalhar com intervalos de tempo.
LocalDate — trabalhando com datas
import java.time.LocalDate;import java.time.Month;
public class LocalDateExample { public static void main(String[] args) { // Data atual LocalDate today = LocalDate.now(); System.out.println("Hoje: " + today);
// Data específica LocalDate specific = LocalDate.of(2025, Month.DECEMBER, 25); System.out.println("Natal: " + specific);
// Adicionando dias LocalDate nextWeek = to