java.time
S vydáním Java SE 8 v březnu 2014, zastaralé a k chybám náchylné starší rozhraní Date-Time API (java.util
Typy data a času a jejich typ formátování, SimpleDateFormat
atd.) byl nahrazen java.time
, moderní rozhraní Date-Time API. následující tabulka
znázorňuje mapování typů ANSI SQL pomocí java.time
typy:
ANSI SQL | Java SE 8 |
---|---|
DATUM | LocalDate |
ČAS | Místní čas |
TIMESTAMP | LocalDateTime |
ČAS S ČASOVÝM PÁSEM | Čas odsazení |
ČASOVÉ RAZÍTKO S ČASOVÝM PÁSEM | OffsetDateTime |
Všimněte si, že ZonedDateTime
a Instant
nejsou podporovány žádným ovladačem JDBC, zatímco některé ovladače, např. PostgreSQL také nepodporuje OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Všimněte si také, že všechny OffsetDateTime
instance budou muset být v UTC (mají offset 0). Je to proto, že je backend ukládá jako UTC.
Jak jej používat v JDBC?
Níže je uveden ukázkový kód pro vložení aktuálního OffsetDateTime
v UTC do columnfoo
(což je z TIMESTAMP WITH TIMEZONE
typ):
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
Instant
představuje okamžitý bod na časové ose a je nezávislý na časovém pásmu, tj. má posun časového pásma +00:00
hodin.
Níže je uveden ukázkový kód pro načtení OffsetDateTime
z columnfoo
:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
// Assuming the column index of columnfoo is 1
OffsetDateTime odt = rs.getObject(1, OffsetDateTime.class));
System.out.println(odt);
}
rs.close();
st.close();
Pro případ, že byste potřebovali převést OffsetDateTime
do jiného s jiným posunem:
Existuje několik způsobů, jak to udělat, ale většinou používám OffsetDateTime#withOffsetSameInstant
, pro převod OffsetDateTime
do jiného s jiným posunem časového pásma, např.
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
// A sample OffsetDateTime in UTC.
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
System.out.println(odt);
OffsetDateTime offsetTimeAtOffset0100 = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
System.out.println(offsetTimeAtOffset0100);
// Time at JVM's default timezone offset
ZoneOffset jvmTzOffset = ZonedDateTime.now(ZoneId.systemDefault()).getOffset();
OffsetDateTime offsetTimeAtJvmTzOffset = odt.withOffsetSameInstant(jvmTzOffset);
System.out.println(offsetTimeAtJvmTzOffset);
}
}
Výstup:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Některé body související s kódem uvedeným výše:
Z
ve výstupu je označení časového pásma pro posun nulového časového pásma. Zkratka pro Zulu a specifikujeEtc/UTC
časové pásmo (které má posun časového pásma+00:00
hodiny).- Kód převádí
odt
do dvou instancíOffsetDateTime
- každý jiným způsobem. První instance je s pevným posunem časového pásma+02:00
hodin, zatímco druhý je s posunem časového pásma JVM. Všimněte si, že posun časového pásma místa pozorujícího DST mění se podle letního/zimního času. Pokud tedy místo dodržuje letní čas, místo použití pevného posunu časového pásma, např.+02:00
hodiny; měli bychom to získat z API. - Časové pásmo mého JVM je
Europe/London
a aktuálně je jeho offset+01:00
hodin.
Další informace o moderním rozhraní API pro datum a čas z Trail:Date Time .