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).
) ;
Vyhněte se starším třídám podle data a času
Používáte hrozné třídy podle data a času, které byly před lety nahrazeny java.time třídy.
Nikdy nepoužívejte Date
nebo Timestamp
.
UTC
Zachyťte aktuální okamžik v UTC. Většina databází ukládá okamžik v UTC. A obecně byste měli většinu své obchodní logiky, ladění, protokolování, ukládání a výměnu dat provádět v UTC.
OffsetDateTime
Představte okamžik s odchylkou od UTC pomocí vhodně nazvaného OffsetDateTime
třída.
Chceme samotné UTC nebo offset nuly. K tomu můžeme použít konstantu ZoneOffset.UTC
.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;
JDBC 4.2
Od JDBC 4.2 můžeme přímo vyměňovat java.time objektů s databází.
Chcete-li uložit tento okamžik do sloupce datového typu podobného standardu SQL TIMESTAMP WITH TIME ZONE
:
myPreparedStatement.setObject( … , odt ) ;
Získání:
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime
Chcete-li zobrazit tento získaný okamžik uživateli, možná budete chtít upravit očekávané/požadované časové pásmo uživatele.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Nikdy se nespoléhejte na výchozí časové pásmo
Všimněte si v kódu výše, že jsme vždy specifikovali požadovaný/očekávaný offset nebo zónu.
Pokud neurčíte, posun nebo zóna se tiše implicitně použije. Lepší je explicitně specifikovat své záměry, protože aktuální výchozí nastavení vašeho JVM, databáze a hostitelského OS jsou mimo vaše ruce jako programátora. Což znamená, že kód spoléhající na výchozí nastavení se bude za běhu chovat různě.
Java 6 a 7
Stejný muž, Stephen Colebourne, který vede JSR 310 a java.time implementace, stejně jako slavný Joda-Time projekt, vede také další projekt, ThreeTen-Backport . Většina z java.time funkčnost je v této knihovně zpětně portována na Java 6 a 7 s téměř identickým API.
Veškerou svou práci tedy dělejte ve třídách back-port. Pak na poslední chvíli převeďte do/z java.sql.Timestamp
prostřednictvím DateTimeUtils
třída.
Tyto metody převodu většinou používají Instant
objektů. Instant
je okamžik v UTC, vždy v UTC. Můžete upravit z OffsetDateTime
na UTC extrahováním Instant
. Instant
class je základní třída stavebního bloku v java.time , s OffsetDateDate
mít větší flexibilitu, jako jsou alternativní vzory formátování při generování řetězce. Ale obojí Instant
a OffsetDateTime
představují okamžik, bod na časové ose.
Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;
Jděte opačným směrem a načtěte Timestamp
z vaší databáze a poté okamžitě převést na Instant
.
java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;
O java.time
java.time
framework je zabudován do Javy 8 a novější. Tyto třídy nahrazují staré problematické dědictví
třídy podle data a času, jako je java.util.Date
, Calendar
, &SimpleDateFormat
.
Čas Joda projekt, nyní v režimu údržby , doporučuje migraci na java.time třídy.
Další informace naleznete v Výukovém programu Oracle . A prohledejte Stack Overflow pro mnoho příkladů a vysvětlení. Specifikace je JSR 310 .
Můžete si vyměnit java.time objektů přímo s vaší databází. Použijte ovladač JDBC
v souladu s JDBC 4.2
nebo později. Není potřeba řetězců, není potřeba java.sql.*
třídy.
Kde získat třídy java.time?
- Java SE 8
, Java SE 9
, Java SE 10
, Java SE 11
a novější - Část standardního Java API s implementací v balíčku.
- Java 9 přidává některé drobné funkce a opravy.
- Java SE 6
a Java SE 7
- Většina z java.time funkčnost je zpětně portována na Java 6 a 7 v ThreeTen-Backport .
- Android
- Pozdější verze implementací balíčku java.time pro Android třídy.
- Pro starší Android (<26), ThreeTenABP projekt přizpůsobuje ThreeTen-Backport (zmíněno výše). Viz Jak používat ThreeTenABP… .
ThreeTen-Extra
projekt rozšiřuje java.time o další třídy. Tento projekt je zkušební půdou pro možná budoucí rozšíření java.time. Zde můžete najít některé užitečné třídy, jako je Interval
, YearWeek
, YearQuarter
a další
.