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

JPA TemporalType.Date che fornisce una data errata

Siamo spiacenti ma tutte le risposte finora sono generalmente errate. La risposta è abbastanza semplice ma richiede di separare cinque punti:

  1. DATE =java.sql.Date, che è un wrapper attorno a java.util.Date che è il numero di millisecondi trascorsi da Epoch nel fuso orario UTC. Quindi questo ha l'anno/mese/data/ore/minuti/secondi in un fuso orario GMT+0 (UTC) fisso. Si noti tuttavia che java.sql.Date imposta i componenti dell'ora su zero!
  2. TIMESTAMP =java.sql.TimeStamp che è un wrapper di componenti attorno a Date che aggiunge frazioni di secondi per supportare lo standard di tipo SQL DATE. Questa classe/tipo non è rilevante o necessaria per questa domanda ma in breve ha la data più l'ora.
  3. Il database memorizza gli oggetti DATE come definiti (usando UTC come offset da Java) ma può tradurre l'ora se configurata nel database in un fuso orario diverso. Per impostazione predefinita, la maggior parte dei database utilizza il fuso orario del server locale, il che è una pessima idea. Signore, signori... Memorizzare SEMPRE gli oggetti DATE in UTC. Continua a leggere...
  4. L'ora nella JVM e il fuso orario devono essere corretti. Poiché l'oggetto Date utilizza UTC, viene calcolato un offset per l'ora del server? Consideralo con la forte raccomandazione di impostare l'ora del server su GMT+0 (UTC).
  5. Infine, quando vogliamo eseguire il rendering della DATA dal database (usando JSF o altro), dovrebbe essere impostato per essere il fuso orario GMT + 0 e, se eseguito dal server anche in alto ... le tue date e orari saranno SEMPRE coerenti, referenziali e tutte cose buone. Tutto ciò che resta è rendere l'ora e QUESTO è dove lo user-agent (per un'applicazione web per esempio) potrebbe essere utilizzato per tradurre l'ora GMT+0 nel fuso orario "locale" degli utenti.

Riepilogo:utilizza UTC (GMT+0) sul server, nel database, nei tuoi oggetti Java.

DATE e TIMESTAMP sono diversi solo dal punto di vista del database in quanto TIMESTAMP contiene frazioni di secondi aggiuntive. Entrambi usano GMT+0 (implicito). JodaTime è un framework di calendario preferito per gestire tutto questo, ma non risolverà i problemi di JVM non corrispondenti alle impostazioni del fuso orario del database.

Se i progetti di applicazioni dalla JVM al DB non utilizzano GMT, a causa dell'ora legale, delle regolazioni dell'orologio e di tutti i tipi di altri giochi regionali che vengono giocati negli orologi locali del mondo ... i tempi delle transazioni e tutto il resto saranno per sempre distorti , non referenziale, incoerente, ecc.

Un'altra buona risposta correlata sui tipi di dati:java.util .Date vs java.sql.Date

Si noti inoltre che Java 8 ha aggiornamenti con una migliore gestione di data/ora (finalmente) ma ciò non risolve il fatto che l'orologio del server su cui è in esecuzione la JVM si trovi in ​​un fuso orario e il database in un altro. A questo punto c'è sempre la traduzione in corso. In ogni client (intelligente) di grandi dimensioni con cui lavoro, i fusi orari del database e del server JVM sono impostati su UTC proprio per questo motivo, anche se le loro operazioni si verificano in gran parte in un altro fuso orario.