TemporalAdjuster in Java

1. Panoramica

In questo tutorial, daremo una rapida occhiata a TemporalAdjuster e lo useremo in alcuni scenari pratici.

Java 8 ha introdotto una nuova libreria per lavorare con date e orari: java.time e TemporalAdjuster ne fanno parte. Se vuoi saperne di più su java.time, controlla questo articolo introduttivo.

In poche parole, TemporalAdjuster è una strategia per la regolazione di un oggetto temporale . Prima di entrare nell'uso di TemporalAdjuster , diamo un'occhiata all'interfaccia temporale stessa.

2. Temporale

Un temporale definisce una rappresentazione di una data, ora o una combinazione di entrambi, a seconda dell'implementazione che utilizzeremo.

Esistono numerose implementazioni dell'interfaccia temporale , tra cui:

  • LocalDate - che rappresenta una data senza fuso orario
  • LocalDateTime - che rappresenta una data e un'ora senza un fuso orario
  • HijrahDate - che rappresenta una data nel sistema di calendario Hijrah
  • MinguoDate - che rappresenta una data nel sistema di calendario Minguo
  • ThaiBuddhistDate - che rappresenta una data nel sistema di calendario buddista thailandese

3. TemporalAdjuster

Una delle interfacce incluse in questa nuova libreria è TemporalAdjuster .

TemporalAdjuster è un'interfaccia funzionale che ha molte implementazioni predefinite nella classe TemporalAdjusters . L'interfaccia ha un unico metodo astratto chiamato AdjustInto () che può essere chiamato in una qualsiasi delle sue implementazioni passandole un oggetto Temporal .

TemporalAdjuster ci consente di eseguire complesse manipolazioni della data. Ad esempio , possiamo ottenere la data della domenica successiva, l'ultimo giorno del mese corrente o il primo giorno dell'anno successivo. Ovviamente possiamo farlo usando il vecchio java.util.Calendar .

Tuttavia, la nuova API astrae la logica sottostante utilizzando le sue implementazioni predefinite. Per ulteriori informazioni, visitare il Javadoc.

4. TemporalAdjusters predefiniti

La classe TemporalAdjusters ha molti metodi statici predefiniti che restituiscono un oggetto TemporalAdjuster per regolare gli oggetti Temporal in molti modi diversi, indipendentemente dall'implementazione di Temporal che potrebbero essere.

Ecco un breve elenco di questi metodi e una rapida definizione di essi:

  • dayOfWeekInMonth () - un regolatore per il giorno della settimana ordinale. Ad esempio la data del secondo martedì di marzo
  • firstDayOfMonth () - un regolatore per la data del primo giorno del mese corrente
  • firstDayOfNextMonth () - un regolatore per la data del primo giorno del mese successivo
  • firstDayOfNextYear () - un regolatore per la data del primo giorno dell'anno successivo
  • firstDayOfYear () - un regolatore per la data del primo giorno dell'anno corrente
  • lastDayOfMonth () - un regolatore per la data dell'ultimo giorno del mese corrente
  • nextOrSame () - un regolatore per la data della prossima occorrenza di uno specifico giorno della settimana o lo stesso giorno nel caso in cui oggi corrisponda al giorno della settimana richiesto

Come possiamo vedere, i nomi dei metodi sono praticamente autoesplicativi. Per altri TemporalAdjusters , visita il Javadoc.

Cominciamo con un semplice esempio : invece di usare una data specifica come negli esempi, possiamo usare LocalDate.now () per ottenere la data corrente dall'orologio di sistema.

Ma, per questo tutorial, useremo una data fissa in modo che i test non falliscano in seguito quando il risultato previsto cambia. Vediamo come possiamo usare la classe TemporalAdjusters per ottenere la data della domenica successiva all'8 luglio 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()); }

Ecco come possiamo ottenere l'ultimo giorno del mese corrente:

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

5. Definizione delle implementazioni personalizzate di TemporalAdjuster

Possiamo anche definire le nostre implementazioni personalizzate per TemporalAdjuster . Ci sono due modi diversi per farlo.

5.1. Utilizzo delle espressioni Lambda

Vediamo come possiamo ottenere la data che è di 14 giorni dopo l'8 luglio 2017 utilizzando il metodo Temporal.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()); }

In questo esempio, utilizzando un'espressione lambda, impostiamo l' oggetto temporalAdjuster per aggiungere 14 giorni all'oggetto localDate , che contiene la data (2017-07-08).

Vediamo come possiamo ottenere la data del giorno lavorativo subito dopo l'8 luglio 2017 definendo le nostre implementazioni di TemporalAdjuster utilizzando un'espressione lambda. Ma, questa volta, utilizzando il metodo factory statico ofDateAdjuster () :

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); });

Testare il nostro codice:

@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 l' interfaccia TemporalAdjuster

Vediamo come possiamo scrivere un TemporalAdjuster personalizzato che ottenga il giorno lavorativo successivo al 08/07/2017 implementando l' interfaccia TemporalAdjuster :

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); } }

Ora, eseguiamo il nostro test:

@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. Conclusione

In questo tutorial, abbiamo mostrato cos'è TemporalAdjuster , TemporalAdjuster predefiniti , come possono essere utilizzati e come possiamo implementare le nostre implementazioni TemporalAdjuster personalizzate in due modi diversi.

L'implementazione completa di questo tutorial può essere trovata su GitHub.