patternjavaMinor
Age in years at a specific date
Viewed 0 times
agespecificdateyears
Problem
For eligibility to events I need to know the age of a competitor at a specific date.
Now the thing is the date calculations are checked in two places, an online PHP app where the entries are registered, and an offline Java app that runs the events.
So I have 2 versions of the same code, the PHP one was written originally and the Java is a conversion of that. (So that I am using the same calculations in both places).
My Java skills are very rusty.
I am happy to take any improvements onboard, but it is essential that both calculations return the same result.
PHP
Java
Now the thing is the date calculations are checked in two places, an online PHP app where the entries are registered, and an offline Java app that runs the events.
So I have 2 versions of the same code, the PHP one was written originally and the Java is a conversion of that. (So that I am using the same calculations in both places).
My Java skills are very rusty.
I am happy to take any improvements onboard, but it is essential that both calculations return the same result.
PHP
public function ageAt($age_reference_date) {
$ts_ref = strtotime($age_reference_date);
list($dob_year, $dob_month, $dob_day) = explode('-', $this->date_of_birth);
$age = date('Y', $ts_ref) - $dob_year;
if (date('md', $ts_ref) < $dob_month.$dob_day) {
$age--;
}
return $age;
}Java
public int ageAt(Date ageReferenceDate) {
Calendar calAgeReferenceDate = Calendar.getInstance();
Calendar calDateOfBirth = Calendar.getInstance();
int refDateMonth;
int dobDateMonth;
int age;
calAgeReferenceDate.setTime(ageReferenceDate);
calDateOfBirth.setTime(this.dateOfBirth);
age = calAgeReferenceDate.get(Calendar.YEAR) - calDateOfBirth.get(Calendar.YEAR);
refDateMonth = Integer.parseInt(String.format("%02d", calAgeReferenceDate.get(Calendar.MONTH)) + String.format("%02d", calAgeReferenceDate.get(Calendar.DAY_OF_MONTH)));
dobDateMonth = Integer.parseInt(String.format("%02d", calDateOfBirth.get(Calendar.MONTH)) + String.format("%02d", calDateOfBirth.get(Calendar.DAY_OF_MONTH)));
if (refDateMonth < dobDateMonth) {
age--;
}
return age;
}Solution
In Java 8 you can more accurately represent the dateOfBirth with a
If the
It is fairly easy, albeit a bit verbose, to convert a
The catch is that you need to interpret it vs. a
This is also the reason why it is a better idea to represent date of birth as a
LocalDate.If the
ageAt() method also takes a LocalDate as argument, then the age is easily computed using Period.public int ageAt(LocalDate ageReferenceDate) {
return Period.between(dateOfBirth, ageReferenceDate).getYears();
}It is fairly easy, albeit a bit verbose, to convert a
Date instance to a LocalDate :LocalDate localDate = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate();The catch is that you need to interpret it vs. a
ZoneId. A Date can be mapped to different LocalDates depending on what ZoneId (TimeZone's successor) it is evaluated against. You should use the ZoneId that was used when the Date was recorded. That is probably ZoneId.systemDefault(), but if your code can run on systems accross time zones, you can have a problem.This is also the reason why it is a better idea to represent date of birth as a
LocalDate, since it does away with that ambiguity.Code Snippets
public int ageAt(LocalDate ageReferenceDate) {
return Period.between(dateOfBirth, ageReferenceDate).getYears();
}LocalDate localDate = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate();Context
StackExchange Code Review Q#85002, answer score: 2
Revisions (0)
No revisions yet.