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

Java Date og MySQL tidsstempler tidszoner

tl;dr

myPreparedStatement
.setObject(  
    … ,                                   // Specify which placeholder `?` in your SQL statement. 
    OffsetDateTime.now( ZoneOffset.UTC )  // Capture the current moment as seen in the wall-clock time of UTC (an offset-from-UTC of zero).
) ;

Undgå forældede dato-/tidskurser

Du bruger frygtelige dato-tidsklasser, der blev erstattet for år siden af ​​java.time klasser.

Brug aldrig Dato eller Tidsstempel .

UTC

Fang det aktuelle øjeblik i UTC. De fleste databaser gemmer et øjeblik i UTC. Og generelt bør du gøre det meste af din forretningslogik, fejlfinding, logning, lagring og dataudveksling i UTC.

OffsetDateTime

Repræsenter et øjeblik med en offset-fra-UTC ved hjælp af det passende navn OffsetDateTime klasse.

Vi ønsker selve UTC eller en offset på nul. Vi kan bruge en konstant til det, ZoneOffset.UTC .

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;

JDBC 4.2

Fra JDBC 4.2 kan vi udveksle java.time direkte objekter med databasen.

For at gemme dette øjeblik i en kolonne af en datatype beslægtet med SQL-standarden TIMESTAMP WITH TIME ZONE :

myPreparedStatement.setObject( … , odt ) ;

Hentning:

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

ZonedDateTime

For at præsentere dette hentede øjeblik for brugeren, kan det være en god ide at tilpasse sig brugerens forventede/ønskede tidszone.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

Stol aldrig på standardtidszonen

Bemærk i koden ovenfor, at vi altid har angivet den ønskede/forventede offset eller zone.

Hvis du ikke specificerer, anvendes en forskydning eller zone stille implicit. Bedre at specificere dine hensigter eksplicit, da den nuværende standard for din JVM, database og værts-OS er alle ude af dine hænder som programmør. Hvilket betyder, at kode, der er afhængig af standarden, vil variere i adfærd under kørsel.

Java 6 &7

Den samme mand, Stephen Colebourne, der leder JSR 310 og java.time implementering, samt den berømte Joda-Time projekt, leder også et andet projekt, ThreeTen-Backport . Det meste af java.time funktionalitet er back-porteret til Java 6 og 7 i dette bibliotek med næsten identisk API.

Så gør alt dit arbejde i back-port klasser. Derefter, i sidste øjeblik, konverter til/fra java.sql.Timestamp via DateTimeUtils klasse.

Disse konverteringsmetoder bruger for det meste Instant genstande. Et Instant er et øjeblik i UTC, altid i UTC. Du kan justere fra din OffsetDateTime til UTC ved at udtrække en Instant . Instant klasse er den grundlæggende byggeblokklasse i java.time , med OffsetDateDate have mere fleksibilitet, såsom alternative formateringsmønstre, når du genererer en streng. Men begge Instant og OffsetDateTime repræsentere et øjeblik, et punkt på tidslinjen.

Instant instant = odt.toInstant() ;  
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;

Går den anden retning, henter et Timestamp fra din database, og konverter derefter til en Instant .

java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;

Om java.time

java.time framework er indbygget i Java 8 og nyere. Disse klasser erstatter den besværlige gamle arv dato-tidsklasser såsom java. util.Dato , Kalender , &SimpleDateFormat .

Joda-Time projekt, nu i vedligeholdelsestilstand , anbefaler migrering til java.time klasser.

For at lære mere, se Oracle Tutorial . Og søg i Stack Overflow for mange eksempler og forklaringer. Specifikationen er JSR 310 .

Du kan udveksle java.time objekter direkte med din database. Brug en JDBC-driver i overensstemmelse med JDBC 4.2 eller senere. Intet behov for strenge, intet behov for java.sql.* klasser.

Hvor får man java.time klasserne?

ThreeTen-Extra projekt udvider java.time med yderligere klasser. Dette projekt er et bevisgrundlag for mulige fremtidige tilføjelser til java.time. Du kan finde nogle nyttige klasser her, såsom Interval , Årsuge , YearQuarter , og mere .




  1. Marker for at indsætte eller opdatere tabel

  2. Hvordan kan jeg indsætte data i SQL Server ved hjælp af VBNet

  3. Django-migreringer - er det muligt at bruge syd midt i projektet?

  4. ORA-01034:ORACLE ikke tilgængelig ORA-27101:delt hukommelsesrige eksisterer ikke