Kahanan saiki saka wektu

Wiwit nalika JDBC diciptakake lan antarmuka standar, 20 taun wis liwati, lan ing wektu iki akeh perkara sing wis diganti.

Kaping pisanan, jagad wis dadi global lan saiki siji server bisa nglayani pangguna saka saindenging jagad. Kacepetan internet munggah. Mulane, jinis data liyane ditambahake menyang SQL kanggo nggarap wektu. Saiki jinis katon kaya iki:

  • DATE - nyimpen tanggal: taun, sasi, dina.
  • TIME - nyimpen wektu: jam, menit, detik.
  • TIMESTAMP - nyimpen titik tartamtu ing wektu: tanggal, wektu lan milliseconds.
  • TIMESTAMP WITH TIME ZONE - TIMESTAMP lan zona wektu (jeneng zona utawa offset).

Kapindho, Jawa ngenalake DateTime API kanggo manajemen wektu global. Wis kelas ing ngisor iki:

  • Tanggal lan wektu :
    • LocalDate
    • Wektu Lokal
  • Wektu sing tepat :
    • java.wektu.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime
  • Wektu karo zona wektu :
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

Titik menarik katelu yaiku akeh klien SQL sing pengin nampa wektu saka server sing wis ana ing zona lokal . Mesthi, sampeyan bisa ngowahi wektu ing fly, nanging ora trep, lan ana kesalahane.

Contone, aku pengin njaluk kabeh tugas kanggo dina iki saka database. SQL Server nduweni fungsi CURDATE() kanggo iki. Mung kene server ing Amerika Serikat, lan aku ing Jepang. Lan aku pengin dheweke bali kabeh cathetan kanggo "dina iki", lan ora "dina iki".

Umumé, server SQL uga kudu bisa kerja cerdas karo klien ing zona wektu sing beda.

Masalah modern mbutuhake solusi modern

Umumé, jinis anyar saka Java DateTime API lan jinis saka SQL bisa gampang dipetakan. Kanggo makili jinis DATE ing Jawa, sampeyan kudu nggunakake java.time.LocalDate kelas saka JDK 8 DateTime API.

Jinis TIME saka database bisa diwakili dening rong jinis saka Jawa: java.time.LocalTime lan java.time.OffsetTime . Ora ana sing rumit.

Titik wektu tartamtu, diwakili dening jinis TIMESTAMP ing basis data, bisa diwakili ing Jawa kanthi 4 jinis:

  • java.wektu.Instant
  • java.time.LocalDateTime
  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

Lan pungkasane, TIMESTAMP WITH TIME ZONE bisa diwakili dening rong jinis:

  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

Amarga sampeyan wis kenal karo DateTime API, ngelingi perkara iki ora bakal angel kanggo sampeyan :)

Aku bakal nulis ing wangun tabel, supaya luwih gampang:

JENIS SQL Tipe Jawa
TANGGAL java.time.LocalDate
WAKTU java.time.LocalTime
java.time.OffsetTime
TIMESTAMP java.time.Instant
java.time.LocalDateTime
java.time.OffsetDateTime
java.time.ZonedDateTime
TIMESTAMP KARO ZONA WAKTU java.time.OffsetDateTime
_

Njupuk tanggal

Aku duwe kabar apik kanggo sampeyan. Pisanan ing dangu. Kita bisa ngubengi watesan metode getDate () , sing ngasilake jinis Tanggal java.sql.

Intine yaiku obyek kasebutset asilana cara liyane sing menarik - getObject () . Cara iki njupuk rong paramèter: kolom lan jinis, lan ngasilake nilai kolom sing diowahi menyang jinis tartamtu. Bentuk umum saka metode kasebut yaiku:

ClassName Name = getObject(column, ClassName);

Lan yen sampeyan pengin ngowahi jinis DATE menyang jinis java.time.LocalDate , sampeyan kudu nulis kaya:

LocalDate localDate = results.getObject(4, LocalDate.class);

Lan TIMESTAMP umume bisa diowahi dadi pirang-pirang jinis:

java.time.Instant instant = results.getObject(9, java.time.Instant.class);
java.time.LocalDateTime local = results.getObject(9, java.time. LocalDateTime.class);
java.time.OffsetDateTime offset = results.getObject(9, java.time. OffsetDateTime.class);
java.time.ZonedDateTime zoned = results.getObject(9, java.time. ZonedDateTime.class);

Penting! Kode iki ora bakal bisa digunakake yen sampeyan duwe MySQL JDBC Driver lawas . Pay manungsa waé kanggo versi "mysql-konektor-java" ditulis ing pom.xml Panjenengan, utawa ditambahake menyang Pustaka ing setelan project.

Miturut cara, kanthi cara sing padha, sampeyan bisa ngubengi kasekengan kanggo nyimpen null kanggo jinis primitif. Yen kolom tabel saka jinis INT, banjur ana sawetara cara kanggo null saka iku. Deleng conto ing ngisor iki:

Integer id1 = results.getObject(8, Integer.class);    	 // this will work
Integer id2 = results.getObject(8, int.class);                 //this will also work
int id3 = results.getObject(8,  Integer.class);            	//method will return null, JVM will throw NPE
int id4 = results.getObject(8,  int.class);                    	//method will return null, JVM will throw NPE

Setelan zona wektu ing MySQL

Akeh kedadeyan sing menarik karo MySQL uga. Kaya sing sampeyan ngerteni, nalika nggawe sambungan MySQL, sampeyan bisa nambah macem-macem parameter :
mysql://localhost:3306/db_scheme?Name=meaning&Name=meaning

Dadi, telung paramèter wis ditambahake kanggo nggarap zona wektu ing MySQL. Sampeyan bisa ngliwati paramèter kasebut nalika nggawe sambungan menyang server.

Ing ngisor iki aku bakal menehi meja karo dheweke:

Parameter Nilai Nilai standar
koneksiTimeZone LOKAL | SERVER | zona panganggo SERVER
forceConnectionTimeZoneToSession bener | palsu bener
preserveInstants bener | palsu palsu

Nggunakake parameter connectionTimeZone , kita milih zona wektu (zona wektu) ing ngendi kabeh panjalukan bakal dileksanakake. Saka sudut pandang klien, server mlaku ing zona wektu sing ditemtokake.

Parameter forceConnectionTimeZoneToSession nyebabake variabel time_zone sesi ora digatekake lan diganti karo connectionTimeZone.

Pungkasan, parameter preserveInstants ngontrol konversi pas-wektu antarane timeZone JVM lan connectionTimeZone.

Konfigurasi sing paling umum yaiku:

  • connectionTimeZone = LOKAL & forceConnectionTimeZoneToSession = palsu - cocog karo driver MySQL JDBC lawas versi 5.1 karo useLegacyDatetimeCode = bener.

  • connectionTimeZone=LOCAL & forceConnectionTimeZoneToSession=true yaiku mode anyar sing nyedhiyakake cara paling alami kanggo nangani nilai tanggal lan wektu.

  • connectionTimeZone=SERVER & preserveInstants=true - Cocog karo driver MySQL JDBC lawas versi 5.1 karo useLegacyDatetimeCode=palsu.

  • connectionTimeZone=user_defined & preserveInstants=true - Mbantu ngatasi kahanan zona wektu server ora bisa dikenali dening konektor amarga disetel minangka singkatan umum kayata CET / CEST.

Ya, tanggal minangka topik sing menarik lan akeh masalah karo dheweke. Kaya sing dicritakake: medeni, mesthi, nanging aku uga ora nesu! :)