Mysql
 sql >> Database >  >> RDS >> Mysql

JPA Salvataggio di una data errata nel database MySQL

tl;dr

Utilizza JPA 2.2 per il supporto di java.time .

Usa una classe di sola data in Java per lavorare con i valori di sola data in SQL.

LocalDate                           // Represent a date-only, without a time-of-day and without a time zone.
.now(                               // Get today's date…
    ZoneId.of( "Africa/Tunis" )     // …as seen in the wall-clock time used by the people of a particular region.
)                                   // Returns a `LocalDate` object.
.plusMonths( 1 )                    // Returns another `LocalDate` object, per immutable objects pattern.

java.time

APP 2.2 ora supporta il moderno java.time classi. Non è più necessario utilizzare Joda-Time.

Non non usa java.sql.Date . Quella classe finge per rappresentare una sola data ma in realtà ha un'ora del giorno impostata su UTC a causa della terribile decisione di progettazione di ereditare da java.util.Date (che nonostante il nome rappresenta una data e un'ora del giorno e un offset di zero per UTC stesso). Queste classi legacy sono un terribile disastro. Sun, Oracle e la comunità JCP hanno rinunciato a queste lezioni anni fa con l'adozione di JSR 310, e dovresti farlo anche tu.

LocalDate

Il LocalDate class rappresenta un valore di sola data senza ora del giorno e senza fuso orario o offset-from-UTC .

Un fuso orario è fondamentale per determinare una data. Per un dato momento, la data varia in tutto il mondo per zona. Ad esempio, pochi minuti dopo la mezzanotte a Parigi Francia è un nuovo giorno mentre è ancora “ieri” a Montréal Québec .

Se non viene specificato alcun fuso orario, la JVM applica implicitamente il fuso orario predefinito corrente. Tale impostazione predefinita potrebbe cambia in qualsiasi momento durante il runtime(!), quindi i risultati possono variare. È meglio specificare il fuso orario desiderato/previsto in modo esplicito come argomento. Se critico, conferma la zona con il tuo utente.

Specificare un nome del fuso orario corretto nel formato Continent/Region , come America/Montreal , Africa/Casablanca o Pacific/Auckland . Non utilizzare mai l'abbreviazione di 2-4 lettere come EST o IST in quanto non fusi orari veri, non standardizzati e nemmeno unici(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Se si desidera utilizzare il fuso orario predefinito corrente della JVM, richiederlo e passare come argomento. Se omesso, il codice diventa ambiguo da leggere in quanto non sappiamo con certezza se intendevi utilizzare l'impostazione predefinita o se, come tanti programmatori, non eri a conoscenza del problema.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Oppure specifica una data. Puoi impostare il mese in base a un numero, con una sana numerazione da 1 a 12 per gennaio-dicembre.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

O, meglio, usa il Month enum oggetti predefiniti, uno per ogni mese dell'anno. Suggerimento:usa questi Month oggetti nella tua codebase anziché un semplice numero intero per rendere il tuo codice più auto-documentante, garantire valori validi e fornire sicurezza del tipo . Idem per Year &YearMonth .

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Matematica data-ora

Apparentemente vuoi iniziare con una data e ottenere un mese dopo come intervallo di date.

LocalDate monthLater = ld.plusMonths( 1 ) ;

JDBC 4.2

A partire da JDBC 4.2, il tuo driver JDBC è necessario per supportare alcune delle chiavi java.time classi come LocalDate .

Intervallo di date

Nota i link sottostanti per ThreeTen-Extra . Potresti trovare il LocalDateRange lezione lì per essere utile se lavori molto con gli intervalli di date.

Informazioni su java.time

Il java.time framework è integrato in Java 8 e versioni successive. Queste classi soppiantano la vecchia e problematica eredità classi data-ora come java.util.Date , Calendar , &SimpleDateFormat .

Per ulteriori informazioni, consulta il Tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Il Joda-Time progetto, ora in modalità di manutenzione , consiglia la migrazione a java.time classi.

Puoi scambiare java.time oggetti direttamente con il tuo database. Utilizzare un driver JDBC conforme a JDBC 4.2 o più tardi. Non c'è bisogno di stringhe, non c'è bisogno di java.sql.* classi.

Dove ottenere le classi java.time?

Il ThreeTen-Extra il progetto estende java.time con classi aggiuntive. Questo progetto è un banco di prova per possibili future aggiunte a java.time. Potresti trovare alcune classi utili qui come Interval , YearWeek , YearQuarter e altro .