java मैं जावा में किसी की उम्र की गणना कैसे करूं?




date calendar (18)

मैं जावा विधि में एक int के रूप में वर्षों में एक उम्र वापस करना चाहता हूँ। मेरे पास अब निम्न है जहां प्राप्त करें जन्मदिन () दिनांक वस्तु (जन्म तिथि के साथ ;-)) देता है:

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

    Date age = new Date(ageInMillis);

    return age.getYear();
}

लेकिन जब से getear () को बहिष्कृत किया गया है, तो मुझे आश्चर्य है कि ऐसा करने का कोई बेहतर तरीका है या नहीं? मुझे यह भी यकीन नहीं है कि यह सही तरीके से काम करता है, क्योंकि मेरे पास जगह में अभी तक कोई यूनिट परीक्षण नहीं है (अभी तक)।

https://code.i-harness.com


आधुनिक उत्तर और सिंहावलोकन

ए) जावा -8 (जावा.टाइम-पैकेज)

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

ध्यान दें कि अभिव्यक्ति LocalDate.now() पूरी तरह से सिस्टम LocalDate.now() से संबंधित है (जिसे अक्सर उपयोगकर्ताओं द्वारा अनदेखा किया जाता है)। स्पष्टता के लिए now(ZoneId.of("Europe/Paris")) ओवरलोडेड विधि का उपयोग करना बेहतर होता है now(ZoneId.of("Europe/Paris")) एक स्पष्ट now(ZoneId.of("Europe/Paris")) निर्दिष्ट करते हैं (उदाहरण के लिए यहां "यूरोप / पेरिस")। यदि सिस्टम LocalDate.now(ZoneId.systemDefault()) से अनुरोध किया गया है तो मेरी व्यक्तिगत प्राथमिकता सिस्टम LocalDate.now(ZoneId.systemDefault()) स्पष्ट से संबंध बनाने के लिए LocalDate.now(ZoneId.systemDefault()) लिखना है। यह अधिक लेखन प्रयास है लेकिन पढ़ने को आसान बनाता है।

बी) जोडा-टाइम

कृपया ध्यान दें कि प्रस्तावित और स्वीकृत जोडा-टाइम-सॉल्यूशन ऊपर दिखाए गए तिथियों (एक दुर्लभ मामला) के लिए एक अलग गणना परिणाम उत्पन्न करता है, अर्थात्:

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

मैं इसे एक छोटी सी बग के रूप में मानता हूं लेकिन जोडा-टीम के पास इस अजीब व्यवहार पर एक अलग दृश्य है और यह इसे ठीक नहीं करना चाहता (अजीब क्योंकि समाप्ति तिथि का दिन-दर-दिन प्रारंभ तिथि से छोटा है, इसलिए वर्ष होना चाहिए एक कम)। यह बंद issue भी देखें।

सी) java.util. कैलेंडर आदि

तुलना के लिए कई अन्य उत्तरों देखें। मैं इन पुरानी कक्षाओं का उपयोग बिल्कुल अनुशंसा नहीं करता क्योंकि परिणामस्वरूप कोड अभी भी कुछ विदेशी मामलों में त्रुटिप्राप्त है और / या इस तथ्य पर विचार करने के लिए बहुत जटिल है कि मूल प्रश्न इतना आसान लगता है। वर्ष 2015 में हमारे पास वास्तव में बेहतर पुस्तकालय हैं।

डी) दिनांक 4 जे के बारे में:

प्रस्तावित समाधान सरल है लेकिन कभी-कभी लीप वर्षों के मामले में असफल हो जाता है। साल के दिन का मूल्यांकन करना विश्वसनीय नहीं है।

ई) मेरी खुद की लाइब्रेरी Time4J :

यह जावा -8-समाधान के समान काम करता है। LocalDate द्वारा PlainDate और ChronoUnit.YEARS द्वारा LocalDate को बस प्रतिस्थापित करें। हालांकि, "आज" प्राप्त करने के लिए एक स्पष्ट टाइमज़ोन संदर्भ की आवश्यकता है।

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

इसे अपने कोड में कॉपी करने का प्रयास करें, फिर आयु प्राप्त करने के लिए विधि का उपयोग करें।

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;
}

किसी भी पुस्तकालय के बिना सबसे आसान तरीका:

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

खेत जन्म और प्रभाव दोनों तारीख फ़ील्ड हैं:

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);

यह मूल रूप से कमजोर तरीकों का उपयोग किए बिना जॉन ओ के समाधान का एक संशोधन है। मैंने अपने कोड में अपने कोड को काम करने की कोशिश करने में काफी समय बिताया। शायद यह उस समय दूसरों को बचाएगा।


जेडीके 8 यह आसान और सुरुचिपूर्ण बनाता है:

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;
        }
    }
}

इसके उपयोग का प्रदर्शन करने के लिए एक जुनीट परीक्षण:

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);
    }
}

अब तक सभी को जेडीके 8 का उपयोग करना चाहिए। सभी पुराने संस्करणों ने उनके समर्थन जीवन के अंत को पारित कर दिया है।


मैं अपने लाभ के लिए एक वर्ष निरंतर मूल्य में मिलीसेकंड का उपयोग करता हूं:

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

यदि आप जीडब्ल्यूटी का उपयोग कर रहे हैं तो आप java.util.Date का उपयोग करने तक ही सीमित रहेंगे, यहां एक विधि है जो तिथि को पूर्णांक के रूप में लेती है, लेकिन अभी भी java.util.Date का उपयोग करती है:

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;
}

यरॉन रोनेन समाधान के सुरुचिपूर्ण, प्रतीत होता है कि सही , टाइमस्टैम्प अंतर आधारित संस्करण।

मैं यह साबित करने के लिए एक इकाई परीक्षण भी शामिल कर रहा हूं कि यह कब और क्यों सही नहीं है । किसी भी टाइमस्टैम्प अंतर में लीप दिनों (और सेकंड) की अलग-अलग संख्या (संभवतः) के कारण असंभव है। इस एल्गोरिदम के लिए विसंगति अधिकतम + -1 दिन (और एक सेकंड) होनी चाहिए, test2 () देखें, जबकि समय के पूर्ण निरंतर धारणा के आधार पर timeDiff / MILLI_SECONDS_YEAR रोनेन समाधान 40f वर्ष के लिए 10 दिनों से भिन्न हो सकता है, फिर भी यह संस्करण है भी गलत

यह मुश्किल है, क्योंकि यह बेहतर संस्करण, formula diffAsCalendar.get(Calendar.YEAR) - 1970 का उपयोग करके, अधिकांश समय सही परिणाम देता है, क्योंकि दो तिथियों के बीच औसत में लीप वर्ष की संख्या होती है।

/**
 * 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));
    }
}

यह शायद आश्चर्यजनक है कि आपको यह जानने की आवश्यकता नहीं है कि एक वर्ष में कितने दिन या महीने हैं या उन महीनों में कितने दिन हैं, वैसे ही, आपको लीप साल, लीप सेकंड या किसी के बारे में जानने की आवश्यकता नहीं है इस सरल, 100% सटीक विधि का उपयोग करके उस सामान का:

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;
}

साल, महीने और दिनों में उम्र की गणना करने के लिए जावा कोड यहां दिया गया है।

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);
}

Joda , जो तिथि / समय की गणना को सरल बनाता है (जोडा भी नई मानक जावा तिथि / समय एपीआईएस का आधार है, इसलिए आप जल्द से जल्द मानक एपीआई सीखेंगे)।

संपादित करें: जावा 8 में कुछ समान है और यह जांचने योग्य है।

जैसे

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

जो आप चाहते हैं उतना सरल है। प्री-जावा 8 सामान कुछ है (जैसा कि आपने पहचाना है) कुछ हद तक अनजान है।


डेट 4 जी लाइब्रेरी के साथ:

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

/**
 * 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; 
}

/**
 * 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;
}

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("");
        }
    }
}

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.
}

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;
}

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;
}





calendar