0

I am new to android development and I'm trying to develop an age calculator. With my current code I'm able to find the difference between years and months correctly but the days are not correct. I know I'm doing something wrong. But I'm not able to figure it out. I also used jodatime api, but when I used it my app closed when I call this function I am not able to understand what I am doing wrong. My code is:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         mDateDisplay = (TextView) findViewById(R.id.showMyDate);        
            mPickDate = (Button) findViewById(R.id.myDatePickerButton);

            mPickDate.setOnClickListener(new View.OnClickListener() {
                @SuppressWarnings("deprecation")
                public void onClick(View v) {
                    showDialog(DATE_DIALOG_ID);
                }
            });

            dob_Year = c.get(Calendar.YEAR);
            dob_Month = c.get(Calendar.MONTH);
            dob_Day = c.get(Calendar.DAY_OF_MONTH);
// display the current date
            updateDisplay();
                }

    private void updateAge()
    {
        current_Year = c.get(Calendar.YEAR);
        current_Month = c.get(Calendar.MONTH);
        current_Day = c.get(Calendar.DAY_OF_YEAR);

        if (current_Day < dob_Day) {
            current_Month--;

            current_Day+=c.getMaximum(dob_Month);
           }
if (current_Month < dob_Month) {
            current_Year--;
            current_Month += 12;
        }
int ageYear=current_Year-dob_Year;
int ageMonths=current_Month-dob_Month;
int ageDays= current_Day-dob_Day;
 this.mAgeDisplay.setText(
                new StringBuilder()

                        .append(ageYear).append(" Years ")
                        .append(ageMonths).append(" Months ")
                        .append(ageDays).append(" Days "));
    }

    private void updateDisplay() {
        this.mDateDisplay.setText(
            new StringBuilder()
                    // Month is 0 based so add 1
                    .append(dob_Day).append("-")
                    .append(dob_Month + 1).append("-")
                    .append(dob_Year).append(" "));
    }
    private DatePickerDialog.OnDateSetListener mDateSetListener =
            new DatePickerDialog.OnDateSetListener() {
                public void onDateSet(DatePicker view, int year, 
                                      int monthOfYear, int dayOfMonth) {
                    dob_Year = year;
                    dob_Month = monthOfYear;
                    dob_Day = dayOfMonth;
                    updateDisplay();
                    updateAge();
                }
            };
            @Override
            protected Dialog onCreateDialog(int id) {
               switch (id) {
               case DATE_DIALOG_ID:
                  return new DatePickerDialog(this,
                            mDateSetListener,
                            dob_Year, dob_Month, dob_Day);
               }
               return null;
            }

In this code fragment dob_ variables get their values from datepicker.

Teji
  • 1
  • 1

3 Answers3

1

First, you should set the task in a correct way. Define, what do you mean by these "days". Obviously, you want to get a date difference in Years-Months-Days form. The difference in days only can be counted easily - take difference of timestamps in secs and divide it by 24*3600.

Now you need to subtract from it the numbers of days in the whole months and years. But their lengths ( of the whole years and Februaries) vary. What lengths should be taken? The lengths of the calendar months are set accodring to the calendar. But that months of the difference are not tied to any calendar. For example, the first date and thus the first month of the difference start at 5.Feb. When should this first month end? 5.March of the same calendar year? Or in 30 days? 31? 28? 29?

You can't resolve the programming task before resolving the logical task. And here we all merely can propose some variants - we don't know what do you really need.

Just now, before you have defined the task, you can't say that your code counts correctly anything.


As I can guess by the code, you are accepting the length of the month in the "difference sequence" as equal to the length of the "appropriate" calendar month, that ends in this "difference month". The problem is, that for the detection if the month is appropriate, you already have to know its length.

You have to detaily and explicitly and in human language or diagrams set the rules by which the lengths of the "differece months" should be counted. Your problem is that you are trying to fomalize the informal term - "age". And don't forget, that even if you would invent some rule of formalization, it doesn't mean that other people will agree with it and will feel it as you.

You could easily count the whole canendar days, months and years, lived by a person. But then don't use the term "age", but three terms: days you lived, whole months you lived, whole years you lived. And prepare, that there could be more than 12 months and more than 31 days. But the result will be unambiguous.

You could count the whole years and months as you do now. But in this case "age" between 28.Feb and 28. March will be a month. Do you feel it as a correct result? Are you sure? Are you sure that other people feel it so?

And if you think that code demonstrates your inner feelings how the age should be counted, you could simply define what you are counting as "age".

Edited:

You have three errors in the line

current_Day+=c.getMaximum(dob_Month);

First, use getActualMaximum. Second, you should take the number of days in the previous month. Third, the argument should be Calendar.Month.

And please, make this part of code a function. A function that counts the difference of two calendar dates, given as parameters. You have absolutely no need in global fields and it is bad practice - the errors become hidden. When I worked with your code, I made it as a function... and found the erroneous line at once

Gangnus
  • 24,044
  • 16
  • 90
  • 149
  • boss jst tell me the problem in my logic. i want my result like 24 years 7 months 18 days on dates 24 may,1988 to 11 jan,2013. from my code i got 7 days. plz tel me the logic. – Teji Jan 11 '13 at 15:15
  • Ahem. It is **you** who should set the task. It is not defined yet. The only task I see is your code. BTW, what I see, on your example it gives exactly 18 days that you need, not 7. You have done an error somewhere out of it. Put the example in the question, too, plz. – Gangnus Jan 11 '13 at 17:09
  • Thanks by a questioner should be expressed in marking the answer. :-) – Gangnus Jan 12 '13 at 16:02
0

Maybe this function can help:

public static long daysBetween(Calendar startDate, Calendar endDate) {  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  

Also the following maybe interesting to read: how to calculate difference between two dates using java Also credits go to: http://tripoverit.blogspot.nl/2007_07_01_archive.html

Community
  • 1
  • 1
Stephan Celis
  • 2,492
  • 5
  • 23
  • 38
  • His code counts days **equivalently** to yours and is shorter (I mean its "days" part is). And the links don't fit here. He does not count the difference, but presents it by three numbers - y-m-d. Here is hte problem – Gangnus Jan 11 '13 at 09:33
  • sir with your function i get 8973 days if startDate=24/05/1988 and endDate=11/01/2013 which is incorrect if i compare this result with win 7 inbuilt calculator's result which is 8998 days. and actually i want my result like 24 years 7 months 18 days. from my code i found 24 years 7 month 7 days. that days are not coming properly. – Teji Jan 11 '13 at 14:57
0

The most direct way to achieve this is to calculate the difference in milliseconds and then convert up:

long Milli=(EndDate.getTime() - startDate.getTime());
long Seconds=Milli/1000; 
long Days = Seconds/60L/60L/24L;
Elemental
  • 7,365
  • 2
  • 28
  • 33