Melanjutkan dari pertanyaan Stack Overflow program Java untuk mendapatkan tanggal saat ini tanpa stempel waktu :
Apa cara paling efisien untuk mendapatkan objek Date tanpa waktu? Apakah ada cara lain selain keduanya?
// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));
// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();
Perbarui :
Saya tahu tentang Joda-Time ; Saya hanya mencoba menghindari perpustakaan tambahan untuk tugas yang sederhana (saya pikir). Tetapi berdasarkan jawaban sejauh ini Joda-Time tampaknya sangat populer, jadi saya mungkin mempertimbangkannya.
Dengan efisien , maksud saya saya ingin menghindari
String
pembuatan objek sementara seperti yang digunakan olehmethod 1
, sementara itumethod 2
tampak seperti peretasan bukan solusi.
Jawaban:
Apakah Anda benar - benar harus menggunakan
java.util.Date
? Saya benar - benar akan merekomendasikan Anda menggunakan Joda Time ataujava.time
paket dari Java 8 sebagai gantinya. Secara khusus, saat Tanggal dan Kalender selalu mewakili instan tertentu dalam waktu, tanpa konsep seperti "hanya tanggal", Joda Time memang memiliki tipe yang mewakili ini (LocalDate
). Kode Anda akan jauh lebih jelas jika Anda dapat menggunakan tipe yang mewakili apa yang sebenarnya Anda coba lakukan.Ada banyak, banyak alasan lain untuk menggunakan Joda Time atau
java.time
bukannyajava.util
tipe bawaan - mereka umumnya API yang jauh lebih baik. Anda selalu dapat mengonversi ke / dari ajava.util.Date
di batas kode Anda sendiri jika perlu, misalnya untuk interaksi basis data.sumber
Date
objek - jawaban itu memformat tanggal ke string, yang bukan hal yang sama. Pada dasarnya, menanyakan tanggal berapaDate
pada adalah pertanyaan yang tidak berarti tanpa informasi lebih lanjut: zona waktu dan sistem kalender yang Anda gunakan.Inilah yang saya gunakan untuk mendapatkan tanggal hari ini dengan waktu yang ditentukan
00:00:00
:sumber
Anda dapat menggunakan DateUtils.truncate dari pustaka Apache Commons.
Contoh:
sumber
Ya ada.
waktu java
Java 8 dan yang lebih baru disertai dengan paket java.time baru . Lihat Tutorial . Sebagian besar fungsi java.time di-port-back ke Java 6 & 7 di ThreeTen-Backport dan selanjutnya diadaptasi ke Android di ThreeTenABP .
Mirip dengan Joda-Time , java.time menawarkan
LocalDate
kelas untuk mewakili nilai hanya tanggal tanpa waktu hari dan tanpa zona waktu.Perhatikan bahwa zona waktu sangat penting untuk menentukan tanggal tertentu. Pada tengah malam di Paris, misalnya, tanggalnya masih "kemarin" di Montréal.
Secara default, java.time menggunakan standar ISO 8601 dalam menghasilkan representasi string dari nilai tanggal atau waktu-tanggal. (Kesamaan lain dengan Joda-Time.) Jadi cukup panggil
toString()
untuk menghasilkan teks seperti2015-05-21
.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 .
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
TimeZone.setDefault
selama runtime dan segera memengaruhi semua kode lain yang berjalan di JVM itu. Moral of the Story: Selalu tentukan zona waktu.Cara yang paling mudah:
sumber
long dateOnly = (currentTime / millisInDay) * millisInDay;
sama dengan menulislong dateOnly = currentTime;
?Jawaban standar untuk pertanyaan ini adalah menggunakan Joda Time . API lebih baik dan jika Anda menggunakan formatters dan parser Anda dapat menghindari kurangnya keamanan thread
SimpleDateFormat
.Menggunakan Joda berarti Anda cukup melakukan:
Perbarui :: Menggunakan java 8 ini dapat dicapai menggunakan
sumber
LocalDate
kelas yang mirip dengan Joda-Time.DateTimeZone
kepada konstruktor LocalDate itu. Menentukan tanggal saat ini tergantung pada zona waktu, karena Paris memulai tanggal baru lebih awal dari Montréal. Jika Anda menghilangkan zona waktu, zona waktu default JVM Anda diterapkan. Biasanya lebih baik untuk menentukan daripada mengandalkan default.Ini adalah cara sederhana untuk melakukannya:
sumber
Tidak masuk akal untuk berbicara tentang tanggal tanpa timestamp sehubungan dengan rutinitas Tanggal dalam runtime java standar, karena pada dasarnya peta turun ke milidetik tertentu dan bukan tanggal. Kata milidetik secara intrinsik memiliki waktu sehari yang melekat padanya yang membuatnya rentan terhadap masalah zona waktu seperti Waktu Musim Panas dan penyesuaian kalender lainnya. Lihat Mengapa mengurangi dua kali ini (tahun 1927) memberikan hasil yang aneh? untuk contoh yang menarik.
Jika Anda ingin menggunakan tanggal alih-alih milidetik, Anda perlu menggunakan yang lain. Untuk Java 8 ada serangkaian metode baru yang menyediakan persis apa yang Anda minta. Untuk Java 7 dan sebelumnya gunakan http://www.joda.org/joda-time/
sumber
Jelas bukan cara yang paling benar, tetapi jika Anda hanya memerlukan solusi cepat untuk mendapatkan tanggal tanpa waktu dan Anda tidak ingin menggunakan perpustakaan pihak ketiga ini harus dilakukan
Saya hanya perlu tanggal untuk keperluan visual dan tidak bisa Joda jadi saya substring.
sumber
sumber
Yah, sejauh yang saya tahu tidak ada cara yang lebih mudah untuk mencapai ini jika Anda hanya menggunakan JDK standar.
Anda dapat, tentu saja, meletakkan logika itu di method2 ke dalam fungsi statis di kelas helper, seperti yang dilakukan di sini di metode toBeginningOfTheDay
Kemudian Anda dapat mempersingkat metode kedua menjadi:
Atau, jika Anda benar-benar membutuhkan hari ini dalam format ini begitu sering, maka Anda bisa membungkusnya dengan metode pembantu statis lain, sehingga menjadikannya satu baris.
sumber
Jika semua yang Anda inginkan adalah melihat tanggal seperti "YYYY-MM-DD" tanpa semua kekacauan lainnya misalnya "Kamis 21 Mei 12:08:18 EDT 2015" maka gunakan saja
java.sql.Date
. Contoh ini mendapatkan tanggal saat ini:Juga
java.sql.Date
merupakan subkelas darijava.util.Date
.sumber
Jika Anda hanya memerlukan tanggal saat ini, tanpa waktu, opsi lain adalah:
sumber
00:00:00
biasanya (dapat bervariasi berdasarkan zona waktu untuk anomali seperti DST ). Jadi, seperti yang dicatat oleh Jawaban lain,LocalDate
kelas lebih tepat, dari Joda-Time (dengan asumsi Anda merujuk Joda-Time - yang harus Anda perhatikan secara eksplisit ketika mengutip kelas yang tidak dibundel dengan Java).Gunakan
LocalDate.now()
dan ubah menjadiDate
seperti di bawah ini:sumber
TimeZone.setDefault
. Kode Anda memanggilZoneId.systemDefault
dua kali, yang pertama tersiratLocalDate.now()
dan yang kedua eksplisit denganatStartOfDay
. Di antara kedua momen tersebut saat runtime, zona default saat ini dapat berubah. Saya sarankan menangkap zona menjadi variabel, dan lolos ke kedua metode.Jika Anda memerlukan bagian tanggal hanya untuk tujuan gema, maka
sumber
Bagaimana dengan ini?
sumber
Lihat waktu-Veyder . Ini adalah alternatif yang sederhana dan efisien untuk java.util dan Joda-time. Ini memiliki API intuitif dan kelas yang mewakili tanggal saja, tanpa cap waktu.
sumber
Cara paling straigthforward yang memanfaatkan penuh TimeZone Database besar Java dan benar:
sumber
Ini adalah solusi bersih tanpa konversi ke string dan kembali, dan juga tidak menghitung ulang waktu beberapa kali saat Anda mengatur ulang setiap komponen waktu menjadi nol. Itu juga menggunakan
%
(modulus) daripada membagi diikuti oleh kalikan untuk menghindari operasi ganda.Ini tidak memerlukan dependensi pihak ketiga, dan MENGHARGAI WAKTU DARI objek Kalender berlalu. Fungsi ini mengembalikan waktu pada pukul 12 pagi di zona waktu tanggal (Kalender) yang Anda lewati.
sumber
Memilih untuk tidak menggunakan perpustakaan pihak ketiga sebanyak mungkin. Saya tahu bahwa cara ini disebutkan sebelumnya, tetapi ini cara bersih yang bagus:
Yah, tidak menggunakan GregorianCalendar mungkin merupakan opsi!
sumber
Saya baru saja membuat ini untuk aplikasi saya:
Android API level 1, tidak ada perpustakaan eksternal. Itu menghormati siang hari dan zona waktu standar. Tidak ada manipulasi String, jadi saya pikir cara ini lebih efisien daripada CPU Anda, tetapi saya belum melakukan tes.
sumber
Anda dapat menggunakan waktu joda.
dan Anda menelepon dengan:
sumber