3

I am trying to calculate age in java that accounts for months, so just subtracting years will not work. I also want to tell the user if today is their birthday. Here is the code I have so far, but I am afraid it is a bit off. It also will not tell if today is the birthday even though the two dates it's comparing are equal. The way I tried to originally calculate was using milliseconds. The reason you see 2 ways of getting the current date is because I was trying something to get it working, but wanted to show everyone my work so that they could point me in the right direction.

EDIT FOR CLARIFICATION what I mean is 2015-1993 can either be 22 years old or 21 depending if their birthday has already passed this year. I want to be sure that I get the correct age with this in mind.

public class ShowAgeActivity extends AppCompatActivity {

private TextView usersAge;

private static long daysBetween(Date one, Date two)
{
    long difference = (one.getTime()-two.getTime())/86400000; return Math.abs(difference);
}

private Date getCurrentForBirthday()
{
    Date birthday = (Date) this.getIntent().getExtras().get("TheBirthDay");
    int birthdayYear = birthday.getYear() + 1900;
    Calendar cal = Calendar.getInstance();
    cal.set(birthdayYear, Calendar.MONTH, Calendar.DAY_OF_MONTH);
    Date current = cal.getTime();
    return current;
}


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_show_age);


    Date birthday = (Date) this.getIntent().getExtras().get("TheBirthDay");
      Date currentDay = Calendar.getInstance().getTime();

      long age = daysBetween(birthday,currentDay)/365;

      usersAge =(TextView)findViewById(R.id.ageTextView);

    if (birthday.compareTo(getCurrentForBirthday()) == 0 )
    {
        usersAge.setText("It is your birthday, and your Age is " + String.valueOf(age));
    }

    usersAge.setText("Your Age is " + String.valueOf(age));


    }

}

alphamalle
  • 192
  • 1
  • 3
  • 15
  • 2
    clarify what you mean by "account for months" do you want an age to be 22yrs and 4 months, or do you just mean 2015-1993 can either be 22 years old or 21 depending if their birthday has already passed this year – Joseph Duty Sep 24 '15 at 16:24
  • apologies. what I mean is 2015-1993 can either be 22 years old or 21 depending if their birthday has already passed this year – alphamalle Sep 24 '15 at 16:25
  • @alphamalle Please post such additional information or clarification as an edit to your Question rather than as a comment. Don't make your readers work so hard. – Basil Bourque Sep 24 '15 at 18:36

4 Answers4

7

Below is an example of how to calculate a person's age, if today is their birthday, as well as how many days are left until their birthday if today is not their birthday using the new java.time package classes that were included as a part of Java 8.

  LocalDate today             = LocalDate.now();
  LocalDate birthday          = LocalDate.of(1982, 9, 26);
  LocalDate thisYearsBirthday = birthday.with(Year.now());

  long age = ChronoUnit.YEARS.between(birthday, today);

  if (thisYearsBirthday.equals(today))
  {
     System.out.println("It is your birthday, and your Age is " + age);
  }
  else
  {
     long daysUntilBirthday = ChronoUnit.DAYS.between(today, thisYearsBirthday);
     System.out.println("Your age is " + age + ". " + daysUntilBirthday + " more days until your birthday!");
  }
Nate
  • 539
  • 3
  • 6
3

This is a code I use to figure out how old something is.

Long time= currentDate.getTime / 1000 - birthdate.getTime / 1000

int years = Math.round(time) / 31536000;
int months = Math.round(time - years * 31536000) / 2628000; 
Ashley Alvarado
  • 1,078
  • 10
  • 17
3

This works for me.

Calendar currentDate = Calendar.getInstance();

SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

Date birthdate = null;

try {
     birthdate = myFormat.parse(yourDate);
} catch (ParseException e) {
     e.printStackTrace();
}

Long time= currentDate.getTime().getTime() / 1000 - birthdate.getTime() / 1000;

int years = Math.round(time) / 31536000;
int months = Math.round(time - years * 31536000) / 2628000;
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), and `java.text.SimpleTextFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. – Basil Bourque Mar 17 '17 at 01:42
  • Thank you for the information, they should mark this as deprecated. Anyway this was the simplest solution for my problem. – Matheus Soares Apr 07 '17 at 01:16
2

The Answer by Nate is good. But it ignores the issue of time zone. And there is a more explicit approach possible.

Time Zone

Time zone is crucial in determining the date. For example, a new day dawns earlier in Paris than in Montreal.

If omitted, the JVM’s current default time zone is implicitly applied. I suggest you instead make explicit the time zone you expect/desire.

Use a proper time zone name, continent/city style. Never use the 3-4 letter codes such as "EST" or "IST".

java.time

The java.time framework (Tutorial) built into Java 8 and later includes the Periodclass to represent a span of time as a combined number of years, number of months, and number of days.

You can query a Period to extract each of those three components.

Period’s toString method by default generates a string in the format defined by ISO 8601, where a P marks the beginning followed by digit and letter three times. For example, one and a half years: P1Y6M.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
LocalDate birthdate = LocalDate.of( 1960 , 2 , 17 );
Period p = Period.between( birthdate , today );
String output = p.toString();
Integer age = p.getYears();
Boolean isTodayBirthday = ( (p.getMonths() == 0 )  && ( p.getDays() == 0 ) );

Another approach uses the MonthDay class to represent a month-day without a year.

Boolean isBirthdayToday = 
    MonthDay.from( birthdate )
            .equals( MonthDay.from( today ) ) ;

Android

For Android, you do not have Java 8 technology such as java.time.

You can search for some projects that backport java.time classes. I don't know how successful they are.

Also, you can use the Joda-Time, a third-party library that inspired the java.time framework (JSR 310). The Joda-Time code should be similar to the above. Except that the Period class has a finer resolution, going to hours, minutes, and seconds. To truncate that extra data, call the withTimeAtStartOfDay method.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154