Classi per il Tempo e le Date in Java

Concetti Chiave
  • Le classi Date, Calendar, GregorianCalendar, TimeZone e SimpleTimeZone sono utilizzate per gestire date e orari in Java.
  • La classe Date rappresenta un momento specifico nel tempo, ma non fornisce metodi per ottenere i componenti della data e dell'ora.
  • La classe Calendar fornisce metodi per ottenere i componenti della data e dell'ora, come anno, mese, giorno, ora, minuto e secondo.
  • La classe GregorianCalendar estende Calendar e fornisce funzionalità specifiche per il calendario gregoriano.
  • La classe TimeZone rappresenta un fuso orario e fornisce metodi per ottenere informazioni sul fuso orario corrente.
  • La classe SimpleTimeZone è una sottoclasse di TimeZone che implementa i metodi astratti e calcola l'ora legale.
  • Le classi per il tempo e le date sono fondamentali per la gestione di operazioni temporali, come la pianificazione di eventi e la registrazione di timestamp.

La classe Date per memorizzare una data e un'ora

La classe Date incapsula la data e l'ora correnti.

Prima di iniziare il nostro esame di Date, è importante sottolineare che è cambiata sostanzialmente dalla sua versione originale definita da Java 1.0. Quando Java 1.1 è stato rilasciato, molte delle funzioni svolte dalla classe Date originale sono state spostate nelle classi Calendar e DateFormat, e di conseguenza, molti dei metodi originali 1.0 di Date sono stati deprecati. Poiché i metodi 1.0 deprecati non dovrebbero essere utilizzati per nuovo codice, non sono descritti qui.

Metodo Descrizione
boolean after(Date data) Restituisce true se l'oggetto Date invocante contiene una data che è successiva a quella specificata da data. Altrimenti, restituisce false.
boolean before(Date data) Restituisce true se l'oggetto Date invocante contiene una data che è precedente a quella specificata da data. Altrimenti, restituisce false.
Object clone() Duplica l'oggetto Date invocante.
int compareTo(Date data) Confronta il valore dell'oggetto invocante con quello di data. Restituisce 0 se i valori sono uguali. Restituisce un valore negativo se l'oggetto invocante è precedente a data. Restituisce un valore positivo se l'oggetto invocante è successivo a data.
boolean equals(Object data) Restituisce true se l'oggetto Date invocante contiene la stessa ora e data di quella specificata da data. Altrimenti, restituisce false.
static Date from(Instant t) Restituisce un oggetto Date corrispondente all'oggetto Instant passato in t.
long getTime() Restituisce il numero di millisecondi che sono trascorsi dal 1° gennaio 1970.
int hashCode() Restituisce un codice hash per l'oggetto invocante.
void setTime(long tempo) Imposta l'ora e la data come specificato da tempo, che rappresenta un tempo trascorso in millisecondi dalla mezzanotte del 1° gennaio 1970.
Instant toInstant() Restituisce un oggetto Instant corrispondente all'oggetto Date invocante.
String toString() Converte l'oggetto Date invocante in una stringa e restituisce il risultato.
Tabella 1: Metodi della classe Date.

La classe Date supporta i seguenti costruttori:

Date()
Date(long millisecondi)

Il primo costruttore inizializza l'oggetto con la data e l'ora correnti. Il secondo costruttore accetta un argomento che equivale al numero di millisecondi che sono trascorsi dalla mezzanotte del 1° gennaio 1970. La classe Date implementa anche l'interfaccia Comparable.

Come si può vedere esaminando la tabella di sopra, le caratteristiche di Date non permettono di ottenere i componenti individuali della data o dell'ora.

Come dimostra il seguente programma, si può solo ottenere la data e l'ora in termini di millisecondi, nella sua rappresentazione stringa predefinita come restituita da toString(), o come oggetto Instant. Per ottenere informazioni più dettagliate sulla data e sull'ora, useremo la classe Calendar.

// Mostra data e ora usando solo i metodi Date.
import java.util.Date;

class DemoData {

    public static void main(String[] args) {
        // Istanzia un oggetto Date
        Date data = new Date();

        // visualizza ora e data usando toString()
        System.out.println(data);

        // Visualizza il numero di millisecondi dalla mezzanotte del 1° gennaio 1970 GMT
        long millisecondi = data.getTime();
        System.out.println("Millisecondi dal 1° gen. 1970 GMT = " + millisecondi);
    }

}

L'output di esempio è mostrato qui:

Mon Jul 21 17:39:34 CEST 2025
Millisecondi dal 1° gen. 1970 GMT = 1753112374061

La classe Calendar per ottenere i componenti della data e dell'ora

La classe astratta Calendar fornisce un insieme di metodi che consente di convertire un tempo in millisecondi in un numero di componenti utili. Alcuni esempi del tipo di informazioni che possono essere fornite sono anno, mese, giorno, ora, minuto e secondo. È previsto che le sottoclassi di Calendar forniscano la funzionalità specifica per interpretare le informazioni temporali secondo le proprie regole. Questo è un aspetto della libreria di classi Java che consente di scrivere programmi che possono operare in ambienti internazionali. Un esempio di tale sottoclasse è GregorianCalendar.

Calendar non fornisce costruttori pubblici. Calendar definisce diverse variabili di istanza protette. areFieldsSet è un boolean che indica se i componenti temporali sono stati impostati. fields è un array di int che contiene i componenti del tempo. isSet è un array boolean che indica se un componente temporale specifico è stato impostato. time è un long che contiene il tempo corrente per questo oggetto. isTimeSet è un boolean che indica se il tempo corrente è stato impostato.

Un sotto-insieme dei metodi definiti da Calendar è mostrato nella tabella seguente:

Metodo Descrizione
abstract void add(int quale, int valore) Aggiunge valore al componente temporale o di data specificato da quale. Per sottrarre, aggiungere un valore negativo. quale deve essere uno dei campi definiti da Calendar, come Calendar.HOUR.
boolean after(Object oggettoCalendar) Restituisce true se l'oggetto Calendar invocante contiene una data che è successiva a quella specificata da oggettoCalendar. Altrimenti, restituisce false.
boolean before(Object oggettoCalendar) Restituisce true se l'oggetto Calendar invocante contiene una data che è precedente a quella specificata da oggettoCalendar. Altrimenti, restituisce false.
final void clear() Azzera tutti i componenti temporali nell'oggetto invocante.
final void clear(int quale) Azzera il componente temporale specificato da quale nell'oggetto invocante.
Object clone() Restituisce un duplicato dell'oggetto invocante.
boolean equals(Object oggettoCalendar) Restituisce true se l'oggetto Calendar invocante contiene una data che è uguale a quella specificata da oggettoCalendar. Altrimenti, restituisce false.
int get(int campoCalendar) Restituisce il valore di un componente dell'oggetto invocante. Il componente è indicato da campoCalendar. Esempi dei componenti che possono essere richiesti sono Calendar.YEAR, Calendar.MONTH, Calendar.MINUTE, e così via.
static Locale[] getAvailableLocales() Restituisce un array di oggetti Locale che contiene le impostazioni locali per le quali i calendari sono disponibili.
static Calendar getInstance() Restituisce un oggetto Calendar per l'impostazione locale predefinita e il fuso orario.
static Calendar getInstance(TimeZone fusoOrario) Restituisce un oggetto Calendar per il fuso orario specificato da fusoOrario. Viene utilizzata l'impostazione locale predefinita.
static Calendar getInstance(Locale impostazioneLocale) Restituisce un oggetto Calendar per l'impostazione locale specificata da impostazioneLocale. Viene utilizzato il fuso orario predefinito.
static Calendar getInstance(TimeZone fusoOrario, Locale impostazioneLocale) Restituisce un oggetto Calendar per il fuso orario specificato da fusoOrario e l'impostazione locale specificata da impostazioneLocale.
final Date getTime() Restituisce un oggetto Date equivalente al tempo dell'oggetto invocante.
TimeZone getTimeZone() Restituisce il fuso orario per l'oggetto invocante.
final boolean isSet(int quale) Restituisce true se il componente temporale specificato è impostato. Altrimenti, restituisce false.
void set(int quale, int valore) Imposta il componente di data o tempo specificato da quale al valore specificato da valore nell'oggetto invocante. quale deve essere uno dei campi definiti da Calendar, come Calendar.HOUR.
final void set(int anno, int mese, int giornoDelMese) Imposta vari componenti di data e tempo dell'oggetto invocante.
final void set(int anno, int mese, int giornoDelMese, int ore, int minuti) Imposta vari componenti di data e tempo dell'oggetto invocante.
final void set(int anno, int mese, int giornoDelMese, int ore, int minuti, int secondi) Imposta vari componenti di data e tempo dell'oggetto invocante.
final void setTime(Date d) Imposta vari componenti di data e tempo dell'oggetto invocante. Queste informazioni sono ottenute dall'oggetto Date d.
void setTimeZone(TimeZone fusoOrario) Imposta il fuso orario per l'oggetto invocante a quello specificato da fusoOrario.
final Instant toInstant() Restituisce un oggetto Instant corrispondente all'istanza Calendar invocante.
Tabella 2: Sotto-insieme dei metodi definiti da Calendar.

Calendar definisce le seguenti costanti int, che vengono utilizzate quando si ottengono o si impostano componenti del calendario:

Costante Descrizione
ALL_STYLES Indica che tutti gli stili di formattazione devono essere utilizzati.
AM Indica il periodo di tempo da mezzanotte a mezzogiorno.
AM_PM Indica il periodo di tempo da mezzogiorno a mezzanotte.
APRIL Indica il mese di aprile.
AUGUST Indica il mese di agosto.
DATE Indica il giorno del mese.
DAY_OF_MONTH Indica il giorno del mese.
DAY_OF_WEEK Indica il giorno della settimana.
DAY_OF_WEEK_IN_MONTH Indica il giorno della settimana nel mese.
DAY_OF_YEAR Indica il giorno dell'anno.
DECEMBER Indica il mese di dicembre.
DST_OFFSET Indica l'offset dell'ora legale.
ERA Indica l'era.
FEBRUARY Indica il mese di febbraio.
FIELD_COUNT Indica il numero di campi definiti da Calendar.
FRIDAY Indica il giorno della settimana venerdì.
HOUR Indica l'ora del giorno.
HOUR_OF_DAY Indica l'ora del giorno in formato 24 ore.
JANUARY Indica il mese di gennaio.
JULY Indica il mese di luglio.
JUNE Indica il mese di giugno.
LONG Indica lo stile di formattazione lungo.
LONG_FORMAT Indica lo stile di formattazione lungo.
LONG_STANDALONE Indica lo stile di formattazione lungo per i campi di data e ora.
MARCH Indica il mese di marzo.
MAY Indica il mese di maggio.
MILLISECOND Indica il millisecondo.
MINUTE Indica il minuto.
MONDAY Indica il giorno della settimana lunedì.
MONTH Indica il mese.
NARROW_FORMAT Indica lo stile di formattazione stretto.
NARROW_STANDALONE Indica lo stile di formattazione stretto per i campi di data e ora.
NOVEMBER Indica il mese di novembre.
OCTOBER Indica il mese di ottobre.
PM Indica il periodo di tempo da mezzogiorno a mezzanotte.
SATURDAY Indica il giorno della settimana sabato.
SECOND Indica il secondo.
SEPTEMBER Indica il mese di settembre.
SHORT Indica lo stile di formattazione breve.
SHORT_FORMAT Indica lo stile di formattazione breve.
SHORT_STANDALONE Indica lo stile di formattazione breve per i campi di data e ora.
SUNDAY Indica il giorno della settimana domenica.
THURSDAY Indica il giorno della settimana giovedì.
TUESDAY Indica il giorno della settimana martedì.
UNDECIMBER Indica il mese di dicembre in un calendario non standard.
WEDNESDAY Indica il giorno della settimana mercoledì.
WEEK_OF_MONTH Indica la settimana del mese.
WEEK_OF_YEAR Indica la settimana dell'anno.
Tabella 3: Costanti definite da Calendar.

Il seguente programma dimostra diversi metodi di Calendar:

// Dimostra Calendar
import java.util.Calendar;

class DemoCalendar {

    public static void main(String[] args) {
        // Crea un array di stringhe per i mesi dell'anno.
        String[] mesi = {
                "Gen", "Feb", "Mar", "Apr",
                "Mag", "Giu", "Lug", "Ago",
                "Set", "Ott", "Nov", "Dic" };

        // Crea un calendario inizializzato con la
        // data e ora correnti nell'impostazione
        // locale e fuso orario predefiniti.
        Calendar calendario = Calendar.getInstance();

        // Visualizza le informazioni correnti di data e ora.
        System.out.print("Data: ");
        System.out.print(mesi[calendario.get(Calendar.MONTH)]);
        System.out.print(" " + calendario.get(Calendar.DATE) + " ");
        System.out.println(calendario.get(Calendar.YEAR));
        System.out.print("Ora: ");
        System.out.print(calendario.get(Calendar.HOUR) + ":");
        System.out.print(calendario.get(Calendar.MINUTE) + ":");
        System.out.print(calendario.get(Calendar.SECOND));
        System.out.print(" ");
        System.out.println(calendario.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM");

        // Imposta le informazioni di ora e data e le visualizza.
        calendario.set(Calendar.HOUR, 10);
        calendario.set(Calendar.MINUTE, 29);
        calendario.set(Calendar.SECOND, 22);
        System.out.print("Ora aggiornata: ");
        System.out.print(calendario.get(Calendar.HOUR) + ":");
        System.out.print(calendario.get(Calendar.MINUTE) + ":");
        System.out.print(calendario.get(Calendar.SECOND));
        System.out.print(" ");
        System.out.println(calendario.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM");
    }

}

Un esempio di output è mostrato qui:

Data: Lug 21 2025
Ora: 5:51:46 PM
Ora aggiornata: 10:29:22 PM

La classe GregorianCalendar

GregorianCalendar è un'implementazione concreta di un Calendar che implementa il normale calendario gregoriano con cui siamo familiari. Il metodo getInstance() di Calendar restituirà tipicamente un GregorianCalendar inizializzato con la data e l'ora correnti nella locale e nel fuso orario predefiniti.

GregorianCalendar definisce due campi: AD e BC. Questi rappresentano le due ere definite dal calendario gregoriano.

Ci sono anche diversi costruttori per gli oggetti GregorianCalendar. Il predefinito, GregorianCalendar(), inizializza l'oggetto con la data e l'ora correnti nella locale e nel fuso orario predefiniti. Altri tre costruttori offrono livelli crescenti di specificità:

GregorianCalendar(int anno, int mese, int giornoDelMese)
GregorianCalendar(int anno, int mese, int giornoDelMese, int ore, int minuti)
GregorianCalendar(int anno, int mese, int giornoDelMese, int ore, int minuti, int secondi)

Tutte e tre le versioni impostano il giorno, il mese e l'anno. Qui, anno specifica l'anno. Il mese è specificato da mese, con zero che indica gennaio. Il giorno del mese è specificato da giornoDelMese. La prima versione imposta l'ora a mezzanotte. La seconda versione imposta anche le ore e i minuti. La terza versione aggiunge i secondi.

Si può anche costruire un oggetto GregorianCalendar specificando il formato locale (ossia se si desidera utilizzare un formato locale specifico) e/o il fuso orario. I seguenti costruttori creano oggetti inizializzati con la data e l'ora correnti utilizzando il fuso orario e/o l'impostazione locale specificati:

GregorianCalendar(Locale locale)
GregorianCalendar(TimeZone fusoOrario)
GregorianCalendar(TimeZone fusoOrario, Locale locale)

GregorianCalendar fornisce un'implementazione di tutti i metodi astratti in Calendar. Fornisce anche alcuni metodi aggiuntivi. Forse il più interessante è isLeapYear(), che verifica se l'anno è bisestile. La sua forma è

boolean isLeapYear(int anno)

Questo metodo restituisce true se anno è un anno bisestile e false altrimenti. Altri due metodi di interesse sono from() e toZonedDateTime(), che supportano l'API di data e ora aggiunta da JDK 8 e inclusa nel pacchetto java.time.

Il seguente programma dimostra GregorianCalendar:

// Dimostra la classe GregorianCalendar
import java.util.*;

class DemoCalendarioGregoriano {

    public static void main(String[] args) {
        // Crea un array di stringhe per i mesi
        String[] mesi = {
                "Gen", "Feb", "Mar", "Apr",
                "Mag", "Giu", "Lug", "Ago",
                "Set", "Ott", "Nov", "Dic" };

        // Crea una variabile per l'anno
        int anno;

        // Crea un calendario gregoriano inizializzato
        // con la data e l'ora correnti nel formato
        // locale e fuso orario predefiniti.
        GregorianCalendar calendarioGregoriano = new GregorianCalendar();

        // Visualizza le informazioni correnti di ora e data.
        System.out.print("Data: ");
        System.out.print(mesi[calendarioGregoriano.get(Calendar.MONTH)]);
        System.out.print(" " + calendarioGregoriano.get(Calendar.DATE) + " ");
        System.out.println(anno = calendarioGregoriano.get(Calendar.YEAR));
        System.out.print("Ora: ");
        System.out.print(calendarioGregoriano.get(Calendar.HOUR) + ":");
        System.out.print(calendarioGregoriano.get(Calendar.MINUTE) + ":");
        System.out.println(calendarioGregoriano.get(Calendar.SECOND));

        // Verifica se l'anno corrente è bisestile
        if (calendarioGregoriano.isLeapYear(anno)) {
            System.out.println("L'anno corrente è bisestile");
        } else {
            System.out.println("L'anno corrente non è bisestile");
        }
    }

}

Un output di esempio è mostrato qui:

Data: Lug 21 2025
Ora: 5:58:48
L'anno corrente non è bisestile

La classe TimeZone per gestire i fusi orari

Un'altra classe relativa al tempo è TimeZone. La classe astratta TimeZone consente di lavorare con gli offset del fuso orario dal tempo medio di Greenwich (GMT), denominato anche Tempo Universale Coordinato (UTC). Calcola anche l'ora legale. TimeZone fornisce solo il costruttore predefinito.

Un sotto-insieme di metodi definiti da TimeZone è riportato nella tabella seguente:

Metodo Descrizione
Object clone() Clona l'oggetto TimeZone.
static String[] getAvailableIDs() Restituisce un array di oggetti String che rappresentano i nomi di tutti i fusi orari.
static String[] getAvailableIDs(int deltaTempo) Restituisce un array di oggetti String che rappresentano i nomi di tutti i fusi orari che hanno un offset di deltaTempo da UTC.
static TimeZone getDefault() Restituisce un oggetto TimeZone che rappresenta il fuso orario predefinito utilizzato sul computer host.
String getID() Restituisce il nome dell'oggetto TimeZone invocante.
abstract int getOffset(int era, int anno, int mese, int giornoDelMese, int giornoDellaSettimana, int millisecondi) Restituisce l'offset che dovrebbe essere aggiunto a UTC per calcolare l'ora locale. Questo valore è regolato per l'ora legale. I parametri del metodo rappresentano componenti di data e ora.
abstract int getRawOffset() Restituisce l'offset grezzo (in millisecondi) che dovrebbe essere aggiunto a UTC per calcolare l'ora locale. Questo valore non è regolato per l'ora legale.
static TimeZone getTimeZone(String nomeTz) Restituisce l'oggetto TimeZone per il fuso orario denominato nomeTz.
abstract boolean inDaylightTime(Date d) Restituisce true se la data rappresentata da d è nell'ora legale nell'oggetto invocante. Altrimenti, restituisce false.
static void setDefault(TimeZone tz) Imposta il fuso orario predefinito da utilizzare su questo host. tz è un riferimento all'oggetto TimeZone da utilizzare.
void setID(String nomeTz) Imposta il nome del fuso orario (cioè, il suo ID) a quello specificato da nomeTz.
abstract void setRawOffset(int millis) Imposta l'offset in millisecondi da UTC.
ZoneId toZoneId() Converte l'oggetto invocante in un ZoneId e restituisce il risultato. ZoneId è contenuto in java.time.
abstract boolean useDaylightTime() Restituisce true se l'oggetto invocante utilizza l'ora legale. Altrimenti, restituisce false.
Tabella 4: Metodi più importanti definiti da TimeZone.

La classe SimpleTimeZone

La classe SimpleTimeZone è una sottoclasse di convenienza di TimeZone. Implementa i metodi astratti di TimeZone e permette di lavorare con i fusi orari per un calendario gregoriano. Calcola anche l'ora legale.

SimpleTimeZone definisce quattro costruttori. Il primo costruttore è

SimpleTimeZone(int deltaTempo, String nomeZf)

Questo costruttore crea un oggetto SimpleTimeZone. L'offset relativo al tempo UTC è deltaTempo. Il fuso orario è denominato nomeZf.

Il secondo costruttore di SimpleTimeZone è:

SimpleTimeZone(int deltaTempo,
               String idZf,
               int meseOraLegale0,
               int giornoInMeseOraLegale0,
               int giornoOraLegale0,
               int tempo0,
               int meseOraLegale1,
               int giornoInMeseOraLegale1,
               int giornoOraLegale1,
               int tempo1)

Qui, l'offset relativo ad UTC è specificato in deltaTempo. Il nome del fuso orario è passato in idZf. L'inizio dell'ora legale è indicato dai parametri meseOraLegale0, giornoInMeseOraLegale0, giornoOraLegale0, e tempo0. La fine dell'ora legale è indicata dai parametri meseOraLegale1, giornoInMeseOraLegale1, giornoOraLegale1, e tempo1.

Il terzo costruttore di SimpleTimeZone è

SimpleTimeZone(int deltaTempo,
               String idZf,
               int meseOraLegale0,
               int giornoInMeseOraLegale0,
               int giornoOraLegale0,
               int tempo0,
               int meseOraLegale1,
               int giornoInMeseOraLegale1,
               int giornoOraLegale1,
               int tempo1,
               int deltaOraLegale)

Qui, deltaOraLegale è il numero di millisecondi risparmiati durante l'ora legale.

Il quarto costruttore di SimpleTimeZone è:

SimpleTimeZone(int deltaTempo,
               String idZf,
               int meseOraLegale0,
               int giornoInMeseOraLegale0,
               int giornoOraLegale0,
               int tempo0,
               int modalitaTempo0,
               int meseOraLegale1,
               int giornoInMeseOraLegale1,
               int giornoOraLegale1,
               int tempo1,
               int modalitaTempo1,
               int deltaOraLegale)

Qui, modalitaTempo0 specifica la modalità del tempo di inizio, e modalitaTempo1 specifica la modalità del tempo di fine. I valori di modalità validi includono:

  • WALL_TIME: il tempo locale.
  • UTC_TIME: il tempo universale coordinato (UTC).
  • STANDARD_TIME: il tempo standard, che è il tempo locale senza l'ora legale.

La modalità tempo indica come vengono interpretati i valori di tempo. La modalità predefinita utilizzata dagli altri costruttori è WALL_TIME.