Saya ingin mengembalikan usia bertahun-tahun sebagai int dalam metode Java. Apa yang saya miliki sekarang adalah yang berikut ini di mana getBirthDate () mengembalikan objek Date (dengan tanggal lahir ;-)):
public int getAge() {
long ageInMillis = new Date().getTime() - getBirthDate().getTime();
Date age = new Date(ageInMillis);
return age.getYear();
}
Tetapi karena getYear () sudah usang saya bertanya-tanya apakah ada cara yang lebih baik untuk melakukan ini? Saya bahkan tidak yakin ini berfungsi dengan benar, karena saya belum memiliki unit test.
Jawaban:
JDK 8 menjadikan ini mudah dan elegan:
Tes JUnit untuk menunjukkan penggunaannya:
Semua orang harus menggunakan JDK 8 sekarang. Semua versi sebelumnya telah melewati akhir masa dukungan mereka.
sumber
null
sama sekali, melainkan menggunakanObjects.requireNonNull
.Lihat Joda , yang menyederhanakan perhitungan tanggal / waktu (Joda juga merupakan dasar dari apis tanggal / waktu Java standar yang baru, jadi Anda akan mempelajari API yang segera menjadi standar).
EDIT: Java 8 memiliki sesuatu yang sangat mirip dan layak untuk dicoba.
misalnya
yang sesederhana yang Anda inginkan. Hal-hal pra-Java 8 agak (seperti yang telah Anda identifikasi) agak tidak intuitif.
sumber
sumber
Jawaban dan gambaran umum modern
a) Java-8 (paket java.time)
Perhatikan bahwa ekspresi
LocalDate.now()
secara implisit terkait dengan zona waktu sistem (yang sering diabaikan oleh pengguna). Untuk kejelasan itu umumnya lebih baik menggunakan metode kelebihan bebannow(ZoneId.of("Europe/Paris"))
menentukan zona waktu eksplisit (contohnya "Eropa / Paris"). Jika zona waktu sistem diminta maka preferensi pribadi saya adalah menulisLocalDate.now(ZoneId.systemDefault())
untuk membuat hubungan dengan zona waktu sistem lebih jelas. Ini lebih merupakan upaya menulis tetapi membuat membaca lebih mudah.b) Joda-Time
Harap perhatikan bahwa solusi Joda-Time yang diusulkan dan diterima menghasilkan hasil perhitungan yang berbeda untuk tanggal yang ditunjukkan di atas (kasus yang jarang terjadi), yaitu:
Saya menganggap ini sebagai bug kecil tetapi tim Joda memiliki pandangan yang berbeda tentang perilaku aneh ini dan tidak ingin memperbaikinya (aneh karena hari akhir bulan lebih kecil daripada tanggal mulai sehingga tahun seharusnya satu kurang). Lihat juga masalah tertutup ini .
c) java.util.Calendar dll.
Untuk perbandingan, lihat berbagai jawaban lainnya. Saya tidak akan merekomendasikan menggunakan kelas-kelas yang sudah usang ini sama sekali karena kode yang dihasilkan masih kesalahan dalam beberapa kasus eksotis dan / atau terlalu rumit mengingat fakta bahwa pertanyaan aslinya terdengar sangat sederhana. Pada tahun 2015 kami memiliki perpustakaan yang benar-benar lebih baik.
d) Tentang Date4J:
Solusi yang diusulkan sederhana tetapi kadang-kadang akan gagal jika tahun kabisat. Hanya mengevaluasi hari dalam setahun tidak dapat diandalkan.
e) Pustaka saya sendiri Time4J :
Ini berfungsi mirip dengan Java-8-solusi. Cukup ganti
LocalDate
denganPlainDate
danChronoUnit.YEARS
olehCalendarUnit.YEARS
. Namun, mendapatkan "hari ini" memerlukan referensi zona waktu yang eksplisit.sumber
LocalDate.now
. Jika dihilangkan, zona waktu default JVM saat ini diterapkan secara implisit. Default itu dapat berubah antara mesin / OS / pengaturan, dan juga dapat setiap saat selama runtime oleh panggilan kode apa punsetDefault
. Saya sarankan untuk spesifik, sepertiLocalDate.now( ZoneId.for( "America/Montreal" ) )
sumber
(birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)
? Tampaknya tidak ada gunanya dengan adanya perbandingan bulan dan hari.Saya hanya menggunakan milidetik dalam nilai konstan setahun untuk keuntungan saya:
sumber
Jika Anda menggunakan GWT, Anda akan dibatasi menggunakan java.util.Date, berikut adalah metode yang menganggap tanggal sebagai bilangan bulat, tetapi masih menggunakan java.util.Date:
sumber
Jawaban yang benar menggunakan JodaTime adalah:
Anda bahkan dapat mempersingkat menjadi satu baris jika Anda mau. Saya menyalin ide dari jawaban BrianAgnew , tapi saya percaya ini lebih benar seperti yang Anda lihat dari komentar di sana (dan itu menjawab pertanyaan dengan tepat).
sumber
Dengan perpustakaan date4j :
sumber
Ini adalah versi yang disempurnakan dari yang di atas ... mengingat Anda ingin usia menjadi 'int'. karena kadang-kadang Anda tidak ingin mengisi program Anda dengan banyak perpustakaan.
sumber
Mungkin mengejutkan untuk dicatat bahwa Anda tidak perlu tahu berapa hari atau bulan dalam satu tahun atau berapa hari dalam bulan-bulan itu, juga, Anda tidak perlu tahu tentang tahun kabisat, detik kabisat, atau apa pun semua itu menggunakan metode sederhana, akurat 100% ini:
sumber
Cobalah untuk menyalin yang ini dalam kode Anda, lalu gunakan metode untuk mendapatkan usia.
sumber
Saya menggunakan kode ini untuk perhitungan usia, Semoga ini bisa membantu .. tidak ada perpustakaan yang digunakan
sumber
Bidang kelahiran dan efek keduanya bidang tanggal:
Ini pada dasarnya merupakan modifikasi dari solusi John O tanpa menggunakan metode depresiasi. Saya menghabiskan cukup banyak waktu untuk mencoba agar kodenya berfungsi dalam kode saya. Mungkin ini akan menyelamatkan orang lain saat itu.
sumber
Bagaimana dengan yang ini?
sumber
String
dateofbirth
memiliki tanggal lahir. dan format adalah apa saja (didefinisikan pada baris berikut):Berikut cara memformat:
Variabel
ageStr
akan memiliki tahun.sumber
Elegan, tampaknya benarVarian , beda waktu timestamp dari solusi Yaron Ronen.
Saya menyertakan unit test untuk membuktikan kapan dan mengapa itu tidak benar . Tidak mungkin karena (mungkin) jumlah hari kabisat yang berbeda (dan detik) dalam perbedaan cap waktu. Perbedaan harus maks + -1 hari (dan satu detik) untuk algoritma ini, lihat test2 (), sedangkan solusi Yaron Ronen didasarkan pada asumsi yang sepenuhnya konstan dari
timeDiff / MILLI_SECONDS_YEAR
dapat berbeda 10 hari untuk usia 40 tahun, namun varian ini juga tidak benar.Ini rumit, karena varian yang ditingkatkan ini, menggunakan rumus
diffAsCalendar.get(Calendar.YEAR) - 1970
, mengembalikan hasil yang benar sebagian besar waktu, karena jumlah tahun kabisat rata-rata sama antara dua tanggal.sumber
sumber
sumber
Berikut adalah kode java untuk menghitung usia dalam tahun, bulan, dan hari.
sumber
Cara termudah tanpa perpustakaan:
sumber
ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() )
. Lihat Jawaban yang benarDateUtils
adalah perpustakaanDengan Java 8, kita dapat menghitung usia seseorang dengan satu baris kode:
sumber
sumber
sumber
sumber
sumber
sumber
Saya menghargai semua jawaban yang benar tetapi ini adalah jawaban kotlin untuk pertanyaan yang sama
Saya harap akan membantu pengembang kotlin
sumber