Dapatkah seseorang tolong beri tahu "praktik terbaik" saat ini di sekitar Date
dan Calendar
jenis.
Saat menulis kode baru, itu yang terbaik untuk selalu mendukung Calendar
lebih Date
, atau keadaan di sana di mana Date
adalah datatype lebih tepat?
java.util.Date
,java.util.Calendar
, danjava.text.SimpleDateFormat
sekarang warisan, digantikan oleh java.time kelas. Sebagian besar fungsi java.time di -porting ke Java 6 & Java 7 di proyek ThreeTen-Backport . Lebih lanjut diadaptasi untuk Android sebelumnya dalam proyek ThreeTenABP . Lihat Cara menggunakan ThreeTenABP… .Jawaban:
Date adalah kelas yang lebih sederhana dan terutama ada untuk alasan kompatibilitas ke belakang. Jika Anda perlu mengatur tanggal tertentu atau melakukan aritmatika tanggal, gunakan Kalender. Kalender juga menangani pelokalan. Fungsi manipulasi tanggal sebelumnya dari Date telah ditinggalkan.
Secara pribadi saya cenderung menggunakan waktu dalam milidetik sebagai panjang (atau Panjang, jika perlu) atau Kalender ketika ada pilihan.
Tanggal dan Kalender keduanya bisa berubah, yang cenderung menyajikan masalah saat menggunakan API.
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 .Cara terbaik untuk kode baru (jika kebijakan Anda mengizinkan kode pihak ketiga) adalah dengan menggunakan perpustakaan Joda Time .
Keduanya, Date dan Calendar , memiliki begitu banyak masalah desain yang tidak ada solusi yang baik untuk kode baru.
sumber
Date
danCalendar
benar-benar konsep dasar yang sama (keduanya mewakili instan dalam waktu dan pembungkus di sekitarlong
nilai yang mendasarinya ).Orang bisa berargumen bahwa
Calendar
itu sebenarnya bahkan lebih rusak daripadaDate
, karena tampaknya menawarkan fakta konkret tentang hal-hal seperti hari dalam seminggu dan waktu dalam sehari, sedangkan jika Anda mengubahtimeZone
propertinya, beton berubah menjadi blancmange! Tidak ada objek yang benar-benar berguna sebagai penyimpan tahun-bulan-hari atau waktu-hari karena alasan ini.Gunakan
Calendar
hanya sebagai kalkulator yang, ketika diberikanDate
danTimeZone
objek, akan melakukan perhitungan untuk Anda. Hindari penggunaannya untuk mengetik properti dalam aplikasi.Gunakan
SimpleDateFormat
bersama denganTimeZone
danDate
untuk menghasilkan Strings tampilan.Jika Anda merasa ingin menggunakan Joda-Time, meskipun itu IMHO tidak perlu rumit dan segera akan digantikan oleh API tanggal JSR-310 dalam peristiwa apa pun.
Saya telah menjawab sebelumnya bahwa tidak sulit untuk menggulung
YearMonthDay
kelas Anda sendiri , yang menggunakan diCalendar
bawah tenda untuk perhitungan tanggal. Saya downvoted untuk saran tetapi saya masih percaya itu adalah saran yang valid karena Joda-Time (dan JSR-310 ) benar-benar sangat rumit untuk kebanyakan use-case.sumber
Tanggal terbaik untuk menyimpan objek tanggal. Ini adalah yang bertahan, yang Serialized ...
Kalender adalah yang terbaik untuk memanipulasi Tanggal.
sumber
java.lang.Long
Saya biasanya menggunakan Date jika memungkinkan. Meskipun bisa berubah, mutator sebenarnya sudah usang. Pada akhirnya itu pada dasarnya membungkus panjang yang akan mewakili tanggal / waktu. Sebaliknya, saya akan menggunakan Kalender jika saya harus memanipulasi nilai.
Anda dapat memikirkannya seperti ini: Anda hanya menggunakan StringBuffer hanya ketika Anda perlu memiliki Strings yang dapat Anda manipulasi dengan mudah dan kemudian mengonversinya menjadi Strings menggunakan metode toString (). Dengan cara yang sama, saya hanya menggunakan Kalender jika saya perlu memanipulasi data sementara.
Untuk praktik terbaik, saya cenderung menggunakan objek tidak berubah sebanyak mungkin di luar model domain . Ini secara signifikan mengurangi kemungkinan efek samping dan itu dilakukan untuk Anda oleh kompiler, daripada tes JUnit. Anda menggunakan teknik ini dengan membuat bidang akhir pribadi di kelas Anda.
Dan kembali ke analogi StringBuffer. Berikut adalah beberapa kode yang menunjukkan kepada Anda cara mengkonversi antara Kalender dan Tanggal
sumber
Date
/Calendar
menggunakan pola objek abadi.Date
s harus digunakan sebagai titik waktu yang tidak dapat diubah;Calendar
s bisa berubah, dan dapat diedarkan dan dimodifikasi jika Anda perlu berkolaborasi dengan kelas lain untuk menghasilkan tanggal akhir. Anggap mereka analog denganString
danStringBuilder
dan Anda akan memahami bagaimana saya menganggap mereka harus digunakan.(Dan ya, saya tahu Date sebenarnya tidak bisa diubah secara teknis, tetapi tujuannya adalah bahwa itu seharusnya tidak bisa berubah, dan jika tidak ada yang memanggil metode yang sudah usang maka memang begitu.)
sumber
Date
/Calendar
menggunakan pola objek abadi. Secara khusus,Instant
menggantikanjava.util.Date
, danZonedDateTime
menggantikanCalendar
/GregorianCalendar
.tl; dr
Hindari kelas-kelas warisan ini sepenuhnya. Gunakan kelas java.time sebagai gantinya.
Instant
Date
ZonedDateTime
GregorianCalendar
OffsetDateTime
LocalDateTime
Detail
The Answer Ortomala Lokni yang tepat untuk menyarankan menggunakan modern java.time kelas daripada kelas warisan tanggal-waktu lama merepotkan (
Date
,Calendar
, dll). Tetapi Jawaban itu menyarankan kelas yang salah sebagai setara (lihat komentar saya pada Jawaban itu).Menggunakan java.time
Kelas java.time adalah peningkatan besar atas kelas tanggal-waktu lama, perbedaan malam-dan-hari. Kelas-kelas lama dirancang dengan buruk, membingungkan, dan merepotkan. Anda harus menghindari kelas lama jika memungkinkan. Tetapi ketika Anda perlu mengkonversi ke / dari yang lama / baru, Anda dapat melakukannya dengan memanggil metode baru, tambahkan ke kelas lama .
Untuk informasi lebih lanjut tentang konversi, lihat Jawab saya dan diagram bagus untuk Pertanyaan lain, Konversi java.util. Tanggal ke tipe "java.time" apa? .
Pencarian Stack Overflow memberikan ratusan contoh Pertanyaan dan Jawaban tentang penggunaan java.time. Tapi ini sinopsis singkatnya.
Instant
Dapatkan momen saat ini dengan
Instant
. TheInstant
kelas merupakan saat di timeline di UTC dengan resolusi nanodetik (hingga sembilan (9) angka dari pecahan desimal).ZonedDateTime
Untuk melihat momen simultan yang sama melalui lensa waktu jam dinding wilayah tertentu , terapkan zona waktu (
ZoneId
) untuk mendapatkan aZonedDateTime
.Zona waktu
Tentukan nama zona waktu yang tepat dalam format
continent/region
, sepertiAmerica/Montreal
,Africa/Casablanca
, atauPacific/Auckland
. Jangan pernah menggunakan singkatan 3-4 huruf sepertiEST
atauIST
karena mereka bukan zona waktu yang sebenarnya, tidak terstandarisasi, dan bahkan tidak unik (!).Mengimbangi
Zona waktu adalah sejarah perubahan suatu kawasan dalam offset-dari-UTC . Namun terkadang Anda hanya diberikan offset tanpa zona penuh. Dalam hal itu, gunakan
OffsetDateTime
kelas.Penggunaan zona waktu lebih disukai daripada penggunaan offset semata.
LocalDateTime
"Lokal" dalam
Local…
kelas berarti lokalitas apa saja , bukan lokalitas tertentu. Jadi namanya bisa kontra-intuitif.LocalDateTime
,,LocalDate
danLocalTime
sengaja tidak memiliki informasi tentang offset atau zona waktu. Jadi mereka tidak mewakili momen aktual, mereka bukan poin di timeline. Saat ragu atau bingung, gunakanZonedDateTime
bukanLocalDateTime
. Cari Stack Overflow untuk diskusi lebih lanjut.String
Jangan mengacaukan objek waktu-waktu dengan string yang mewakili nilainya. Anda bisa menguraikan string untuk mendapatkan objek waktu-tanggal, dan Anda bisa menghasilkan string dari objek tanggal-waktu. Tetapi string tidak pernah tanggal-waktu itu sendiri.
Pelajari tentang format standar ISO 8601 , yang digunakan secara default di kelas java.time.
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 .
Menggunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru, Anda dapat bertukar objek java.time secara langsung dengan database Anda. Tidak perlu untuk string atau kelas java.sql. *.
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
Dengan Java 8, paket java.time baru harus digunakan.
Objek tidak berubah, zona waktu dan penghematan cahaya siang hari diperhitungkan.
Anda dapat membuat
ZonedDateTime
objek darijava.util.Date
objek lama seperti ini:sumber
LocalDateTime
. Kelas itu dengan sengaja kehilangan informasi apa pun tentang offset-dari-UTC dan zona waktu. Sehingga kelas itu tidak setara sepertiDate
di UTC danCalendar
memiliki zona waktu yang ditetapkan. Lihat Jawaban saya dan diagram bagus untuk Pertanyaan lain, Konversi java.util.Date ke tipe "java.time" apa? .Saya selalu menganjurkan waktu Joda . Inilah sebabnya.
EDIT: Kelas tanggal / waktu Java yang diperkenalkan dengan Java 8 sekarang merupakan solusi yang lebih disukai, jika Anda dapat bermigrasi ke Java 8
sumber
Sedikit terlambat di pesta, tetapi Java memiliki Date Date API baru di JDK 8. Anda mungkin ingin meningkatkan versi JDK Anda dan merangkul standar. Tidak ada lagi tanggal / kalender yang berantakan, tidak ada lagi stoples pihak ke-3.
sumber
Tanggal harus dikembangkan kembali. Alih-alih menjadi interger yang panjang, itu harus memegang tahun, bulan, tanggal, jam, menit, detik, sebagai bidang yang terpisah. Bahkan mungkin baik untuk menyimpan kalender dan zona waktu yang terkait dengan tanggal ini.
Dalam percakapan alami kami, jika mengatur janji temu pada 1 November 2013 13:00 Waktu NY, ini adalah DateTime. Ini BUKAN Kalender. Jadi kita harus bisa berkomunikasi seperti ini di Jawa juga.
Ketika Date disimpan sebagai bilangan bulat panjang (mili detik sejak 1 Januari 1970 atau apalah), menghitung tanggal saat ini tergantung pada kalender. Kalender yang berbeda akan memberikan tanggal yang berbeda pula. Ini dari prospek memberikan waktu absolut (misalnya 1 triliun detik setelah Big Bang). Namun seringkali kita juga membutuhkan cara percakapan yang nyaman, seperti objek yang merangkum tahun, bulan, dll.
Saya ingin tahu apakah ada kemajuan baru di Jawa untuk merekonsiliasi 2 tujuan ini. Mungkin pengetahuan java saya terlalu tua.
sumber
Date
telah dikembangkan kembali; digantikan olehjava.time.Instant
kelas. DanCalendar
/GregorianCalendar
digantikan olehjava.time.ZonedDateTime
kelas.Btw "date" biasanya ditandai sebagai "usang / usang" (saya tidak tahu persis mengapa) - sesuatu tentang itu ditulis di sana Java: Mengapa konstruktor Date sudah usang, dan apa yang saya gunakan sebagai gantinya?
Sepertinya ini masalah konstruktor satu-satunya jalan melalui Tanggal baru (tahun int, bulan int, hari int) , cara yang disarankan adalah melalui Kalender dan setel param secara terpisah .. ( Kalender cal = Calendar.getInstance (); )
sumber
Saya menggunakan Kalender ketika saya memerlukan beberapa operasi spesifik pada tanggal seperti memindahkan waktu, tetapi Tanggal saya merasa terbantu ketika Anda perlu memformat tanggal untuk menyesuaikan kebutuhan Anda, baru-baru ini saya menemukan bahwa Lokal memiliki banyak operasi dan metode yang bermanfaat. Saya menggunakan Lokal sekarang!
sumber
Calendar
&Date
digantikan bertahun-tahun yang lalu oleh kelas java.time . Tidak perlu pernah menggunakanDate
atauCalendar
. DanLocale
tidak ada hubungannya dengan makna objek waktu-tanggal. ALocale
hanya digunakan untuk menentukan bahasa manusia dan norma-norma budaya yang akan digunakan dalam melokalisasi sambil menghasilkan teks untuk mewakili nilai objek waktu-tanggal.