Java'da birinin yaşını nasıl hesaplayabilirim?


147

Java yönteminde int olarak yıllara dönmek istiyorum. Şimdi ne var getBirthDate () (doğum tarihi ;-) ile) bir Date nesnesi döndürür aşağıdaki:

public int getAge() {
    long ageInMillis = new Date().getTime() - getBirthDate().getTime();

    Date age = new Date(ageInMillis);

    return age.getYear();
}

Ancak getYear () kullanımdan kaldırıldığından, bunu yapmanın daha iyi bir yolu olup olmadığını merak ediyorum. Halihazırda birim testleri olmadığım için bunun doğru çalıştığından bile emin değilim.


Bu konuda fikrimi değiştirdim: diğer soru sadece tarihler arasında yaklaşık bir yıla sahip, gerçekten doğru bir yaş değil.
cletus

Bir int döndürdüğü göz önüne alındığında, 'doğru' yaşla ne demek istediğini açıklayabilir misin?
Brian Agnew

2
Tarih ve Takvim, Java belgelerini okumaktan çıkarılabilecek temel bir kavramdır. Bunun neden bu kadar ileri sürüleceğini anlayamıyorum.
demongolem

@demongolem ??? Tarih ve Takvim kolayca anlaşılır mı ?! Hayır, hiç de değil. Stack Overflow'da bu konuda bir milyon soru var. Joda-Time projesi, bu zahmetli tarih-saat sınıflarının yerini almak için en popüler kütüphanelerden birini üretti. Daha sonra Sun, Oracle ve JCP topluluğu , eski sınıfların umutsuzca yetersiz olduğunu kabul ederek JSR 310 ( java.time ) 'ı kabul etti. Daha fazla bilgi için bkz . Oracle Öğreticisi .
Basil Bourque

Yanıtlar:


159

JDK 8 bunu kolay ve zarif kılar:

public class AgeCalculator {

    public static int calculateAge(LocalDate birthDate, LocalDate currentDate) {
        if ((birthDate != null) && (currentDate != null)) {
            return Period.between(birthDate, currentDate).getYears();
        } else {
            return 0;
        }
    }
}

Kullanımını göstermek için bir JUnit testi:

public class AgeCalculatorTest {

    @Test
    public void testCalculateAge_Success() {
        // setup
        LocalDate birthDate = LocalDate.of(1961, 5, 17);
        // exercise
        int actual = AgeCalculator.calculateAge(birthDate, LocalDate.of(2016, 7, 12));
        // assert
        Assert.assertEquals(55, actual);
    }
}

Herkes şimdiye kadar JDK 8 kullanıyor olmalı. Önceki tüm sürümler destek ömrünü tamamladı.


10
DAY_OF_YEAR karşılaştırması artık yıllarla uğraşırken hatalı sonuçlara yol açabilir.
sinuhepop

1
DateOfBirth değişkeni Date nesnesi olmalıdır. Doğum tarihi ile nasıl bir Date nesnesi oluşturabilirim?
Erick

9 yıldır olduğumuz ve Java 8 kullanılması durumunda kullanılacak çözüm bu olmalıdır.
nojevive

JDK 9 mevcut üretim sürümüdür. Her zamankinden daha gerçek.
duffymo

2
@SteveOh katılmıyorum. Ben hiç nulls kabul değil , yerine kullanın Objects.requireNonNull.
MC İmparatoru

170

Tarih / saat hesaplamalarını kolaylaştıran Joda'ya göz atın (Joda aynı zamanda yeni standart Java tarih / saat API'sinin de temelidir, bu yüzden yakında standart olacak bir API öğreneceksiniz).

EDIT: Java 8 çok benzer bir şey vardır ve kontrol etmeye değer.

Örneğin

LocalDate birthdate = new LocalDate (1970, 1, 20);
LocalDate now = new LocalDate();
Years age = Years.yearsBetween(birthdate, now);

ki bu da istediğiniz kadar basit. Java 8 öncesi şeyler (tanımladığınız gibi) biraz sezgisel değil.


2
@ HoàngLong: JavaDocs'tan: "Bu sınıf bir günü değil, gece yarısı milisaniyeyi temsil eder. Bütün günü temsil eden bir sınıfa ihtiyacınız varsa, bir Aralık veya bir LocalDate daha uygun olabilir." Gerçekten yok burada bir tarih temsil etmek istiyorum.
Jon Skeet

@JohnSkeet'in önerdiği şekilde yapmak istiyorsanız, şöyle: Years age = Years.yearsBetween (new LocalDate (getBirthDate ()), new LocalDate ());
Fletch

DateMidnight'ı neden kullandığımı bilmiyorum ve şimdi kullanımdan kaldırıldığını not ediyorum. Şimdi LOCALDATE kullanmak değişti
Brian Agnew


2
@IgorGanapolsky Aslında asıl fark şudur: Joda-Time kullanıcıları kullanırken Java-8 ve ThreetenBP statik fabrika yöntemlerini kullanır. Joda-Time'ın yaşı hesaplama biçimindeki ince bir hata için lütfen farklı kütüphanelerin davranışları hakkında genel bir bakış sunduğum cevaba bakın .
Meno Hochschild

43
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(...);
if (dob.after(now)) {
  throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
int age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
  age--;
} else if (month1 == month2) {
  int day1 = now.get(Calendar.DAY_OF_MONTH);
  int day2 = dob.get(Calendar.DAY_OF_MONTH);
  if (day2 > day1) {
    age--;
  }
}
// age is now correct

Evet, takvim sınıfı korkunç. Ne yazık ki, iş yerinde bazen kullanmak zorundayım:. Bunu yayınladığınız için teşekkürler Cletus
Steve

1
Calendar.MONTH ve Calendar.DAY_OF_MONTH yerine Calendar.DAY_OF_YEAR girin ve en azından biraz daha temiz olacak
Tobbbe

@ Tobbbe Artık bir yılda 1 Mart'ta doğmuşsanız, doğum gününüz ertesi yıl 1 Mart'ta olur, 2 değil. DAY_OF_YEAR çalışmaz.
Airsource Ltd

42

Modern cevap ve genel bakış

a) Java-8 (java.time paketi)

LocalDate start = LocalDate.of(1996, 2, 29);
LocalDate end = LocalDate.of(2014, 2, 28); // use for age-calculation: LocalDate.now()
long years = ChronoUnit.YEARS.between(start, end);
System.out.println(years); // 17

İfadenin LocalDate.now(), sistem saat dilimiyle (genellikle kullanıcılar tarafından göz ardı edilir) örtülü olarak ilişkili olduğunu unutmayın . Anlaşılır olması için, now(ZoneId.of("Europe/Paris"))açık bir zaman dilimi belirten aşırı yüklenmiş yöntemi kullanmak daha iyidir (burada örnek olarak "Avrupa / Paris"). Sistem saat dilimi istenirse, kişisel tercihim, LocalDate.now(ZoneId.systemDefault())sistem saat dilimi ile ilişkiyi daha net hale getirmek için yazmaktır . Bu daha fazla yazma çabasıdır ancak okumayı kolaylaştırır.

b) Joda-Time

Önerilen ve kabul edilen Joda-Time-çözümünün yukarıda gösterilen tarihler için farklı bir hesaplama sonucu verdiğini unutmayın (nadir bir durum), yani:

LocalDate birthdate = new LocalDate(1996, 2, 29);
LocalDate now = new LocalDate(2014, 2, 28); // test, in real world without args
Years age = Years.yearsBetween(birthdate, now);
System.out.println(age.getYears()); // 18

Bunu küçük bir hata olarak görüyorum, ancak Joda takımı bu garip davranış hakkında farklı bir görüşe sahip ve düzeltmek istemiyor (garip çünkü bitiş tarihi ayın başlangıç ​​tarihi daha küçük olduğundan yıl olmalı bir tane daha az). Ayrıca bu kapalı konuya bakın .

c) java.util.Calendar vb.

Karşılaştırma için diğer cevaplara bakınız. Sonuçta ortaya çıkan kod hala bazı egzotik durumlarda ve / veya orijinal soru çok basit geliyor aslında göz önüne alındığında çok karmaşık hata eğilimli olduğundan bu eski sınıfları kullanmayı tavsiye etmem. 2015 yılında gerçekten daha iyi kütüphanelerimiz var.

d) Date4J Hakkında:

Önerilen çözüm basittir, ancak artık yıllar durumunda başarısız olacaktır. Sadece yılın gününü değerlendirmek güvenilir değildir.

e) Kendi kütüphanem Time4J :

Bu Java-8 çözümüne benzer şekilde çalışır. Sadece yerine LocalDategöre PlainDateve ChronoUnit.YEARStarafından CalendarUnit.YEARS. Ancak, "bugün" elde etmek için açık bir saat dilimi referansı gerekir.

PlainDate start = PlainDate.of(1996, 2, 29);
PlainDate end = PlainDate.of(2014, 2, 28);
// use for age-calculation (today): 
// => end = SystemClock.inZonalView(EUROPE.PARIS).today();
// or in system timezone: end = SystemClock.inLocalView().today();
long years = CalendarUnit.YEARS.between(start, end);
System.out.println(years); // 17

1
Java 8 sürümü için teşekkür ederiz! Biraz zaman kazandım :) Şimdi sadece kalan ayları nasıl çıkaracağımı bulmam gerekiyor. Örneğin 1 yıl 1 ay. :)
thomas77

2
@ thomas77 Cevabınız için teşekkürler, birleşik yıllar ve aylar (ve belki de günler) Java-8'de `` java.time.Period '' kullanılarak yapılabilir. Saat gibi diğer birimleri de hesaba katmak istiyorsanız, Java-8 bir çözüm sunmaz.
Meno Hochschild

Tekrar teşekkürler (ve hızlı yanıt için) :)
thomas77

1
Kullanırken bir saat dilimi belirtmenizi öneririm LocalDate.now. Atlanırsa, JVM'nin geçerli varsayılan saat dilimi örtülü olarak uygulanır. Bu varsayılan, makineler / işletim sistemleri / ayarlar arasında değişebilir ve çalışma sırasında herhangi bir zamanda herhangi bir kod çağrısı ile de değişebilir setDefault. Ben gibi belirli, tavsiyeLocalDate.now( ZoneId.for( "America/Montreal" ) )
Basil Bourque

1
@GoCrafter_LP Evet, Java-8'i simüle eden ThreetenABP veya bu tür eski Android sürümleri için Joda-Time-Android (D. Lew'den) veya lib Time4A'mı uygulayabilirsiniz.
Meno Hochschild

17
/**
 * This Method is unit tested properly for very different cases , 
 * taking care of Leap Year days difference in a year, 
 * and date cases month and Year boundary cases (12/31/1980, 01/01/1980 etc)
**/

public static int getAge(Date dateOfBirth) {

    Calendar today = Calendar.getInstance();
    Calendar birthDate = Calendar.getInstance();

    int age = 0;

    birthDate.setTime(dateOfBirth);
    if (birthDate.after(today)) {
        throw new IllegalArgumentException("Can't be born in the future");
    }

    age = today.get(Calendar.YEAR) - birthDate.get(Calendar.YEAR);

    // If birth date is greater than todays date (after 2 days adjustment of leap year) then decrement age one year   
    if ( (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3) ||
            (birthDate.get(Calendar.MONTH) > today.get(Calendar.MONTH ))){
        age--;

     // If birth date and todays date are of same month and birth day of month is greater than todays day of month then decrement age
    }else if ((birthDate.get(Calendar.MONTH) == today.get(Calendar.MONTH )) &&
              (birthDate.get(Calendar.DAY_OF_MONTH) > today.get(Calendar.DAY_OF_MONTH ))){
        age--;
    }

    return age;
}

2
Çekin amacı nedir (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)? Ayın varlığı ve dayofmonth karşılaştırmaları ile anlamsız görünüyor.
Jed Schaaf

13

Ben sadece bir yıl sabit değerde milisaniye benim avantajım için kullanın:

Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);

2
Bu doğru cevap değil ... yıl 3.156e + 10 değil, 3.15576e + 10 (çeyrek gün!)
Maher Abuthraa

1
Bu işe yaramaz, bazı yıllar artık yıl ve farklı bir msec değerine sahip
Greg Ennis

12

GWT kullanıyorsanız, java.util.Date kullanmakla sınırlı olacaksınız, burada tarihi tamsayı olarak alan, ancak yine de java.util.Date kullanan bir yöntem var:

public int getAge(int year, int month, int day) {
    Date now = new Date();
    int nowMonth = now.getMonth()+1;
    int nowYear = now.getYear()+1900;
    int result = nowYear - year;

    if (month > nowMonth) {
        result--;
    }
    else if (month == nowMonth) {
        int nowDay = now.getDate();

        if (day > nowDay) {
            result--;
        }
    }
    return result;
}

5

JodaTime kullanarak doğru cevap :

public int getAge() {
    Years years = Years.yearsBetween(new LocalDate(getBirthDate()), new LocalDate());
    return years.getYears();
}

İsterseniz tek bir hatta kısaltabilirsiniz. Fikri BrianAgnew'in cevabından kopyaladım , ancak buradaki yorumlardan gördüğünüz gibi daha doğru olduğuna inanıyorum (ve soruyu tam olarak cevaplıyor).


4

İle date4j kütüphanesinde:

int age = today.getYear() - birthdate.getYear();
if(today.getDayOfYear() < birthdate.getDayOfYear()){
  age = age - 1; 
}

4

Bu, yukarıdaki sürümün geliştirilmiş bir versiyonudur ... yaşın 'int' olmasını istediğiniz göz önüne alındığında. çünkü bazen programınızı bir grup kütüphaneyle doldurmak istemezsiniz.

public int getAge(Date dateOfBirth) {
    int age = 0;
    Calendar born = Calendar.getInstance();
    Calendar now = Calendar.getInstance();
    if(dateOfBirth!= null) {
        now.setTime(new Date());
        born.setTime(dateOfBirth);  
        if(born.after(now)) {
            throw new IllegalArgumentException("Can't be born in the future");
        }
        age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);             
        if(now.get(Calendar.DAY_OF_YEAR) < born.get(Calendar.DAY_OF_YEAR))  {
            age-=1;
        }
    }  
    return age;
}

4

Bir yılda kaç gün veya ay olduğunu veya o aylarda kaç gün olduğunu bilmenize gerek olmadığını, aynı şekilde artık yılları, artık saniyeleri veya herhangi birini bilmenize gerek olmadığını belirtmek şaşırtıcı olabilir. bu basit,% 100 doğru yöntemi kullanarak:

public static int age(Date birthday, Date date) {
    DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
    int d1 = Integer.parseInt(formatter.format(birthday));
    int d2 = Integer.parseInt(formatter.format(date));
    int age = (d2-d1)/10000;
    return age;
}

Java 6 ve 5 için bir çözüm arıyorum. Bu basit ama doğru.
Jj Tuibeo

3

Bunu kodunuzda kopyalamaya çalışın, ardından yaşı almak için yöntemi kullanın.

public static int getAge(Date birthday)
{
    GregorianCalendar today = new GregorianCalendar();
    GregorianCalendar bday = new GregorianCalendar();
    GregorianCalendar bdayThisYear = new GregorianCalendar();

    bday.setTime(birthday);
    bdayThisYear.setTime(birthday);
    bdayThisYear.set(Calendar.YEAR, today.get(Calendar.YEAR));

    int age = today.get(Calendar.YEAR) - bday.get(Calendar.YEAR);

    if(today.getTimeInMillis() < bdayThisYear.getTimeInMillis())
        age--;

    return age;
}

Yalnızca kod yanıtı önerilmez. Bu kodun OP sorusunu neden ele alabileceğini açıklamak daha iyi olur.
рüффп

Bu aslında bir beyinsiz değil ... ama sadece endişenizi gidermek için güncellenecek
Kevin

3

Bu kod parçasını yaş hesaplaması için kullanıyorum, umarım bu yardımcı olur .. kullanılan kitaplık yok

private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());

public static int calculateAge(String date) {

    int age = 0;
    try {
        Date date1 = dateFormat.parse(date);
        Calendar now = Calendar.getInstance();
        Calendar dob = Calendar.getInstance();
        dob.setTime(date1);
        if (dob.after(now)) {
            throw new IllegalArgumentException("Can't be born in the future");
        }
        int year1 = now.get(Calendar.YEAR);
        int year2 = dob.get(Calendar.YEAR);
        age = year1 - year2;
        int month1 = now.get(Calendar.MONTH);
        int month2 = dob.get(Calendar.MONTH);
        if (month2 > month1) {
            age--;
        } else if (month1 == month2) {
            int day1 = now.get(Calendar.DAY_OF_MONTH);
            int day2 = dob.get(Calendar.DAY_OF_MONTH);
            if (day2 > day1) {
                age--;
            }
        }
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return age ;
}

2

Doğum ve efekt alanlarının her ikisi de tarih alanıdır:

Calendar bir = Calendar.getInstance();
bir.setTime(birth);
int birthNm = bir.get(Calendar.DAY_OF_YEAR);
int birthYear = bir.get(Calendar.YEAR);
Calendar eff = Calendar.getInstance();
eff.setTime(effect);

Bu temel olarak, amortisman yöntemleri kullanılmadan John O çözeltisinin bir modifikasyonu. Kodumda çalışmak için kodunu almaya çalışırken çok zaman geçirdim. Belki bu o zaman başkalarını kurtarabilir.


2
bunu biraz daha iyi açıklayabilir misin? bu yaşı nasıl hesaplar?
Jonathan S. Fisher

1

Peki ya bu?

public Integer calculateAge(Date date) {
    if (date == null) {
        return null;
    }
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date);
    Calendar cal2 = Calendar.getInstance();
    int i = 0;
    while (cal1.before(cal2)) {
        cal1.add(Calendar.YEAR, 1);
        i += 1;
    }
    return i;
}

Bu gerçekten sevimli bir öneridir (Joda kullanmadığınızda ve Java 8'i kullanamadığınızda), ancak algoritma biraz yanlıştır, çünkü ilk yılın tamamı geçene kadar 0'sınız. Bu yüzden while döngüsünü başlatmadan önce tarihe bir yıl eklemeniz gerekir.
Dagmar

1

String dateofbirthdoğum tarihi vardır. ve biçim ne olursa olsun (aşağıdaki satırda tanımlanmıştır):

org.joda.time.format.DateTimeFormatter formatter =  org.joda.time.format.DateTimeFormat.forPattern("mm/dd/yyyy");

Biçimlendirmek için:

org.joda.time.DateTime birthdateDate = formatter.parseDateTime(dateofbirth );
org.joda.time.DateMidnight birthdate = new         org.joda.time.DateMidnight(birthdateDate.getYear(), birthdateDate.getMonthOfYear(), birthdateDate.getDayOfMonth() );
org.joda.time.DateTime now = new org.joda.time.DateTime();
org.joda.time.Years age = org.joda.time.Years.yearsBetween(birthdate, now);
java.lang.String ageStr = java.lang.String.valueOf (age.getYears());

Değişken ageStryıllar olacak.


1

Yaron Ronen çözümünün zarif, görünüşte doğru , zaman damgası fark tabanlı varyantı.

Ne zaman ve neden doğru olmadığını kanıtlamak için bir birim testi ekliyorum . Herhangi bir zaman damgası farkında (muhtemelen) farklı sayıda gün (ve saniye) olması imkansızdır. Bu algoritma için tutarsızlık maksimum + -1 gün (ve bir saniye) olmalıdır, test2 () 'ye timeDiff / MILLI_SECONDS_YEARbakarken , tamamen sabit varsayımlara dayanan Yaron Ronen çözeltisi 40 yaşındaki bir çocuk için 10 gün farklı olabilir, ancak bu varyant da yanlıştır.

Zor, çünkü bu geliştirilmiş varyant, formülü kullanarak diffAsCalendar.get(Calendar.YEAR) - 1970, iki tarih arasında ortalama olarak artık yıl sayısı olarak, çoğu zaman doğru sonuçları döndürür.

/**
 * Compute person's age based on timestamp difference between birth date and given date
 * and prove it is INCORRECT approach.
 */
public class AgeUsingTimestamps {

public int getAge(Date today, Date dateOfBirth) {
    long diffAsLong = today.getTime() - dateOfBirth.getTime();
    Calendar diffAsCalendar = Calendar.getInstance();
    diffAsCalendar.setTimeInMillis(diffAsLong);
    return diffAsCalendar.get(Calendar.YEAR) - 1970; // base time where timestamp=0, precisely 1/1/1970 00:00:00 
}

    final static DateFormat df = new SimpleDateFormat("dd.MM.yyy HH:mm:ss");

    @Test
    public void test1() throws Exception {
        Date dateOfBirth = df.parse("10.1.2000 00:00:00");
        assertEquals(87, getAge(df.parse("08.1.2088 23:59:59"), dateOfBirth));
        assertEquals(87, getAge(df.parse("09.1.2088 23:59:59"), dateOfBirth));
        assertEquals(88, getAge(df.parse("10.1.2088 00:00:01"), dateOfBirth));
    }

    @Test
    public void test2() throws Exception {
        // between 2000 and 2021 was 6 leap days
        // but between 1970 (base time) and 1991 there was only 5 leap days
        // therefore age is switched one day earlier
            // See http://www.onlineconversion.com/leapyear.htm
        Date dateOfBirth = df.parse("10.1.2000 00:00:00");
        assertEquals(20, getAge(df.parse("08.1.2021 23:59:59"), dateOfBirth));
        assertEquals(20, getAge(df.parse("09.1.2021 23:59:59"), dateOfBirth)); // ERROR! returns incorrect age=21 here
        assertEquals(21, getAge(df.parse("10.1.2021 00:00:01"), dateOfBirth));
    }
}

1
public class CalculateAge { 

private int age;

private void setAge(int age){

    this.age=age;

}
public void calculateAge(Date date){

    Calendar calendar=Calendar.getInstance();

    Calendar calendarnow=Calendar.getInstance();    

    calendarnow.getTimeZone();

    calendar.setTime(date);

    int getmonth= calendar.get(calendar.MONTH);

    int getyears= calendar.get(calendar.YEAR);

    int currentmonth= calendarnow.get(calendarnow.MONTH);

    int currentyear= calendarnow.get(calendarnow.YEAR);

    int age = ((currentyear*12+currentmonth)-(getyears*12+getmonth))/12;

    setAge(age);
}
public int getAge(){

    return this.age;

}

0
/**
 * Compute from string date in the format of yyyy-MM-dd HH:mm:ss the age of a person.
 * @author Yaron Ronen
 * @date 04/06/2012  
 */
private int computeAge(String sDate)
{
    // Initial variables.
    Date dbDate = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");      

    // Parse sDate.
    try
    {
        dbDate = (Date)dateFormat.parse(sDate);
    }
    catch(ParseException e)
    {
        Log.e("MyApplication","Can not compute age from date:"+sDate,e);
        return ILLEGAL_DATE; // Const = -2
    }

    // Compute age.
    long timeDiff = System.currentTimeMillis() - dbDate.getTime();      
    int age = (int)(timeDiff / MILLI_SECONDS_YEAR);  // MILLI_SECONDS_YEAR = 31558464000L;

    return age; 
}

Bunu gerçekten test edip etmediğinizden emin değilim, ancak diğerleri için bu yöntemin bir kusuru var. bugün doğum tarihinizle aynı aysa ve bugün <doğum günü, hala gerçek yaş + 1 gösteriyorsa, örneğin gününüz 7 Eylül 1986 ise ve bugün 1 Eylül 2013 ise, bunun yerine size 27 gösterecektir. 26.
srahul07

2
Bir yıldaki milisaniye sayısı SABİT DEĞİLDİĞİ için bu doğru olamaz. Artık yıllarda bir gün daha var, bu diğerlerinden çok daha fazla milisaniye. 40 yaşındaki bir kişi için algoritmanız doğum gününü 9 - 10 gün önce rapor edebilir. Ayrıca artık saniye var.
Espinosa

0

İşte yıl, ay ve gün cinsinden yaşı hesaplamak için java kodu.

public static AgeModel calculateAge(long birthDate) {
    int years = 0;
    int months = 0;
    int days = 0;

    if (birthDate != 0) {
        //create calendar object for birth day
        Calendar birthDay = Calendar.getInstance();
        birthDay.setTimeInMillis(birthDate);

        //create calendar object for current day
        Calendar now = Calendar.getInstance();
        Calendar current = Calendar.getInstance();
        //Get difference between years
        years = now.get(Calendar.YEAR) - birthDay.get(Calendar.YEAR);

        //get months
        int currMonth = now.get(Calendar.MONTH) + 1;
        int birthMonth = birthDay.get(Calendar.MONTH) + 1;

        //Get difference between months
        months = currMonth - birthMonth;

        //if month difference is in negative then reduce years by one and calculate the number of months.
        if (months < 0) {
            years--;
            months = 12 - birthMonth + currMonth;
        } else if (months == 0 && now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
            years--;
            months = 11;
        }

        //Calculate the days
        if (now.get(Calendar.DATE) > birthDay.get(Calendar.DATE))
            days = now.get(Calendar.DATE) - birthDay.get(Calendar.DATE);
        else if (now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
            int today = now.get(Calendar.DAY_OF_MONTH);
            now.add(Calendar.MONTH, -1);
            days = now.getActualMaximum(Calendar.DAY_OF_MONTH) - birthDay.get(Calendar.DAY_OF_MONTH) + today;
        } else {
            days = 0;
            if (months == 12) {
                years++;
                months = 0;
            }
        }
    }

    //Create new Age object
    return new AgeModel(days, months, years);
}

0

Herhangi bir kütüphane olmadan en kolay yol:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;

1
Bu kod, java.time sınıfları tarafından desteklenen, artık eski olan sıkıntılı eski tarih-saat sınıflarını kullanır. Bunun yerine, Java: 'da yerleşik olan modern sınıfları kullanın ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() ). Doğru Cevabı
Basil Bourque

DateUtilsbir kütüphane
Terran

0

Java 8 ile, bir kişinin yaşını bir kod satırı ile hesaplayabiliriz:

public int calCAge(int year, int month,int days){             
    return LocalDate.now().minus(Period.of(year, month, days)).getYear();         
}

yıl veya ay yaşı? ayda bebeğe ne dersin?
gumuruh

-1
public int getAge(Date dateOfBirth) 
{
    Calendar now = Calendar.getInstance();
    Calendar dob = Calendar.getInstance();

    dob.setTime(dateOfBirth);

    if (dob.after(now)) 
    {
        throw new IllegalArgumentException("Can't be born in the future");
    }

    int age = now.get(Calendar.YEAR) - dob.get(Calendar.YEAR);

    if (now.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR)) 
    {
        age--;
    }

    return age;
}

@sinuhepop "DAY_OF_YEAR karşılaştırması artık yıllar ile uğraşırken hatalı sonuçlara yol açabilir" fark
Krzysztof Kot

-1
import java.io.*;

class AgeCalculator
{
    public static void main(String args[])
    {
        InputStreamReader ins=new InputStreamReader(System.in);
        BufferedReader hey=new BufferedReader(ins);

        try
        {
            System.out.println("Please enter your name: ");
            String name=hey.readLine();

            System.out.println("Please enter your birth date: ");
            String date=hey.readLine();

            System.out.println("please enter your birth month:");
            String month=hey.readLine();

            System.out.println("please enter your birth year:");
            String year=hey.readLine();

            System.out.println("please enter current year:");
            String cYear=hey.readLine();

            int bDate = Integer.parseInt(date);
            int bMonth = Integer.parseInt(month);
            int bYear = Integer.parseInt(year);
            int ccYear=Integer.parseInt(cYear);

            int age;

            age = ccYear-bYear;
            int totalMonth=12;
            int yourMonth=totalMonth-bMonth;

            System.out.println(" Hi " + name + " your are " + age + " years " + yourMonth + " months old ");
        }
        catch(IOException err)
        {
            System.out.println("");
        }
    }
}

-1
public int getAge(String birthdate, String today){
    // birthdate = "1986-02-22"
    // today = "2014-09-16"

    // String class has a split method for splitting a string
    // split(<delimiter>)
    // birth[0] = 1986 as string
    // birth[1] = 02 as string
    // birth[2] = 22 as string
    // now[0] = 2014 as string
    // now[1] = 09 as string
    // now[2] = 16 as string
    // **birth** and **now** arrays are automatically contains 3 elements 
    // split method here returns 3 elements because of yyyy-MM-dd value
    String birth[] = birthdate.split("-");
    String now[] = today.split("-");
    int age = 0;

    // let us convert string values into integer values
    // with the use of Integer.parseInt(<string>)
    int ybirth = Integer.parseInt(birth[0]);
    int mbirth = Integer.parseInt(birth[1]);
    int dbirth = Integer.parseInt(birth[2]);

    int ynow = Integer.parseInt(now[0]);
    int mnow = Integer.parseInt(now[1]);
    int dnow = Integer.parseInt(now[2]);

    if(ybirth < ynow){ // has age if birth year is lesser than current year
        age = ynow - ybirth; // let us get the interval of birth year and current year
        if(mbirth == mnow){ // when birth month comes, it's ok to have age = ynow - ybirth if
            if(dbirth > dnow) // birth day is coming. need to subtract 1 from age. not yet a bday
                age--;
        }else if(mbirth > mnow){ age--; } // birth month is comming. need to subtract 1 from age            
    }

    return age;
}

Not: Tarih biçimi: yyyy-AA-gg. Bu jdk7 test genel bir kod ...
Jhonie

1
Bazı yorumlar sağladıysanız veya bu kodu tam olarak nasıl kullanacağınızı açıklarsanız yardımcı olur. Basitçe kod dökümü genellikle önerilmez ve askerin, yönteminizi neden bu şekilde kodlamaya karar verdiğinizin arkasındaki seçimlerinizi anlamayabilir.
rayryeng

@rayryeng: Jhonie zaten koda yorum ekledi. Bunu anlamak yeterli. Lütfen böyle bir yorum yapmadan önce düşünün ve okuyun.
akshay

@Akshay bu benim için açık değildi. Geriye dönüp kod atmış gibi görünüyordu. Genellikle yorumları okumuyorum. Bunların vücuttan çıkarılması ve bir açıklama olarak ayrı olarak yerleştirilmesi iyi olurdu. Bu benim tercihim olsa ve burada katılmamaya karar verebiliriz .... Bu söyleniyor, neredeyse iki yıl önce olduğu gibi bu yorumu bile yazdım.
rayryeng

@rayryeng: Bu yorumun arkasındaki sebep, olumsuz yorumlar yazmak insanların böyle güzel bir forum kullanmalarını engellemektir. Bu yüzden, olumlu yorumlar vererek onları teşvik etmeliyiz. Bdw, suç yok. Alkış !!!
akshay

-1
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.Period;

public class AgeCalculator1 {

    public static void main(String args[]) {
        LocalDate start = LocalDate.of(1970, 2, 23);
        LocalDate end = LocalDate.now(ZoneId.systemDefault());

        Period p = Period.between(start, end);
        //The output of the program is :
        //45 years 6 months and 6 days.
        System.out.print(p.getYears() + " year" + (p.getYears() > 1 ? "s " : " ") );
        System.out.print(p.getMonths() + " month" + (p.getMonths() > 1 ? "s and " : " and ") );
        System.out.print(p.getDays() + " day" + (p.getDays() > 1 ? "s.\n" : ".\n") );
    }//method main ends here.
}

3
StackOverflow'a katıldığınız için teşekkür ederiz. Sizin için birkaç öneri. [A] Lütfen Cevabınıza biraz tartışma ekleyin. StackOverflow.com bir kod pasajı koleksiyonundan çok daha fazlasıdır. Örneğin, diğer yanıtların çoğu java.util.Date ve Joda-Time kullanırken kodunuzun yeni java.time çerçevesini nasıl kullandığını not edin. [B] Lütfen Cevabınızı, java.time kullanan Meno Hochschild'in benzer Cevapıyla karşılaştırın. Sizinkinin nasıl daha iyi olduğunu açıklayın veya probleme farklı bir açıdan saldırın. Veya daha iyi değilse kendiniz geri çekin.
Basil Bourque

-1
public int getAge(Date birthDate) {
    Calendar a = Calendar.getInstance(Locale.US);
    a.setTime(date);
    Calendar b = Calendar.getInstance(Locale.US);
    int age = b.get(YEAR) - a.get(YEAR);
    if (a.get(MONTH) > b.get(MONTH) || (a.get(MONTH) == b.get(MONTH) && a.get(DATE) > b.get(DATE))) {
        age--;
    }
    return age;
}

-1

Tüm doğru cevapları takdir ediyorum ama bu aynı sorunun kotlin cevabı

Umarım kotlin geliştiricilerine yardımcı olur

fun calculateAge(birthDate: Date): Int {
        val now = Date()
        val timeBetween = now.getTime() - birthDate.getTime();
        val yearsBetween = timeBetween / 3.15576e+10;
        return Math.floor(yearsBetween).toInt()
    }

Bu, endüstri lideri java.time sınıflarımız elimizde olduğu zaman böyle bir matematik yapmak için aptalca görünüyor .
Basil Bourque

Java'da OP istekleri.
Terran
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.