sql >> Database >  >> RDS >> Mysql

JPA TemporalType.Date geeft verkeerde datum op

Het spijt me, maar alle antwoorden tot nu toe zijn over het algemeen onjuist. Het antwoord is vrij eenvoudig, maar vereist dat we vijf punten scheiden:

  1. DATE =java.sql.Date, wat een wrapper is rond java.util.Date dat het aantal milliseconden is sinds de Epoch in de UTC-tijdzone. Dit heeft dus het jaar/maand/datum/uren/minuten/seconden in een vaste GMT+0 (UTC) tijdzone. Merk echter op dat java.sql.Date de tijdcomponenten op nul zet!
  2. TIMESTAMP =java.sql.TimeStamp, een componentomhulling rond Date die fractionele seconden toevoegt om de SQL DATE-typestandaard te ondersteunen. Deze klasse/type is niet relevant of nodig voor deze vraag, maar in het kort heeft dit de datum plus de tijd.
  3. De database slaat DATE-objecten op zoals gedefinieerd (met UTC als offset van Java), maar mag vertaal de tijd indien geconfigureerd in de database om in een andere tijdzone te zijn. Standaard gebruiken de meeste databases de tijdzone van de lokale server, wat een heel slecht idee is. Dames, heren ... Sla DATE-objecten ALTIJD op in UTC. Lees verder...
  4. De tijd in de JVM en tijdzone moet kloppen. Wordt er een offset berekend voor uw servertijd, aangezien het Date-object UTC gebruikt? Overweeg dat met de sterke aanbeveling om de servertijd in te stellen op GMT+0 (UTC).
  5. Als we ten slotte de DATE uit de database willen weergeven (met JSF of wat dan ook), moet wees ingesteld om GMT+0 tijdzone te zijn en, indien gedaan vanaf de server naar boven, ook ... uw datums en tijden zullen ALTIJD consistent, referentieel en alle goede dingen zijn. Het enige dat overblijft is om de tijd weer te geven en DIT is waar de user-agent (voor een web-applicatie bijvoorbeeld) zou kunnen worden gebruikt om de GMT+0-tijd te vertalen naar de "lokale" tijdzone van de gebruiker.

Samenvatting:gebruik UTC (GMT+0) op de server, in de database, in uw Java-objecten.

DATE en TIMESTAMP verschillen alleen vanuit een databaseperspectief doordat TIMESTAMP extra fracties van seconden bevat. Beide gebruiken GMT+0 (impliciet). JodaTime is een voorkeurskalender om hiermee om te gaan, maar lost de problemen van niet-overeenkomende JVM en tijdzone-instellingen van de database niet op.

Als applicatieontwerpen van JVM tot de DB geen GMT gebruiken, vanwege zomertijd, klokaanpassingen en allerlei andere regionale spellen die in de wereld lokale klokken worden gespeeld ... zullen de tijden van transacties en al het andere voor altijd vertekend zijn , niet-referentieel, inconsistent, enz.

Nog een goed gerelateerd antwoord over gegevenstypen:java.util .Datum versus java.sql.Datum

Merk ook op dat Java 8 updates heeft met een betere datum/tijd-afhandeling (eindelijk), maar dit lost niet op dat de serverklok waarop de JVM draait zich in de ene tijdzone bevindt en de database in een andere. Op dit punt vindt er altijd een vertaling plaats. In elke grote (slimme) client waarmee ik werk, zijn de tijdzones van de database en JVM-server juist om deze reden ingesteld op UTC, zelfs als hun activiteiten grotendeels in een andere tijdzone plaatsvinden.



  1. Doorlopende bereiken groeperen met MySQL

  2. CTE-fout:typen komen niet overeen tussen het anker en het recursieve deel

  3. Hoe dubbele rijen uit een MySQL-tabel te verwijderen

  4. pgAdmin III Waarom worden zoekopdrachtresultaten verkort?