Получение возраста в месяцах с использованием Java Time API - PullRequest
0 голосов
/ 22 октября 2019

Я написал, как мне кажется, простой вызов времени API, чтобы получить количество месяцев и лет между двумя LocalDate с. Тем не менее, когда я выполняю свои тесты, кажется, что числа вычисляются неправильно.

https://repl.it/@trajano/LocalDate-Period-Ages?language=java

import java.time.*;
import java.time.temporal.*;
import static org.junit.Assert.assertEquals;
class Main {
  public static void main(String[] args) {

    {
        User user = new User();
        user.setDateOfBirth(LocalDate.of(2014, 11, 11));
        assertEquals(0, user.getAgeInMonths(LocalDate.of(2014, 11, 11)));
        assertEquals(0, user.getAgeInMonths(LocalDate.of(2014, 11, 12)));
        assertEquals(0, user.getAgeInMonths(LocalDate.of(2014, 12, 10)));
        assertEquals(1, user.getAgeInMonths(LocalDate.of(2014, 12, 11)));
        assertEquals(1, user.getAgeInMonths(LocalDate.of(2014, 12, 25)));
        assertEquals(1, user.getAgeInMonths(LocalDate.of(2015, 1, 6)));
        assertEquals(1 + 12, user.getAgeInMonths(LocalDate.of(2016, 1, 6)));
        assertEquals(1 + 12 * 2, user.getAgeInMonths(LocalDate.of(2017, 1, 6)));
        assertEquals(1 + 12 * 3, user.getAgeInMonths(LocalDate.of(2018, 1, 6)));    }
  }
}

class User {
  LocalDate dateOfBirth;

  public void setDateOfBirth(LocalDate dateOfBirth) {
    this.dateOfBirth = dateOfBirth;
  }

  public int getAge(final LocalDate processingDate) {

    return (int) Period.between(dateOfBirth, processingDate.plusDays(1)).get(ChronoUnit.YEARS);
  }

  public int getAgeInMonths(final LocalDate processingDate) {
    return (int) Period.between(dateOfBirth, processingDate.plusDays(1)).get(ChronoUnit.MONTHS);
  }

  public int getAge() {
    return getAge(LocalDate.now());
  }

  public int getAgeInMonths() {
    return getAgeInMonths(LocalDate.now());
  }
}

Я пробовал и Period., и ChronoUnit.MONTHS, но утверждения не сработали,Использование кода из Период времени Java в десятичном числе лет Java 8 Дата и время для расчета возраста в десятичных числах

return (int) Period.between(dateOfBirth, processingDate.plusDays(1)).get(ChronoUnit.MONTHS);

и

return (int) ChronoUnit.MONTHS.between(dateOfBirth, processingDate.plusDays(1));

ОБНОВЛЕНИЕ: я сделал ошибку в утверждениях. Поэтому я исправил их.

Ответы [ 2 ]

2 голосов
/ 22 октября 2019

Моя версия, вероятно, будет выглядеть следующим образом:

public int getAgeInMonths(LocalDate processingDate) {
    return Math.toIntExact(ChronoUnit.MONTHS.between(dateOfBirth, processingDate));
}

На вкус я считаю излишним объявлять параметр final. Изменяет ли метод параметр или нет, это деталь реализации, не относящаяся к сигнатуре метода.

Я предпочитаю Math.toIntExact как более безопасный способ преобразования из long в int. Это приведет к исключению в случае переполнения int.

Также для вкуса, когда все, что нас интересует, это месяцы, нам не нужно проходить класс Period.

1 голос
/ 22 октября 2019

Вот что наконец сработало

public int getAge(final LocalDate processingDate) {

    return Period.between(dateOfBirth, processingDate).getYears();
}

public int getAgeInMonths(final LocalDate processingDate) {

    return (int) Period.between(dateOfBirth, processingDate).toTotalMonths();

}
...