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?
- Java SE 8
, Java SE 9
, Java SE 10
, Java SE 11
, och senare - En del av standard Java API med en medföljande implementering.
- Java 9 lägger till några mindre funktioner och korrigeringar.
- Java SE 6
och Java SE 7
- Det mesta av java.time Funktionaliteten är backporterad till Java 6 &7 i ThreeTen-Backport .
- Android
- Senare versioner av Android-paketimplementeringar av java.time klasser.
- För tidigare Android (<26), ThreeTenABP projektet anpassar ThreeTen-Backport (nämnts ovan). Se Hur du använder ThreeTenABP... .
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
.