Dipotong menjadi mikrodetik
Jelas kami tidak dapat menekan nanodetik
resolusi Instant
ke dalam mikrodetik
resolusi tipe data MySQL DateTime
dan Timestamp
.
Meskipun saya tidak menggunakan MySQL, saya membayangkan driver JDBC
dibuat untuk mengabaikan nanodetik saat menerima Instant
, memotong nilai menjadi mikrodetik. Saya sarankan Anda mencoba eksperimen untuk melihat, dan mungkin memeriksa kode sumber driver Anda yang sesuai dengan JDBC 4.2 dan yang lebih baru.
Instant instant = Instant.now().with( ChronoField.NANO_OF_SECOND , 123_456_789L ) ; //Set the fractional second to a spefic number of nanoseconds.
myPreparedStatement.setObject( … , instant ) ;
…dan…
Instant instant2 = myResultSet.getObject( … , Instant.class ) ;
Spesifikasi JDBC 4.2
memerlukan dukungan untuk OffsetDateTime
tapi anehnya tidak memerlukan dua jenis yang lebih umum digunakan, Instant
dan ZonedDateTime
. Jika pengemudi JDBC
Anda tidak mendukung Instant
, konversi.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; // Use `OffsetDateTime` if your JDBC driver does not support `Instant`.
Instant instant2 = odt.toInstant() ; // Convert from `OffsetDateTime` to `Instant`.
Kemudian bandingkan.
Boolean result = instant.equals( instant2 ) ;
System.out.println( "instant: " + instant + " equals instant2: = " + instant2 + " is: " + result ) ;
Anda dengan bijak mengkhawatirkan nilai yang diambil dari database yang tidak cocok dengan nilai aslinya. Salah satu solusi, jika dapat diterima untuk masalah bisnis Anda, adalah memotong setiap nanodetik ke mikrodetik dalam data asli Anda. Saya merekomendasikan pendekatan ini secara umum.
java.time kelas menawarkan truncatedTo
metode. Lewati ChronoUnit
enum objek untuk menentukan granularitas. Dalam hal ini, itu adalah ChronoUnit.MICROS
.
Instant instant = Instant().now().truncatedTo( ChronoUnit.MICROS ) ;
Saat ini pendekatan ini sudah cukup karena Anda tidak mungkin memiliki nanodetik dalam data Anda. Komputer arus utama saat ini tidak menggunakan jam perangkat keras yang mampu menangkap nanodetik, sejauh yang saya tahu.
Hitung dari zaman
Jika Anda tidak mampu kehilangan data nanodetik apa pun yang mungkin ada, gunakan hitungan dari zaman.
Saya biasanya merekomendasikan untuk tidak melacak waktu-tanggal sebagai hitungan dari tanggal referensi zaman. Tetapi Anda memiliki beberapa pilihan lain dalam menyimpan nilai berbasis nanodetik Anda dalam database seperti MySQL dan Postgres terbatas pada nilai berbasis mikrodetik.
Menyimpan pasangan bilangan bulat
Daripada menggunakan jumlah nanodetik yang sangat besar sejak zaman seperti 1970-01-01T00:00Z, saya sarankan mengikuti pendekatan yang diambil oleh internal Instant
kelas:Gunakan pasangan angka.
Simpan sejumlah utuh detik sebagai bilangan bulat dalam database Anda. Di kolom kedua, simpan sebagai bilangan bulat jumlah nanodetik dalam pecahan detik.
Anda dapat dengan mudah mengekstrak/menyuntikkan angka-angka ini dari/ke Instant
obyek. Hanya long
64-bit sederhana nomor yang terlibat; tidak perlu BigDecimal
atau BigInteger
. Saya kira Anda mungkin dapat menggunakan kolom bilangan bulat 32-bit untuk setidaknya satu dari dua angka. Tapi saya akan memilih tipe kolom integer 64-bit untuk kesederhanaan dan untuk kompatibilitas langsung dengan java.time.Instant
sepasang long class.
long seconds = instant.getEpochSecond() ;
long nanos = instant.getNano() ;
…dan…
Instant instant = Instant.ofEpochSecond( seconds , nanos ) ;
Saat menyortir secara kronologis, Anda harus melakukan pengurutan bertingkat, pengurutan pertama pada kolom detik penuh, lalu pengurutan kedua pada kolom nano pecahan detik.