TemporalAdjuster em Java

TemporalAdjuster em Java

1. Visão geral

Neste tutorial, vamos dar uma olhada rápida emTemporalAdjustere usá-lo em alguns cenários práticos.

Java 8 introduziu uma nova biblioteca para trabalhar com datas e horas -java.timeeTemporalAdjuster faz parte dela. Se você quiser ler mais sobrejava.time,, marquethis introductory article.

Simplificando,TemporalAdjuster é uma estratégia para ajustar um objetoTemporal. Antes de entrar no uso deTemporalAdjuster, vamos dar uma olhada na própria interfaceTemporal.

2. Temporal

UmTemporal define uma representação de uma data, hora ou uma combinação de ambos, dependendo da implementação que vamos usar.

Existem várias implementações da interfaceTemporal, incluindo:

  • LocalDate - que representa uma data sem fuso horário

  • LocalDateTime - que representa uma data e hora sem fuso horário

  • HijrahDate - que representa uma data no sistema de calendário da Hégira

  • MinguoDate - que representa uma data no sistema de calendário Minguo

  • ThaiBuddhistDate - que representa uma data no sistema de calendário budista tailandês

3. TemporalAdjuster

Uma das interfaces incluídas nesta nova biblioteca éTemporalAdjuster.

TemporalAdjuster é uma interface funcional que possui muitas implementações predefinidas na classeTemporalAdjusters. A interface tem um único método abstrato denominadoadjustInto() que pode ser chamado em qualquer uma de suas implementações passando um objetoTemporal para ela.

TemporalAdjuster nos permite realizar manipulações de datas complexas. For example, podemos obter a data do próximo domingo, o último dia do mês atual ou o primeiro dia do próximo ano. Podemos, é claro, fazer isso usando o antigojava.util.Calendar.

No entanto, a nova API abstrai a lógica subjacente usando suas implementações predefinidas. Para obter mais informações, visiteJavadoc.

4. TemporalAdjusters predefinido

A classeTemporalAdjusters tem muitos métodos estáticos predefinidos que retornam um objetoTemporalAdjuster para ajustar objetosTemporal de muitas maneiras diferentes, não importa qual implementação deTemporal eles possam ser.

Aqui está uma pequena lista desses métodos e uma definição rápida deles:

  • dayOfWeekInMonth() - um ajustador para o dia da semana ordinal. Por exemplo, a data da segunda terça-feira de março

  • firstDayOfMonth() - um ajustador para a data do primeiro dia do mês atual

  • firstDayOfNextMonth() - um ajustador para a data do primeiro dia do próximo mês

  • firstDayOfNextYear() - um ajustador para a data do primeiro dia do próximo ano

  • firstDayOfYear() - um ajustador para a data do primeiro dia do ano atual

  • lastDayOfMonth() - um ajustador para a data do último dia do mês atual

  • nextOrSame() - um ajustador para a data da próxima ocorrência de um dia da semana específico ou o mesmo dia no caso de hoje corresponder ao dia da semana exigido

Como podemos ver, os nomes dos métodos são praticamente auto-explicativos. Para maisTemporalAdjusters, visiteJavadoc.

Let’s start with a simple example - em vez de usar uma data específica como nos exemplos, podemos usarLocalDate.now() para obter a data atual do relógio do sistema.

Mas, para este tutorial, vamos usar uma data fixa para que os testes não falhem mais tarde, quando o resultado esperado mudar. Vamos ver como podemos usar a classeTemporalAdjusters para obter a data do domingo após 08-07-2017:

@Test
public void whenAdjust_thenNextSunday() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    LocalDate nextSunday = localDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));

    String expected = "2017-07-09";

    assertEquals(expected, nextSunday.toString());
}

Veja como podemos obter o último dia do mês atual:

LocalDate lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth());

5. Definindo Implementações deTemporalAdjuster personalizadas

Também podemos definir nossas implementações personalizadas paraTemporalAdjuster. Existem duas maneiras diferentes de fazer isso.

5.1. Usando Expressões Lambda

Vejamos como podemos obter a data que é 14 dias após 08/07/2017 usando o métodoTemporal.with():

@Test
public void whenAdjust_thenFourteenDaysAfterDate() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    TemporalAdjuster temporalAdjuster = t -> t.plus(Period.ofDays(14));
    LocalDate result = localDate.with(temporalAdjuster);

    String fourteenDaysAfterDate = "2017-07-22";

    assertEquals(fourteenDaysAfterDate, result.toString());
}

Neste exemplo, usando uma expressão lambda, definimos o objetotemporalAdjuster para adicionar 14 dias ao objetolocalDate, que contém a data (2017-07-08).

Vamos ver como podemos obter a data do dia útil logo após 08/07/2017, definindo nossas próprias implementações deTemporalAdjuster usando uma expressão lambda. Mas, desta vez, usando o método de fábrica estáticoofDateAdjuster():

static TemporalAdjuster NEXT_WORKING_DAY = TemporalAdjusters.ofDateAdjuster(date -> {
    DayOfWeek dayOfWeek = date.getDayOfWeek();
    int daysToAdd;
    if (dayOfWeek == DayOfWeek.FRIDAY)
        daysToAdd = 3;
    else if (dayOfWeek == DayOfWeek.SATURDAY)
        daysToAdd = 2;
    else
        daysToAdd = 1;
    return today.plusDays(daysToAdd);
});

Testando nosso código:

@Test
public void whenAdjust_thenNextWorkingDay() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    TemporalAdjuster temporalAdjuster = NEXT_WORKING_DAY;
    LocalDate result = localDate.with(temporalAdjuster);

    assertEquals("2017-07-10", date.toString());
}

5.2. Implementando a interfaceTemporalAdjuster

Vamos ver como podemos escrever umTemporalAdjuster personalizado que obtém o dia útil após 08-07-2017 implementando a interfaceTemporalAdjuster:

public class CustomTemporalAdjuster implements TemporalAdjuster {

    @Override
    public Temporal adjustInto(Temporal temporal) {
        DayOfWeek dayOfWeek
          = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));

        int daysToAdd;
        if (dayOfWeek == DayOfWeek.FRIDAY)
            daysToAdd = 3;
        else if (dayOfWeek == DayOfWeek.SATURDAY)
            daysToAdd = 2;
        else
            daysToAdd = 1;
        return temporal.plus(daysToAdd, ChronoUnit.DAYS);
    }
}

Agora, vamos fazer nosso teste:

@Test
public void whenAdjustAndImplementInterface_thenNextWorkingDay() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    CustomTemporalAdjuster temporalAdjuster = new CustomTemporalAdjuster();
    LocalDate nextWorkingDay = localDate.with(temporalAdjuster);

    assertEquals("2017-07-10", nextWorkingDay.toString());
}

6. Conclusão

Neste tutorial, mostramos o queTemporalAdjuster é,TemporalAdjusters, predefinido como eles podem ser usados ​​e como podemos implementar nossas implementaçõesTemporalAdjuster personalizadas de duas maneiras diferentes.

A implementação completa deste tutorial pode ser encontradaover on GitHub.