0

What would be the easiest way to calculate the next birthday given a birthdate (in a Date object) ?

I believe java.time is the library people are trending towards.

The solution below shows how to find the next day of week, but the documentation does not appear to support this scenario. How can I get a DateTime corresponding to next occurence of hour, minute?

Thanks!

C Chow
  • 3
  • 2
  • 5
    Your first point of call should the JavaDocs, probably starting with [`LocalDate`](https://docs.oracle.com/javase/10/docs/api/java/time/LocalDate.html), which would probably lead you to [`LocalDate#plusYears(long)`](https://docs.oracle.com/javase/10/docs/api/java/time/LocalDate.html#plusYears(long)) – MadProgrammer Jan 08 '20 at 20:54
  • You might also want to take look at [Date and Time Classes](https://docs.oracle.com/javase/tutorial/datetime/iso/datetime.html) – MadProgrammer Jan 08 '20 at 20:54
  • *I believe java.time is the library people are trending towards.* You are completely correct. Therefore don’t use the `Date` class, it’s poorly designed and outdated (no pun intended). – Ole V.V. Jan 10 '20 at 00:12
  • Does this answer your question? [Adding Years from Date class](https://stackoverflow.com/questions/11642701/adding-years-from-date-class) – Ole V.V. Jan 10 '20 at 00:14
  • Corner case: A person born on February 29 may have celebrated her/his last birthday on Feb 28, 2019, but doesn’t intend to consider Feb 28, 2020 the next one. If very strict you may consider the next birthday from Feb 29 to be Feb 29 in the next leap year. – Ole V.V. Jan 10 '20 at 00:17

2 Answers2

2

Assumption - you have a java.util.Date input and you want a java.util.Date output.

First recommendation - stop using java.util.Date. The newer java.time API is better implemented and, once you get use to using it, easier to use

Ok, first, we want to convert the java.util.Date to a java.time.LocalDate...

public LocalDate toLocalDate(Date dateToConvert) {
    return dateToConvert.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
}

From there, it's a simple case of just adding another year...

LocalDate nextBirthDate = toLocalDate(someDate).plusYear(1);

Remember, java.time objects are not mutable.

Finally, you can convert the LocalDate back to a java.util.Date if required

public Date toUtilDate(LocalDate dateToConvert) {
    return java.util.Date.from(dateToConvert.atStartOfDay()
      .atZone(ZoneId.systemDefault())
      .toInstant());
}

but this raises a bunch of questions over why you'd even bother (going back to java.util.Date). Once you can get out of that API and into the newer java.time API, you should try and stay there (IMHO)

nb Date conversations from Convert Date to LocalDate or LocalDateTime and Back

"from" and "with" seemed the most promising..but ultimately don't support this use case (i.e. cannot give the next instance of LocalDate given a Day and Month)

Still not seeing the issue. The following examples takes a original birthdate, the current and determines the "next" birthdate based on if the current "year date" is before or after today

LocalDate orignalBirthDate = LocalDate.of(1972, Month.MARCH, 8);
LocalDate today = LocalDate.now();
int year = today.getYear();

LocalDate nextBirthDate = orignalBirthDate.withYear(year);
if (nextBirthDate.isBefore(today)) {
    nextBirthDate = nextBirthDate.plusYears(1);
}

System.out.println("Next birthday = " + DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(nextBirthDate));
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • You might also want to add some edge case handling when the original birthday falls on Feb 29th. – Jason Jan 08 '20 at 21:19
  • @Jason At this point - I'll leave that to the OP (and off the top of my head, I don't know the rules ) – MadProgrammer Jan 08 '20 at 21:23
  • Thanks! But doesn't this assume "someDate" is the last birthday date ? – C Chow Jan 08 '20 at 22:06
  • Thanks! But doesn't this assume "someDate" is the last birthday date ? If "someDate" is the birth date (e.g. Jan 6, 1977), I would want to get the next birthday date from today (i.e. Jan 6, 2020) ? I could manually do this by adding number of age + 1 years; but was wondering if i was overlooking a method (similiar to TemporalAdjusters). – C Chow Jan 08 '20 at 22:12
  • @CChow And what did the [JavaDocs](https://docs.oracle.com/javase/10/docs/api/java/time/LocalDate.html#withYear(int)) show you? – MadProgrammer Jan 08 '20 at 22:24
  • "from" and "with" seemed the most promising..but ultimately don't support this use case (i.e. cannot give the next instance of LocalDate given a Day and Month) – C Chow Jan 09 '20 at 17:49
-1
public Date getBirthDay(Date d) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(d);
    cal.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
    if (new Date().after(cal.getTime())) cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + 1);
    return cal.getTime();
}
Maxdola
  • 1,562
  • 2
  • 10
  • 29
  • 1
    Not your down-voter, but you might want to add some textual explanation with your code. Code-dump answers aren't very helpful for future visitors. Please check out the [answer]. – Hovercraft Full Of Eels Jan 08 '20 at 20:59
  • 2
    Not your down-voter, but, `java.util.Date` and associated classes are consider effectively deprecated and all date/time functionality should be handled through the `java.time` APIs instead (even if you're still stuck in java 7-, you should make use of the ThreeTen-backport) - there is little use in continuing to make use of these older APIs – MadProgrammer Jan 08 '20 at 21:05