Jawaban lain benar, terutama jawaban java.time oleh arganzheng . Seperti yang disebutkan beberapa orang, Anda harus menghindari kelas java.util.Date/.Calendar yang lama karena kelasnya dirancang dengan buruk, membingungkan, dan menyusahkan. Mereka telah digantikan oleh kelas java.time.
Izinkan saya menambahkan catatan tentang strategi penanganan tengah malam dan rentang waktu .
Setengah Terbuka
Dalam pekerjaan waktu-tanggal, rentang waktu sering didefinisikan menggunakan pendekatan "Setengah Terbuka". Dalam pendekatan ini, permulaan bersifat inklusif sedangkan akhiran bersifat eksklusif . Ini menyelesaikan masalah dan jika digunakan secara konsisten membuat alasan tentang penanganan tanggal Anda jauh lebih mudah.
Satu masalah yang dipecahkan adalah mendefinisikan akhir hari. Apakah momen terakhir dalam sehari 23:59:59.999
( milidetik )? Mungkin, di kelas java.util.Date (dari Jawa paling awal; merepotkan - hindari kelas ini!) Dan di perpustakaan Joda-Time yang sangat sukses . Tetapi dalam perangkat lunak lain, seperti database seperti Postgres, saat terakhir adalah 23:59:59.999999
( mikrodetik ). Tetapi dalam perangkat lunak lain seperti kerangka java.time (dibangun ke dalam Java 8 dan yang lebih baru, penerus Joda-Time) dan dalam beberapa database seperti H2 Database , momen terakhir mungkin 23:59.59.999999999
( nanoseconds ). Alih-alih membelah rambut, pikirkan dalam hal saat pertama saja, bukan saat terakhir.
Di Setengah Terbuka, satu hari berjalan dari saat pertama dalam satu hari dan naik ke atas tetapi tidak termasuk saat pertama pada hari berikutnya. Jadi daripada berpikir seperti ini:
… Mulai hari ini pukul 00:00 (tengah malam dini hari tadi) hingga pukul 12:00 (tengah malam malam ini).
... berpikir seperti ini ...
dari saat pertama hari ini berjalan hingga tetapi tidak termasuk saat pertama besok:
(> = 00:00:00.0
hari ini DAN < 00:00:00.0
besok)
Dalam pekerjaan basis data, pendekatan ini berarti tidak menggunakan BETWEEN
operator dalam SQL.
Mulai hari ini
Lebih jauh lagi, momen pertama hari itu tidak selalu merupakan waktu hari itu 00:00:00.0
. Daylight Saving Time (DST) di beberapa zona waktu, dan mungkin anomali lain, dapat berarti waktu yang berbeda memulai hari.
Jadi, biarkan kelas java.time melakukan pekerjaan menentukan awal hari dengan panggilan ke LocalDate::atStartOfDay( ZoneId )
. Jadi kita harus melewati LocalDate
dan kembali ZonedDateTime
seperti yang Anda lihat dalam kode contoh ini.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );
Perhatikan lewatnya opsional ZoneId
. Jika dihilangkan zona waktu default JVM Anda saat ini diterapkan secara implisit. Lebih baik bersikap eksplisit.
Zona waktu sangat penting untuk pekerjaan tanggal-waktu. Pertanyaan dan beberapa Jawaban lainnya berpotensi cacat karena tidak secara sadar menangani zona waktu.
Mengubah
Jika Anda harus menggunakan java.util.Date atau .Calendar, cari metode konversi baru yang ditambahkan ke kelas lama tersebut.
java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );
Rentang waktu
Omong-omong, jika Anda melakukan banyak pekerjaan dengan rentang waktu, perhatikan:
Duration
Period
Interval
The Interval
kelas ditemukan dalam ThreeTen-Extra proyek, perpanjangan kerangka java.time. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time.
Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );
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. Spesifikasi adalah JSR 310 .
Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlu untuk java.sql.*
kelas.
Di mana mendapatkan kelas java.time?
Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval
, YearWeek
, YearQuarter
, dan lebih .