Como obter todas as datas entre duas datas?

Como obter todas as datas entre duas datas?

1. Visão geral

A nova API do Time introduzida no Java 8 tornou possível processar data e hora sem o uso de bibliotecas externas.

Neste breve tutorial, veremos como é fácil obter todas as datas entre duas datas ao longo do tempo em diferentes versões do Java.

2. Usando Java 7

No Java 7, uma maneira de calcular é usando a instânciaCalendar, executando um loop e adicionando 1 dia em cada iteração usando o método add e a unidade de campoCalendar.Date quando atinge a data de término.

Aqui está o código que demonstra isso - usando a instânciaCalendar:

public static List getDatesBetweenUsingJava7(
  Date startDate, Date endDate) {
    List datesInRange = new ArrayList<>();
    Calendar calendar = new GregorianCalendar();
    calendar.setTime(startDate);

    Calendar endCalendar = new GregorianCalendar();
    endCalendar.setTime(endDate);

    while (calendar.before(endCalendar)) {
        Date result = calendar.getTime();
        datesInRange.add(result);
        calendar.add(Calendar.DATE, 1);
    }
    return datesInRange;
}

3. Usando Java 8

No Java 8, podemos agora criar um infinitoStream contínuo de datas e pegar apenas a parte relevante. Infelizmente,there is no way of terminating an infinite Stream when a predicate gets matched - é por isso que precisamos calcular o número de dias entre esses dois dias e, em seguida, simplesmentelimit()aStream:

public static List getDatesBetweenUsingJava8(
  LocalDate startDate, LocalDate endDate) {

    long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate);
    return IntStream.iterate(0, i -> i + 1)
      .limit(numOfDaysBetween)
      .mapToObj(i -> startDate.plusDays(i))
      .collect(Collectors.toList());
}

Observe como, primeiro, podemos obter a diferença de dias entre duas datas usando a funçãobetween - associada à constanteDAYS da enumeraçãoChronoUnit.

Em seguida, criamos umStream de inteiros que representam o número de dias desde a data de início. Na próxima etapa, convertemos nossos inteiros em objetosLocalDate usando a APIplusDays().

Finalmente, coletamos tudo em uma instância de lista.

4. Usando Java 9

Por fim, o Java 9 traz métodos dedicados para calcular isso:

public static List getDatesBetweenUsingJava9(
  LocalDate startDate, LocalDate endDate) {

    return startDate.datesUntil(endDate)
      .collect(Collectors.toList());
}

Podemos obter as datas entre duas datas com uma única chamada de método usando o métododatesUntil dedicado de uma classeLocalDate. OdatesUntill retorna osStream ordenados sequencialmente de datas iniciando no objeto de data cujo método é chamado até a data fornecida como argumento do método.

5. Conclusão

Neste artigo rápido, vimos como podemos obter todas as datas entre duas datas usando as diferentes versões do Java.

Discutimos como a API Time introduzida na versão Java 8 tornou mais fácil executar operações em literais de data e em Java 9, isso pode ser feito apenas chamandodatesUntil.

E, como sempre, os trechos de código podem ser encontradosover on GitHub.