Operare con le date in Java

In Java per memorizzare una data è possibile utilizzare un oggetto di classe Date. Un oggetto di questa classe tratta una data come un istante di tempo con una precisione del millisecondo e la rappresenta con il numero di millisecondi che la separano dalla data del 1 gennaio 1970, assunta come riferimento. Questo numero intero (di tipo long) è positivo per le date successive a quella di riferimento e negativo per le date anteriori.

Il modo più semplice per creare un oggetto di classe Date che contiene la data corrente è il seguente:

ossia richiamando il costruttore della classe Date senza alcun parametro. Si faccia attenzione perché altri suoi costruttori, così come molti suoi metodi, sono deprecati e nei nuovi progetti non devono essere utilizzati. Per questo motivo per operare correttamente con un oggetto di classe Date, bisogna farlo utilizzando altre classi, quali: DateFormat, CalendarSimpleDateFormat. In questo articolo illustrerò solo alcune semplici soluzioni che utilizzano queste classi per realizzare le operazioni più comuni sulle date. Per approfondimenti si rimanda alla documentazione del linguaggio Java presente on line (link) e che viene da me utilizzata come fonte di questo articolo.

La classe DateFormat

Questa classe può essere utile per ottenere la conversione di una data di classe Date in una stringa di testo adatta per la visualizzazione e viceversa, consentendo allo stesso tempo di utilizzare diversi stili di visualizzazione, attraverso l’uso di quattro constanti definite nella stessa classe. Le costanti degli stili di visualizzazione di una data sono quelle riportate nella prima colonna della tabella seguente, che riporta anche gli esempi dei diversi formati di data corrispondenti:

Stile Esempio
SHORT 05/03/17
MEDIUM 5-mar-2017
LONG 5 marzo 2017
FULL domenica 5 marzo 2017

Della classe DateFormat sono molto utili i seguenti metodi:

  • DateFormat getDateInstance(int stile, Locale unLocale)  – metodo statico che istanzia un oggetto di classe DateFormat secondo un fissato stile di visualizzazione della data; richiede due parametri: il primo imposta lo stile (vedi tabella precedente), il secondo imposta la localizzazione (vedi esempi seguenti).
  • String format(Date data) – converte un oggetto di classe Date, che richiede come parametro, in una data sotto forma di una stringa (String), che restituisce al chiamante.
  • Date parse(String data) – converte una data fornita come String, che richiede come parametro, in un oggetto di classe Date, che restituisce al chiamante. Se la stringa  non può essere convertita lancia un’eccezione di classe ParseException. Affinché però nella conversione questo metodo possa segnalare in maniera rigorosa tutti gli errori, è necessario impostare opportunamente il metodo setLenient().
  • void setLenient(boolean clemente) – imposta il tipo di controlli da effettuare durante la conversione di una stringa in un oggetto di classe Date e quindi se segnalare o meno alcuni errori di conversione. Richiede un parametro booleano da impostare su false se si vuole che il metodo parse() non sia clemente, ma al contrario rigoroso, nel calcolo e quindi conversione della data (es. non accetterà una data del tipo 31/02/2017, che per default invece viene accettata e interpretata come 03/04/2017, o un orario del tipo 25:30, che per default viene accettato e interpretato come 01:30 del giorno successivo).

(Visualizzare un data in output)

Il seguente spezzone di codice istanzia un oggetto Date con la data corrente e la visualizza a video nel formato LONG:

Nel codice dell’esempio precedente è stato sfruttato il metodo format() per convertire un oggetto di classe Date in una stringa formattata.

Il seguente programma invece istanzia un oggetto Date con la data corrente e la visualizza prima senza alcuna formattazione e poi in tutti i diversi formati messi a disposizione dalla classe DateFormat:

Il codice produce un output simile a questo:

Mon Mar 20 14:41:32 CET 2017
20/03/17
20-mar-2017
20 marzo 2017
lunedì 20 marzo 2017

(Procurarsi una data in input)

Il  codice seguente esegue il viceversa del precedente, ossia si procura in input da tastiera una data sotto forma di stringa e la converte in un oggetto di classe Date; successivamente la stampa senza formattarla:

In corrispondenza di due input diversi, il codice precedente produce un output simile a questo:

  1. Inserisci la data [gg/mm/yyyy]:
    5/8/80
    Tue Aug 05 00:00:00 CEST 1980
  2. Inserisci la data [gg/mm/yyyy]:
    5/8/1780
    Sat Aug 05 00:00:00 CET 1780

Si noti la differenza tra l’interpretazione di date successive e anteriori al 1 gennaio 1970.

La classe Calendar

La classe Calendar viene introdotta qui per mostrare come effettuare delle operazioni aritmetiche su una data. Della classe Calendar prendiamo in considerazione solo i metodi che ci serviranno a questo scopo. Per approfondire lo studio di questa classe si rimanda alla documentazione del linguaggio Java presente on line (link).

Un oggetto di classe Calendar può essere istanziato a partire da un oggetto di classe Date, sfruttando il metodo statico getInstance() e il metodo setTime() della classe Calendar, nel modo seguente:

nell’ esempio si è partiti dall’oggetto di classe Date della data corrente.

Un metodo alternativo può essere quello che sfrutta il metodo getCalendar() di un oggetto di classe DateFormat nel modo seguente:

Della classe Calendar saranno utili i seguenti metodi:

  • void setTime(Date data) – imposta la data dell’oggetto di classe Calendar uguale alla data di un oggetto di classe Date fornito come parametro.
  • Date getTime() – restituisce un oggetto di classe Date con la data dell’oggetto di classe Calendar su cui il metodo viene richiamato.
  • void add(int campo, int quantità) – somma al campo dell’oggetto di classe Calendar, passato come primo parametro, la quantità intera passata come secondo parametro che può essere anche un intero negativo (vedi esempio sotto).

(Sommare o sottrarre ad una data un intervallo di tempo)

Con un oggetto di classe Calendar, per il quale sono definiti i valori dei campi anno, mese e giorni utilizzabili attraverso alcuni attributi statici (per approfondire consulta la documentazione del linguaggio Java: link), è possibile sommare o sottrarre alla sua data  un certo intervallo di tempo nel modo seguente.

Nell’esempio precedente dopo esserci procurati una data in input dalla tastiera, le abbiamo sommato 10 anni e 6 mesi e l’abbiamo visualizzata a video come stringa nel formato SHORT.

La classe SimpleDateFormat

La classe SimpleDateFormat è una classe derivata dalla classe DateFormat. Essa, quindi, eredita i metodi pubblici della superclasse, ai quali si aggiungono i propri.  Questa classe rispetto alla superclasse, fornisce molta flessibilità sul formato delle date, permettendo di creare dei formati a piacere (pattern), tramite la costruzione di stringhe ottenute utilizzando combinazioni di opportune lettere. Per approfondimenti su questa classe come al solito si rimanda alla documentazione del linguaggio Java presente on line (link). Qui vedremo un semplice esempio in cui preleviamo in input da tastiera una data secondo un certo formato (pattern) da noi creato e subito dopo la visualizziamo a video in un altro formato sempre creato da noi. Il tutto è inserito all’interno di un ciclo che termina quando l’inserimento della data è andato a buon fine.

L’esecuzione del programma precedente in corrispondenza di un input valido produce a video un risultato simile al seguente:

Inserisci la data [gg/mm/yy HH:mm]:
20/03/17 9:30
OUTPUT: alle ore 09:30 del 20/03/2017