java.time
Dengan dirilisnya Java SE 8 pada bulan Maret 2014, API Date-Time lawas yang sudah ketinggalan zaman dan rawan kesalahan (java.util
Jenis Tanggal-Waktu dan jenis pemformatannya, SimpleDateFormat
dll.) digantikan oleh java.time
, API Tanggal-Waktu modern. tabel berikut
menggambarkan pemetaan tipe ANSI SQL dengan java.time
jenis:
ANSI SQL | Java SE 8 |
---|---|
TANGGAL | Tanggal Lokal |
WAKTU | Waktu Lokal |
TIMESTAMP | WaktuTanggalLokal |
WAKTU DENGAN ZONA WAKTU | OffsetTime |
TIMESTAMP DENGAN ZONA WAKTU | OffsetDateTime |
Perhatikan bahwa ZonedDateTime
dan Instant
tidak didukung oleh driver JDBC mana pun sedangkan beberapa driver mis. PostgreSQL juga tidak mendukung OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Juga, perhatikan bahwa semua OffsetDateTime
instance harus dalam UTC (memiliki offset 0). Ini karena backend menyimpannya sebagai UTC.
Bagaimana cara menggunakannya di JDBC?
Diberikan di bawah ini adalah contoh kode untuk memasukkan OffsetDateTime
saat ini di UTC, ke columnfoo
(yang merupakan TIMESTAMP WITH TIMEZONE
jenis):
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
Sebuah Instant
mewakili titik seketika pada garis waktu dan tidak bergantung pada zona waktu yaitu memiliki zona waktu offset +00:00
jam.
Diberikan di bawah ini adalah contoh kode untuk mengambil OffsetDateTime
dari 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();
Untuk berjaga-jaga jika Anda perlu mengonversi OffsetDateTime
ke yang lain dengan offset yang berbeda:
Ada beberapa cara untuk melakukannya tetapi saya kebanyakan menggunakan OffsetDateTime#withOffsetSameInstant
, untuk mengonversi OffsetDateTime
ke yang lain dengan offset zona waktu yang berbeda, mis.
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);
}
}
Keluaran:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Beberapa poin terkait dengan kode yang diberikan di atas:
Z
dalam output adalah penanda zona waktu untuk offset zona waktu nol. Itu singkatan dari Zulu dan menentukanEtc/UTC
zona waktu (yang memiliki offset zona waktu+00:00
jam).- Kode mengonversi
odt
menjadi dua contohOffsetDateTime
- masing-masing dengan cara yang berbeda. Contoh pertama adalah dengan offset zona waktu tetap+02:00
jam sedangkan yang kedua adalah dengan offset zona waktu JVM. Perhatikan bahwa offset zona waktu suatu tempat mengamati DST berubah sesuai waktu musim panas/musim dingin. Oleh karena itu, jika suatu tempat mengamati DST, alih-alih menggunakan offset zona waktu tetap, mis.+02:00
jam; kita harus mendapatkannya dari API. - Zona waktu JVM saya adalah
Europe/London
dan saat ini offsetnya adalah+01:00
jam.
Pelajari lebih lanjut tentang API tanggal-waktu modern dari Jejak:Tanggal Waktu .