tl; dr
java.util.Date.from( // Transfer the moment in UTC, truncating any microseconds or nanoseconds to milliseconds.
Instant.now() ; // Capture current moment in UTC, with resolution as fine as nanoseconds.
)
Padahal tidak ada gunanya kode di atas. Keduanya java.util.Date
dan Instant
mewakili momen dalam UTC, selalu dalam UTC. Kode di atas memiliki efek yang sama seperti:
new java.util.Date() // Capture current moment in UTC.
Tidak ada manfaat di sini untuk digunakan ZonedDateTime
. Jika Anda sudah memiliki ZonedDateTime
, sesuaikan ke UTC dengan mengekstrak file Instant
.
java.util.Date.from( // Truncates any micros/nanos.
myZonedDateTime.toInstant() // Adjust to UTC. Same moment, same point on the timeline, different wall-clock time.
)
Jawaban Lain Benar
The Answer oleh ssoltanid benar alamat pertanyaan spesifik Anda, bagaimana mengkonversi objek java.time baru-sekolah ( ZonedDateTime
) untuk sekolah tua java.util.Date
objek. Ekstrak Instant
dari ZonedDateTime dan teruskan ke java.util.Date.from()
.
Data hilang
Perhatikan bahwa Anda akan mengalami kehilangan data , karena Instant
melacak nanodetik sejak epoch sementara java.util.Date
melacak milidetik sejak epoch.
Pertanyaan dan komentar Anda mengangkat masalah lain.
Pertahankan Server Dalam UTC
Server Anda harus mengatur OS host mereka ke UTC sebagai praktik terbaik secara umum. JVM mengambil pengaturan OS host ini sebagai zona waktu default-nya, dalam implementasi Java yang saya ketahui.
Tentukan Zona Waktu
Tetapi Anda tidak boleh bergantung pada zona waktu default JVM saat ini. Daripada mengambil pengaturan host, bendera yang diteruskan saat meluncurkan JVM dapat mengatur zona waktu lain. Lebih buruk lagi: Kode apa pun di utas apa pun dari aplikasi apa pun kapan saja dapat melakukan panggilan ke java.util.TimeZone::setDefault
untuk mengubah default itu pada waktu proses!
Timestamp
Jenis Cassandra
Setiap basis data dan driver yang layak harus secara otomatis menangani penyesuaian waktu tanggal yang dilewati ke UTC untuk penyimpanan. Saya tidak menggunakan Cassandra, tetapi tampaknya memiliki beberapa dukungan dasar untuk tanggal-waktu. Dokumentasi mengatakan bahwa Timestamp
tipenya adalah hitungan milidetik dari periode yang sama (momen pertama tahun 1970 di UTC).
ISO 8601
Selanjutnya, Cassandra menerima input string dalam format standar ISO 8601 . Untungnya, java.time menggunakan format ISO 8601 sebagai default untuk parsing / menghasilkan string. The Instant
kelas toString
implementasi akan melakukan dengan baik.
Presisi: Milidetik vs Nano
Tapi pertama-tama kita perlu mengurangi presisi nanodetik dari ZonedDateTime ke milidetik. Salah satu caranya adalah membuat Instan baru menggunakan milidetik. Untungnya, java.time memiliki beberapa metode praktis untuk mengonversi ke dan dari milidetik.
Kode Contoh
Berikut beberapa contoh kode di Java 8 Update 60.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
…
Instant instant = zdt.toInstant();
Instant instantTruncatedToMilliseconds = Instant.ofEpochMilli( instant.toEpochMilli() );
String fodderForCassandra = instantTruncatedToMilliseconds.toString(); // Example: 2015-08-18T06:36:40.321Z
Atau menurut dokumen driver Cassandra Java ini , Anda dapat memberikan java.util.Date
contoh (jangan bingung dengan java.sqlDate
). Jadi Anda bisa membuat juDate dari itu instantTruncatedToMilliseconds
pada kode di atas.
java.util.Date dateForCassandra = java.util.Date.from( instantTruncatedToMilliseconds );
Jika sering melakukan ini, Anda bisa membuat satu baris.
java.util.Date dateForCassandra = java.util.Date.from( zdt.toInstant() );
Tetapi akan lebih baik jika membuat sedikit metode utilitas.
static public java.util.Date toJavaUtilDateFromZonedDateTime ( ZonedDateTime zdt ) {
Instant instant = zdt.toInstant();
// Data-loss, going from nanosecond resolution to milliseconds.
java.util.Date utilDate = java.util.Date.from( instant ) ;
return utilDate;
}
Perhatikan perbedaan di semua kode ini daripada di Pertanyaan. Kode Pertanyaan mencoba menyesuaikan zona waktu contoh ZonedDateTime ke UTC. Tapi itu tidak perlu. Secara konseptual:
ZonedDateTime = Instan + ZoneId
Kami hanya mengekstrak bagian Instan, yang sudah dalam UTC (pada dasarnya dalam UTC, baca dokumen kelas untuk detail tepatnya).
Tentang java.time
The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti java.util.Date
, Calendar
, & SimpleDateFormat
.
Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .
Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasinya adalah JSR 310 .
Anda dapat bertukar objek java.time langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu string, tidak perlu java.sql.*
kelas.
Dimana mendapatkan kelas java.time?
Proyek ThreeTen-Extra memperluas java.time dengan kelas tambahan. Proyek ini adalah tempat pembuktian untuk kemungkinan penambahan java.time di masa mendatang. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval
, YearWeek
, YearQuarter
, dan lebih .
java.util.Date
danjava.sql.Date
.