java.time
С пускането на Java SE 8 през март 2014 г., остарелият и податлив на грешки наследен API за дата-време (java.util Типове дата-час и техният тип форматиране, SimpleDateFormat и т.н.) беше заменен от java.time , съвременният API за дата-време. Следната таблица
изобразява съпоставянето на ANSI SQL типове с java.time видове:
| ANSI SQL | Java SE 8 |
|---|---|
| ДАТА | LocalDate |
| ВРЕМЕ | Местно време |
| TIMESTAMP | LocalDateTime |
| ВРЕМЕ С ЧАСОВА ЗОНА | OffsetTime |
| ЧАСОВА ПЕЧАТА С ЧАСОВА ЗОНА | OffsetDateTime |
Имайте предвид, че ZonedDateTime и Instant не се поддържат от нито един JDBC драйвер, докато някои драйвери, напр. PostgreSQL също не поддържа OffsetTime / TIME [ WITHOUT TIMEZONE ] . Също така имайте предвид, че всички OffsetDateTime екземплярите трябва да са в UTC (да имат отместване 0). Това е така, защото бекенда ги съхранява като UTC.
Как да го използвам в JDBC?
По-долу е даден примерен код за вмъкване на текущия OffsetDateTime в UTC, в columnfoo (което е от TIMESTAMP WITH TIMEZONE тип):
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
представлява моментна точка на времевата линия и е независима от часова зона, т.е. има изместване на часовата зона от +00:00 часа.
По-долу е даден примерен код за извличане на OffsetDateTime от 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();
Само в случай, че трябва да конвертирате OffsetDateTime в друг с различно изместване:
Има няколко начина да го направя, но най-вече използвам OffsetDateTime#withOffsetSameInstant
, за да конвертирате OffsetDateTime в друг с различно изместване на часовата зона, напр.
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);
}
}
Изход:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Някои точки, свързани с кода, даден по-горе:
Zв изхода е индикаторът на часовата зона за изместване на нулева часова зона. Той означава Zulu и определяEtc/UTCчасова зона (която има изместване на часовата зона от+00:00часа).- Кодът преобразува
odtв два екземпляра наOffsetDateTime- всеки по различен начин. Първият екземпляр е с фиксирано изместване на часовата зона от+02:00часа, докато вторият е с изместване на часовата зона на JVM. Имайте предвид, че изместването на часовата зона на място, което наблюдава DST промени според лятно/зимно часово време. Следователно, ако дадено място спазва DST, вместо да се използва фиксирано изместване на часовата зона, напр.+02:00часа; трябва да го получим от API. - Часовата зона на моята JVM е
Europe/Londonи в момента нейното изместване е+01:00часа.
Научете повече за модерния API за дата и време от Пътека:Дата и час .