sql >> Databasteknik >  >> RDS >> Mysql

Java Datum och MySQL tidsstämpel 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).
) ;

Undvik äldre klasser med datum och tid

Du använder fruktansvärda datum-tid-klasser som ersattes för flera år sedan av java.time klasser.

Använd aldrig Datum eller Timestamp .

UTC

Fånga det aktuella ögonblicket, i UTC. De flesta databaser lagrar ett ögonblick i UTC. Och generellt sett bör du göra det mesta av din affärslogik, felsökning, loggning, lagring och datautbyte i UTC.

OffsetDateTime

Representera ett ögonblick med en offset-från-UTC med det passande namnet OffsetDateTime klass.

Vi vill ha UTC själv, eller en offset på noll. Vi kan använda en konstant för det, ZoneOffset.UTC .

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

JDBC 4.2

Från och med JDBC 4.2 kan vi direkt byta ut java.time objekt med databasen.

För att spara detta ögonblick i en kolumn av en datatyp som liknar SQL-standarden TIMESTAMP WITH TIME ZONE :

myPreparedStatement.setObject( … , odt ) ;

Hämtning:

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

ZonedDateTime

För att presentera detta hämtade ögonblick för användaren kanske du vill anpassa dig till användarens förväntade/önskade tidszon.

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

Lita aldrig på standardtidszon

Lägg märke till i koden ovan att vi alltid angav önskad/förväntad offset eller zon.

Om du inte anger, tillämpas en förskjutning eller zon tyst implicit. Bättre att specificera dina avsikter explicit eftersom den nuvarande standarden för din JVM, databas och värdoperativsystem är ur dina händer som programmerare. Vilket innebär att kod som förlitar sig på standarden kommer att variera i beteende under körning.

Java 6 &7

Samma man, Stephen Colebourne, som leder JSR 310 och java.time implementering, såväl som den berömda Joda-Time projekt, leder också ett annat projekt, ThreeTen-Backport . Det mesta av java.time Funktionaliteten backporteras till Java 6 och 7 i detta bibliotek, med nästan identisk API.

Så gör allt ditt arbete i back-port klasser. Sedan, i sista stund, konvertera till/från java.sql.Timestamp via DateTimeUtils klass.

Dessa konverteringsmetoder använder oftast Instant objekt. En Instant är ett ögonblick i UTC, alltid i UTC. Du kan justera från din OffsetDateTime till UTC genom att extrahera en Instant . Instant class är den grundläggande byggstensklassen i java.time , med OffsetDateDate ha mer flexibilitet som alternativa formateringsmönster när en sträng genereras. Men båda Instant och OffsetDateTime representera ett ögonblick, en punkt på tidslinjen.

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

Gå åt andra hållet och hämta en Timestamp från din databas och konvertera sedan omedelbart till ett Instant .

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

Om java.time

java.time ramverket är inbyggt i Java 8 och senare. Dessa klasser ersätter det besvärliga gamla arvet datum-tid-klasser som java. util.Datum , Kalender , &SimpleDateFormat .

Joda-Time projekt, nu i underhållsläge , rekommenderar migrering till java.time klasser.

Om du vill veta mer, se Oracle Tutorial . Och sök på Stack Overflow för många exempel och förklaringar. Specifikationen är JSR 310 .

Du kan byta ut java.time objekt direkt med din databas. Använd en JDBC-drivrutin kompatibel med JDBC 4.2 eller senare. Inget behov av strängar, inget behov av java.sql.* klasser.

Var får man tag i java.time-klasserna?

ThreeTen-Extra projektet utökar java.time med ytterligare klasser. Detta projekt är en provningsgrund för möjliga framtida tillägg till java.time. Du kan hitta några användbara klasser här som Intervall , YearWeek , YearQuarter , och mer .




  1. oracle radera data från fjärr SQL Server-tabellen

  2. Ladda data från CSV till mySQL-databasen Java+hibernate+spring

  3. Använder r sf::st_write till icke-offentligt schema i PostgreSQL

  4. Ansluter till fjärr SQL Server 2008 från Windows Azure