-1

I would like to create an age calculator in a register form without Joda Time, but I have a problem with concatenating an int. It deletes the 0 from the day component (by example 04) and month component, so it completely miscalculates the age. I tried to put it first in a String then into an int, but that doesn't work.

private void setAge(View view) {

    Calendar calendarB = Calendar.getInstance();
    int years = calendarB.get(Calendar.YEAR);
    int month = calendarB.get(Calendar.MONTH);
    int day = calendarB.get(Calendar.DAY_OF_MONTH);
    //int
    currentDate = Integer.valueOf(String.valueOf(years) + String.valueOf(month + 1) + String.valueOf(day));

    Calendar calendar = Calendar.getInstance();

    datePickerDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            //int
            birthDate = Integer.valueOf(String.valueOf(year) + String.valueOf(monthOfYear + 1) + String.valueOf(dayOfMonth));

            ageI = (currentDate - birthDate) / 10000;

            String age = Integer.toString(ageI);
            birth.setText(age);

            datePickerDialog.dismiss();
        }
    }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
}
MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Moh
  • 1
  • 1
  • 1
  • 6
  • Without Joda? Why? Which API level are you targeting anyway? – MC Emperor Apr 09 '19 at 09:48
  • 1
    Possible duplicate of [How do I calculate someone's age in Java?](https://stackoverflow.com/questions/1116123/how-do-i-calculate-someones-age-in-java) – Dang Nguyen Apr 09 '19 at 09:52
  • first, get age by [this](https://stackoverflow.com/questions/1116123/how-do-i-calculate-someones-age-in-java), and then from that `int age` result, format it to `String` like "99", "09" and set back – Dang Nguyen Apr 09 '19 at 09:53
  • @MCEmperor : I would like to target all API, with one setage in Joda and one in Calendar but I'm a newbie, it's not usefull ? – Moh Apr 09 '19 at 10:00
  • Well, using `Calendar` [is wrong](https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api) nowadays. You should use the new Java Date and Time API (in the `java.time` package). If you need to target API levels below 26, then you could use the [ThreeTen Backport](https://www.threeten.org/threetenbp/). Juggling with integers to calculate an age is not the way to do it. The question linked by DangNguyen provides a simple solution: `Period.between(birthDate, currentDate).getYears()`. – MC Emperor Apr 09 '19 at 10:04
  • I don't find how to have "birthdate" and currentdate" in this example. My phone have API 23, thanks for links. – Moh Apr 09 '19 at 10:22

2 Answers2

1

Well, juggling like this with integers to calculate an age is not the way to do it.

First, using the Calendar class is wrong nowadays. You should use the new Java Date and Time API (in the java.time package). The between method of the Period class seemlessly calculates the difference between those two years:

Period.between(birthDate, currentDate);

You can then call getYears to get the years. It takes advantage of the fact that when we humans say our age, we do not round the value at all. For example, if I turn 30 tomorrow, I'm today still 29 years old.

This should work:

final LocalDate now = LocalDate.now();
datePickerDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {

    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        LocalDate birthDate = LocalDate.of(year, monthOfYear, dayOfMonth);
        int age = Period.between(birthDate, now).getYears();
        birth.setText(String.valueOf(age));

        datePickerDialog.dismiss();
    }
}, now.getYear(), now.getMonthValue(), now.getDayOfMonth());

If you need to target API levels below 26, then you could use the ThreeTen ABP, which backports the Java 8 Date and Time functionality.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • Thanks ! I will search how to use ThreeTen ABP now, if you have others good link on that I will take it with pleasure. In any case thank you very much for your complete and illumating answer ! – Moh Apr 09 '19 at 11:12
0

Integer always remove preceding 0 from a value. Use this method/function to convert Int to String with preceding 0.

 // ADDS 0  e.g - 02 instead of 2
    public String checkDigit (int number) {
        return number <= 9 ? "0" + number : String.valueOf(number);
    }

EDIT

In your case, just use these lines

private void setAge(View view) {

Calendar calendarB = Calendar.getInstance();
int years = calendarB.get(Calendar.YEAR);
int month = calendarB.get(Calendar.MONTH);
int day = calendarB.get(Calendar.DAY_OF_MONTH);
//int
currentDate = Integer.valueOf(String.valueOf(years) + String.valueOf(month + 1) + String.valueOf(day));

Calendar calendar = Calendar.getInstance();
Calendar dob = Calendar.getInstance();

datePickerDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        //int
        birthDate = Integer.valueOf(String.valueOf(year) + String.valueOf(monthOfYear + 1) + String.valueOf(dayOfMonth));

        // New code
        dob.set(year, month, day); 
        int age = calendar.get(Calendar.YEAR) - dob.get(Calendar.YEAR);

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

        String age = checkDigit(age);
        birth.setText(age);

        datePickerDialog.dismiss();
    }
}, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
}
Jitesh Prajapati
  • 2,533
  • 4
  • 29
  • 51
  • If you have String "04" and you convert it in integer the it will always remove preceding 0. `Integer.valueOf()` is never return preceding 0. The method `checkDigit()` always convert integer to string with preceding 0. but if you again parse the string in integer using `Integer.valueOf()` then it will remove the 0. – Jitesh Prajapati Apr 09 '19 at 10:26
  • Easy, please, @user392117. I recommend waiting a couple of days before accepting an answer since questions without an accepted answer tend to get more attention, so to allow more answers to roll in before picking the one to accept. I agree that accepting an answer in the end is good style. – Ole V.V. Apr 09 '19 at 14:29