Dalam kode saya, saya perlu menemukan semua hal yang terjadi hari ini. Jadi saya perlu membandingkan tanggal mulai hari ini pukul 00:00 (tengah malam dini hari ini) hingga pukul 12:00 malam (tengah malam malam ini).
Aku tahu ...
Date today = new Date();
... menangkap saya sekarang. Dan ...
Date beginning = new Date(0);
... membuat saya nol waktu pada 1 Januari 1970. Tapi apa cara mudah untuk mendapatkan nol waktu hari ini dan nol waktu besok?
MEMPERBARUI; Saya melakukan ini, tetapi pasti ada cara yang lebih mudah?
Calendar calStart = new GregorianCalendar();
calStart.setTime(new Date());
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
Date midnightYesterday = calStart.getTime();
Calendar calEnd = new GregorianCalendar();
calEnd.setTime(new Date());
calEnd.set(Calendar.DAY_OF_YEAR, calEnd.get(Calendar.DAY_OF_YEAR)+1);
calEnd.set(Calendar.HOUR_OF_DAY, 0);
calEnd.set(Calendar.MINUTE, 0);
calEnd.set(Calendar.SECOND, 0);
calEnd.set(Calendar.MILLISECOND, 0);
Date midnightTonight = calEnd.getTime();
java.util.Date
,java.util.Calendar
, danjava.text.SimpleDateFormat
sekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .Jawaban:
java.util.Calendar
JDK 8 - java.time.LocalTime dan java.time.LocalDate
Joda-Time
Jika Anda menggunakan JDK <8, saya sarankan Joda Time , karena APInya sangat bagus:
Karena Joda Time versi 2.3
DateMidnight
sudah tidak digunakan lagi , jadi gunakan ini:Lewati zona waktu jika Anda tidak ingin zona waktu default JVM saat ini.
sumber
toDateMidnight
sudah usang. Lihat jawaban ini untuk detail: stackoverflow.com/a/19048833/363573ZonedDateTime
) seperti yang Anda lakukan di bagian Joda-Time. TheLocal…
jenis tidak memiliki informasi zona waktu - yang seluruh tujuan mereka, tidak ada kehilangan / mengabaikan semua offset dan zona waktu rincian. Terutama ketika Pertanyaan berbicara tentang menggunakan nilai-nilai ini untuk perbandingan (mungkin permintaan basis data?), Nilai tanggal-waktu yang dikategorikan cenderung lebih berguna.Demi kelengkapan, jika Anda menggunakan Java 8 Anda juga dapat menggunakan
truncatedTo
metodeInstant
kelas untuk mendapatkan tengah malam di UTC .Seperti yang tertulis di Javadoc
Semoga ini bisa membantu.
sumber
Date.from(date.toInstant().atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS).toInstant())
truncatedTo
danatStartOfDay
.Cara termudah untuk menemukan tengah malam:
Hari berikutnya:
sumber
Ingat,
Date
ini tidak digunakan untuk mewakili tanggal (!). Untuk mewakili tanggal, Anda memerlukan kalender. Ini:akan membuat
Calendar
instance yang mewakili tanggal sekarang di zona waktu Anda saat ini. Sekarang yang Anda butuhkan adalah memotong setiap bidang di bawah hari (jam, menit, detik, dan milidetik) dengan mengaturnya ke0
. Anda sekarang memiliki tengah malam hari ini.Sekarang untuk mendapatkan tengah malam hari berikutnya, Anda perlu menambahkan satu hari:
Perhatikan bahwa menambahkan
86400
detik atau 24 jam salah karena waktu musim panas yang mungkin terjadi sementara itu.PEMBARUAN: Namun cara favorit saya untuk mengatasi masalah ini adalah dengan menggunakan kelas DateUtils dari Commons Lang :
Itu menggunakan di
Calendar
belakang layar ...sumber
metode ini akan membantu Anda-
dan
sumber
Pada JodaTime 2.3,
toDateMidnight()
sudah usang.Dari Tingkatkan dari 2.2 ke 2.3
Berikut adalah contoh kode tanpa
toDateMidnight()
metode.Kode
Output ( mungkin berbeda tergantung pada zona waktu lokal Anda )
sumber
DateTimeZone
contoh keDateTime
konstruktor itu untuk menekankan pentingnya menentukan zona waktu daripada secara tidak sengaja tergantung pada default:DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
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 adalah23: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 mungkin23: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:
... berpikir seperti ini ...
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 melewatiLocalDate
dan kembaliZonedDateTime
seperti yang Anda lihat dalam kode contoh ini.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.
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 .sumber
waktu java
Jika Anda menggunakan Java 8 dan yang lebih baru, Anda dapat mencoba paket java.time ( Tutorial ):
sumber
Ini tampaknya menjadi opsi:
untuk menambah hari untuk itu, baik
atau
Saya punya firasat yang terakhir lebih disukai dalam hal sesuatu yang aneh seperti penghematan siang hari menyebabkan penambahan 24 jam tidak cukup (lihat https://stackoverflow.com/a/4336131/32453 dan jawaban lainnya).
sumber
Saya melakukan ini secara berbeda dari semua orang di sini. Saya baru di Jawa, jadi mungkin solusi saya buruk.
Saya belum yakin ini berfungsi, tetapi bagaimanapun juga, saya menghargai umpan balik tentang solusi ini.
Saya bingung dengan pernyataan di atas yang dapat Anda hitung besok dengan menelepon:
Jika Anda menambahkan 1 ke hari dalam sebulan dan ini adalah hari ke-31, tidakkah Anda mendapatkan hari ke-32 dalam sebulan?
Mengapa waktu / tanggal tidak semuanya berdasarkan UTC di Jawa? Saya akan berpikir Zona Waktu hanya diperlukan ketika digunakan dengan i / o, tetapi secara internal harus selalu digunakan dalam UTC. Namun, kelas-kelas tersebut tampaknya menyertakan info Timezone yang tampaknya tidak hanya boros, tetapi juga rentan terhadap kesalahan pengkodean.
sumber
Apache Commons Lang
http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/DateUtils.html#isSameDay(java.util.Date , java.util.Date)
sumber
Cara paling sederhana dengan JodaTime
DateMidnight date = DateMidnight.now();
sumber
00:00:00.000
. Alih-alih gunakanwithTimeAtStartOfDay
metode baru . Perbarui ke Joda-Time versi 2.4 saat ini dan baca catatan rilis. Contoh:DateTime today = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Karena satu hari adalah
24 * 60 * 60 * 1000
ms, tengah malam hari ini dapat dihitung sebagai ...sumber
Cukup banyak jawaban sebelumnya, tetapi tidak ada yang menyebutkan parameter AM_PM:
sumber
Calendar
digantikan bertahun-tahun yang lalu oleh kelas java.time , khususnyaZonedDateTime
.sumber
Date
kelas yang mengerikan digantikan tahun yang lalu olehjava.time.Instant
. Hindari penggunaanDate
saat ini.Menggunakan apache commons ..
sumber
java.util.Date
,java.util.Calendar
, danjava.text.SimpleDateFormat
sekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .Saya tahu ini posting yang sangat lama. Saya berpikir untuk membagikan pengetahuan saya di sini!
Untuk tanggal Pertengahan malam hari ini dengan zona waktu yang tepat, Anda dapat menggunakan yang berikut
Dimana
(1000*60 * 330)
sedang dikurangi yaitu sebenarnya terkait dengan zona waktu misalnya zona waktu India yaitu kolkata berbeda +5: 30hrs dari yang sebenarnya. Jadi kurangi itu dengan mengubahnya menjadi milidetik.Jadi, ubah angka yang dikurangi terakhir menurut Anda. Saya membuat produk yaitu hanya berbasis di India Jadi hanya menggunakan cap waktu tertentu.
sumber
Namun waspadalah yang
java.sql.Date.toInstant()
selalu melemparUnsupportedOperationException
.Via LocalDate ke java.util.Date dan sebaliknya konversi paling sederhana?
sumber
Cara kuno ..
sumber
Date
.Date
kelas selalu dalam UTC. Jadi, Anda mengabaikan masalah zona waktu yang diinginkan / diharapkan. Misalnya, hari baru tiba di Kolkata India beberapa jam lebih awal dari pada UTC, dan beberapa jam lebih lambat dari UTC di Montréal Québec.