CodeGym /Cursos /JAVA 25 SELF /Cálculos e comparação de datas, Duration, Period

Cálculos e comparação de datas, Duration, Period

JAVA 25 SELF
Nível 13, Lição 5
Disponível

1. Adição e subtração de datas e horas

No desenvolvimento, trabalhar com datas e horas — não é apenas “mostrar a data na tela”. Muitas vezes é preciso:

  • saber quantos dias faltam para um evento importante;
  • calcular a idade do usuário;
  • determinar quanto tempo se passou entre dois eventos;
  • verificar se o deadline já chegou;
  • adicionar à data uma quantidade de dias, semanas, meses ou horas.

Por exemplo, no nosso aplicativo queremos lembrar ao usuário que faltam 3 dias para o deadline da tarefa. Ou parabenizá-lo pelo aniversário que já passou (se a data já ficou no passado).

Para isso, em java.time há classes e métodos especiais que tornam esses cálculos simples e seguros.

Métodos básicos para somar e subtrair

Todos os tipos de data e hora (LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant) têm métodos:

  • plusXxx() — adicionar (dias, meses, anos, horas, minutos etc.)
  • minusXxx() — subtrair (idem)
import java.time.LocalDate;

LocalDate today = LocalDate.now(); // Data de hoje
LocalDate tomorrow = today.plusDays(1); // Amanhã
LocalDate nextMonth = today.plusMonths(1); // Daqui a um mês
LocalDate lastWeek = today.minusWeeks(1); // Uma semana atrás

System.out.println("Hoje: " + today);
System.out.println("Amanhã: " + tomorrow);
System.out.println("Daqui a um mês: " + nextMonth);
System.out.println("Uma semana atrás: " + lastWeek);

Todos esses métodos retornam um novo objeto, não alteram o original. Imutabilidade é tudo!

import java.time.LocalTime;

LocalTime now = LocalTime.now();
LocalTime inTwoHours = now.plusHours(2);
LocalTime tenMinutesAgo = now.minusMinutes(10);

System.out.println("Agora: " + now);
System.out.println("Daqui a 2 horas: " + inTwoHours);
System.out.println("Há 10 minutos: " + tenMinutesAgo);

Métodos combinados

LocalDate vacation = today.plusMonths(2).plusDays(10);
System.out.println("Férias: " + vacation);

2. Obtendo a diferença entre datas: Period e Duration

Quando precisamos saber quanto tempo passou entre duas datas ou instantes, entram em cena dois protagonistas — Period e Duration. Vamos conhecê-los melhor.

Qual é a diferença entre Period e Duration?

  • Period — para trabalhar com datas (ano, mês, dia). Ex.: “3 anos, 2 meses e 5 dias”.
  • Duration — para trabalhar com tempo (horas, minutos, segundos, nanossegundos). Ex.: “5 horas e 30 minutos”.
Classe Para que serve Exemplo de uso
Period
Diferença entre datas Quantos anos/meses/dias entre datas
Duration
Diferença entre instantes Quantas horas/minutos/segundos entre eventos

Exemplo: calculando a idade do usuário

import java.time.LocalDate;
import java.time.Period;

LocalDate birthday = LocalDate.of(2000, 1, 15); // Data de nascimento
LocalDate today = LocalDate.now();

Period age = Period.between(birthday, today);

System.out.println("Idade: " + age.getYears() + " anos, " +
                   age.getMonths() + " meses, " +
                   age.getDays() + " dias");

Analogia: Period é como uma diferença “humana” entre datas (“tenho 24 anos 5 meses e 12 dias”).

Exemplo: quanto tempo falta para o deadline

import java.time.LocalDate;

LocalDate deadline = LocalDate.of(2025, 7, 1);
LocalDate today = LocalDate.now();

if (today.isBefore(deadline)) {
    Period left = Period.between(today, deadline);
    System.out.println("Até o deadline faltam: " +
        left.getMonths() + " meses e " +
        left.getDays() + " dias");
} else {
    System.out.println("O deadline já passou!");
}

Duration: diferença no tempo

import java.time.LocalDateTime;
import java.time.Duration;

LocalDateTime start = LocalDateTime.of(2025, 6, 1, 10, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 1, 15, 30, 0);

Duration duration = Duration.between(start, end);

System.out.println("Duração: " + duration.toHours() + " horas " +
                   (duration.toMinutes() % 60) + " minutos");

Duration mede a diferença em segundos, minutos, horas, dias (mas dias — sempre de 24 horas, sem considerar peculiaridades do calendário).

Comparação: quando usar Period e quando usar Duration?

  • Se você tem apenas datas (sem horário), use Period.
  • Se você tem horário (por exemplo, LocalDateTime, Instant), use Duration.

3. Comparando datas e horas: isBefore, isAfter, equals

Às vezes só precisamos entender: a data já chegou ou ainda não? O evento está no passado ou no futuro? Para isso, todos os tipos de data e hora têm métodos:

  • isBefore(outraData)
  • isAfter(outraData)
  • isEqual(outraData) (ou simplesmente equals)
import java.time.LocalDate;

LocalDate today = LocalDate.now();
LocalDate deadline = LocalDate.of(2025, 7, 1);

if (today.isBefore(deadline)) {
    System.out.println("Ainda dá tempo!");
} else if (today.isEqual(deadline)) {
    System.out.println("Hoje é o deadline!");
} else {
    System.out.println("O deadline já passou :(");
}
import java.time.LocalTime;

LocalTime now = LocalTime.now();
LocalTime lunch = LocalTime.of(13, 0);

if (now.isAfter(lunch)) {
    System.out.println("O almoço já foi!");
} else {
    System.out.println("Ainda há tempo até o almoço.");
}

Importante: você só pode comparar objetos do mesmo tipo (LocalDate com LocalDate, LocalDateTime com LocalDateTime etc.).

4. Prática: exercícios de cálculo de diferenças e verificação de prazos

Exemplo: quantos dias faltam para o deadline da tarefa

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

LocalDate today = LocalDate.now();
LocalDate deadline = LocalDate.of(2025, 7, 1);

long daysLeft = ChronoUnit.DAYS.between(today, deadline);

if (daysLeft > 0) {
    System.out.println("Faltam " + daysLeft + " dias para o deadline");
} else if (daysLeft == 0) {
    System.out.println("Hoje é o deadline!");
} else {
    System.out.println("O deadline passou há " + Math.abs(daysLeft) + " dias");
}

ChronoUnit.DAYS.between() — uma forma prática de obter a quantidade exata de dias entre duas datas (sem considerar meses e anos).

Exemplo: quantos segundos entre dois eventos

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

LocalDateTime start = LocalDateTime.of(2025, 6, 1, 10, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 1, 15, 30, 0);

long seconds = ChronoUnit.SECONDS.between(start, end);

System.out.println("Entre os eventos se passaram " + seconds + " segundos");

Exemplo: calculando a idade de uma tarefa

import java.time.LocalDate;
import java.time.Period;

LocalDate created = LocalDate.of(2025, 5, 20);
LocalDate today = LocalDate.now();

Period period = Period.between(created, today);

System.out.println("A tarefa foi criada " +
    period.getDays() + " dias, " +
    period.getMonths() + " meses e " +
    period.getYears() + " anos atrás.");

Exemplo: duração entre dois Instant

import java.time.Instant;
import java.time.Duration;

Instant start = Instant.now();
// ... fazendo alguma coisa ...
Instant end = Instant.now();

Duration duration = Duration.between(start, end);

System.out.println("A execução levou " + duration.toMillis() + " milissegundos");

5. Particularidades no uso de Period e Duration

Particularidades do Period

  • Period calcula a diferença segundo o calendário: entre 28 de fevereiro e 1º de março — 1 dia, mesmo sendo meses diferentes.
  • É possível obter separadamente quantidades de anos, meses e dias: getYears(), getMonths(), getDays().
  • Se precisar do número total de dias entre datas — use ChronoUnit.DAYS.between().

Particularidades do Duration

  • Duration trabalha com tempo exato (horas, minutos, segundos).
  • Pode operar com LocalTime, LocalDateTime, Instant.
  • Não pode ser usado com datas sem horário (LocalDate) — lançará uma exceção.

Exemplo: diferença entre Period e Duration

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Duration;
import java.time.Period;

LocalDate date1 = LocalDate.of(2025, 2, 28);
LocalDate date2 = LocalDate.of(2025, 3, 1);

Period period = Period.between(date1, date2); // 2 dias (ano bissexto)
long days = java.time.temporal.ChronoUnit.DAYS.between(date1, date2); // 2 dias

System.out.println("Period: " + period.getDays() + " dias");
System.out.println("ChronoUnit: " + days + " dias");

LocalDateTime dt1 = LocalDateTime.of(2025, 6, 1, 23, 0);
LocalDateTime dt2 = LocalDateTime.of(2025, 6, 2, 1, 0);

Duration duration = Duration.between(dt1, dt2); // 2 horas
System.out.println("Duration: " + duration.toHours() + " horas");

6. Usando Duration e Period para exibir a diferença em um formato amigável

Quando você calcula a diferença entre datas ou horas para o usuário, nem sempre é conveniente mostrar “123456 segundos”. Normalmente queremos algo como “2 dias 3 horas 15 minutos”.

Exemplo: exibindo a diferença entre datas e horas

import java.time.LocalDateTime;
import java.time.Duration;

LocalDateTime start = LocalDateTime.of(2025, 6, 1, 14, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 3, 16, 30);

Duration duration = Duration.between(start, end);

long days = duration.toDays();
long hours = duration.minusDays(days).toHours();
long minutes = duration.minusDays(days).minusHours(hours).toMinutes();

System.out.println("Diferença: " + days + " dias " +
    hours + " horas " + minutes + " minutos");

7. Particularidades ao trabalhar com ZonedDateTime e Instant

  • A diferença entre dois ZonedDateTime em zonas diferentes é calculada pelo tempo absoluto, não pelo tempo “humano” em cada zona.
  • A mudança para horário de verão/inverno pode afetar a diferença em horas entre datas.

Exemplo: diferença entre ZonedDateTime

import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.Duration;

ZonedDateTime MinskTime = ZonedDateTime.of(2025, 6, 1, 12, 0, 0, 0, ZoneId.of("Europe/Minsk"));
ZonedDateTime nyTime = ZonedDateTime.of(2025, 6, 1, 5, 0, 0, 0, ZoneId.of("America/New_York"));

Duration diff = Duration.between(nyTime, MinskTime);
System.out.println("Diferença: " + diff.toHours() + " horas");

8. Erros comuns em cálculos com datas e horas

Erro nº 1: confundir Period e Duration.
Se você tentar usar Duration com LocalDate, receberá uma exceção. Para datas use Period; para tempo — Duration.

Erro nº 2: ignorar os fusos horários.
Ao comparar data e hora em fusos diferentes, você pode obter resultados inesperados. É melhor normalizar tudo para um mesmo fuso ou usar Instant.

Erro nº 3: esperar que os métodos plus/minus modifiquem o objeto.
Todos os tipos java.time são imutáveis! Não se esqueça de atribuir o resultado a uma nova variável (por exemplo, today = today.plusDays(1)).

Erro nº 4: usar getDays() de Period achando que é o total de dias.
Na verdade, ele retorna apenas os dias restantes após subtrair anos e meses. Para o total de dias, use ChronoUnit.DAYS.between().

Erro nº 5: comparar objetos de tipos diferentes.
Os métodos isBefore, isAfter, isEqual funcionam apenas para objetos do mesmo tipo (por exemplo, LocalDate com LocalDate).

1
Tarefa
JAVA 25 SELF, nível 13, lição 5
Bloqueado
Contagem regressiva para o feriado 🎉
Contagem regressiva para o feriado 🎉
1
Tarefa
JAVA 25 SELF, nível 13, lição 5
Bloqueado
Máquina do tempo: verificação se a data já chegou 🕰️
Máquina do tempo: verificação se a data já chegou 🕰️
1
Tarefa
JAVA 25 SELF, nível 13, lição 5
Bloqueado
Gestão de projetos: quantos dias faltam para o prazo? 🗓️
Gestão de projetos: quantos dias faltam para o prazo? 🗓️
1
Tarefa
JAVA 25 SELF, nível 13, lição 5
Bloqueado
Agência imobiliária: cálculo da idade do edifício 🏡
Agência imobiliária: cálculo da idade do edifício 🏡
1
Pesquisa/teste
Datas e tempo, nível 13, lição 5
Indisponível
Datas e tempo
Datas, tempo e timezones
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION