java.util.Date vs java.sql.Date

1. Panoramica

In questo tutorial, confronteremo due classi di date: java.util.Date e java.sql.Date .

Una volta completato il confronto, dovrebbe essere chiaro quale utilizzare e perché.

2. java.util.Date

La classe java.util.Date rappresenta un particolare momento nel tempo, con una precisione al millisecondo dal 1 gennaio 1970 00:00:00 GMT (l'ora dell'epoca) . La classe viene utilizzata per mantenere l'ora universale coordinata (UTC).

Possiamo inizializzarlo in due modi.

Chiamando il costruttore:

Date date = new Date();

che creerà un nuovo oggetto data con l'ora impostata sull'ora corrente, misurata al millisecondo più vicino.

O passando un numero di millisecondi dall'epoca:

long timestamp = 1532516399000; // 25 July 2018 10:59:59 UTC Date date = new Date(timestamp);

Notiamo che altri costruttori, presenti prima di Java 8, sono ora deprecati.

Tuttavia, Date ha una serie di problemi e nel complesso il suo utilizzo non è più raccomandato .

È mutevole. Una volta inizializzato, possiamo modificarne il valore interno. Ad esempio, possiamo chiamare il metodo setTime :

date.setTime(0); // 01 January 1970 00:00:00

Per ulteriori informazioni sui vantaggi degli oggetti immutabili, consulta questo articolo: Oggetti immutabili in Java.

Inoltre non gestisce molto bene tutte le date. Tecnicamente, dovrebbe riflettere l'ora universale coordinata (UTC). Tuttavia, ciò dipende da un sistema operativo dell'ambiente host.

La maggior parte dei sistemi operativi moderni utilizza 1 giorno = 24 h x 60 m x 60 s = 86400 secondi, il che, come possiamo vedere, non tiene conto del "secondo intercalare".

Con l'introduzione di Java 8, dovrebbe essere utilizzato il pacchetto java.time . Prima di Java 8, era disponibile una soluzione alternativa: Joda Time .

3. java.sql.Date

Il java.sql.Date estende java.util.Date classe.

Il suo scopo principale è rappresentare SQL DATE, che mantiene anni, mesi e giorni. Non vengono conservati dati sull'ora.

Infatti la data viene memorizzata in millisecondi a partire dal 1 gennaio 1970 00:00:00 GMT e la parte temporale viene normalizzata, cioè impostata a zero.

Fondamentalmente, è un wrapper attorno a java.util.Date che gestisce i requisiti specifici di SQL. java.sql.Date dovrebbe essere utilizzato solo quando si tratta di database.

Tuttavia, poiché java.sql.Date non contiene informazioni sul fuso orario, la conversione del fuso orario tra il nostro ambiente locale e il server di database dipende da un'implementazione del driver JDBC. Questo aggiunge un altro livello di complessità.

Infine, notiamo che, per supportare altri tipi di dati SQL: SQL TIME e SQL TIMESTAMP, sono disponibili altre due classi java.sql : Time e Timestamp .

Quest'ultimo, anche se si estende da java.util.Date , supporta i nanosecondi.

4. Conclusione

La classe java.util.Date memorizza un valore di data e ora in millisecondi dall'epoca. java.sql.Date memorizza un valore solo data ed è comunemente utilizzato in JDBC.

Gestire le date è complicato. Dobbiamo ricordare casi speciali: secondi intercalari, fusi orari diversi, ecc. Quando si ha a che fare con JDBC, è possibile utilizzare java.sql.Date con cautela.

Se useremo java.util.Date, dobbiamo ricordarci dei suoi difetti. Se si utilizza Java 8, è meglio non usare affatto java.util.Date .