sql >> Databasteknik >  >> RDS >> Mysql

JPA TemporalType.Datum ger fel datum

Mycket ledsen, men alla svar hittills är generellt felaktiga. Svaret är ganska enkelt men kräver att vi separerar fem punkter:

  1. DATE =java.sql.Date, som är ett omslag runt java.util.Date som är antalet millisekunder sedan epoken i UTC-tidszonen. Så detta har år/månad/datum/timmar/minuter/sekunder i en fast GMT+0 (UTC) tidszon. Observera dock att java.sql.Date ställer in tidskomponenterna till noll!
  2. TIMESTAMP =java.sql.TimeStamp som är ett komponentomslag runt Date som lägger till bråkdelar av sekunder för att stödja SQL DATE-typstandarden. Denna klass/typ är inte relevant eller behövs för den här frågan men i korthet har den datumet plus tiden.
  3. Databasen lagrar DATE-objekt enligt definitionen (med UTC som offset från Java) men kan översätt tiden om den är konfigurerad i databasen till en annan tidszon. Som standard använder de flesta databaser den lokala serverns tidszon, vilket är en mycket dålig idé. Mina damer, herrar ... lagra ALLTID DATE-objekt i UTC. Läs vidare...
  4. Klockan i JVM och tidszon måste vara rätt. Eftersom Date-objektet använder UTC, beräknas en offset för din servertid? Tänk på det med den starka rekommendationen att servertiden ställs in på GMT+0 (UTC).
  5. Slutligen när vi vill återge DATUM från databasen (med JSF eller vad som helst), bör ställas in för att vara GMT+0-tidszon och, om det görs från serverns sida också... dina datum och tider kommer ALLTID att vara konsekventa, refererande och alla bra saker. Allt som återstår är att rendera tiden och DETTA är där användaragenten (för en webbapplikation till exempel) kunde användas för att översätta GMT+0-tiden till användarens "lokala" tidszon.

Sammanfattning:Använd UTC (GMT+0) på servern, i databasen, i dina Java-objekt.

DATUM och TIDSTÄMPEL skiljer sig bara från ett databasperspektiv genom att TIDSTÄMPEL har ytterligare bråkdelar av sekunder. Båda använder GMT+0 (underförstått). JodaTime är ett föredraget kalenderramverk för att hantera allt detta, men kommer inte att lösa problemen med att JVM inte matchar tidszonsinställningar för databasen.

Om applikationsdesigner från JVM till DB inte använder GMT, på grund av sommarljus, klockjusteringar och alla typer av andra regionala spel som spelas i världens lokala klockor ... kommer transaktionernas tider och allt annat för alltid att vara snedställda , icke-referensiell, inkonsekvent, etc.

Ett annat bra relaterat svar om datatyper:java.util .Date kontra java.sql.Date

Notera också att Java 8 har uppdateringar med bättre datum/tidshantering (äntligen) men detta fixar inte att serverklockan som JVM körs på är i en tidszon och databasen i en annan. Vid denna tidpunkt sker det alltid översättningar. I varje stor (smart) klient jag arbetar med är databasen och JVM-serverns tidszoner inställda på UTC av just denna anledning, även om deras operationer till stor del sker i någon annan tidszon.



  1. SQL WHERE-villkor är inte lika med?

  2. Hur kan jag slå samman två MySQL-tabeller?

  3. ORA-12514 TNS:listener känner för närvarande inte till tjänst som efterfrågas i anslutningsbeskrivningen

  4. Refaktorera en PL/pgSQL-funktion för att returnera utdata från olika SELECT-frågor