【问题标题】:Getting the age in months using Java Time API使用 Java Time API 以月为单位获取年龄
【发布时间】:2019-10-21 22:27:51
【问题描述】:

我编写了我认为简单的时间 API 调用来获取两个 LocalDates 之间的月数和年数。但是,当我进行测试时,数字似乎计算不正确。

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 Time period in decimal number of years Java 8 Date time for calculating age in decimals

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

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

更新:我在断言上犯了一个错误。所以我修复了它们。

【问题讨论】:

  • 只是最后四个断言失败了吗?如果我在 11 月 11 日出生,那么到 1 月 6 日我还是一个月大,而不是两个。
  • 它在assertEquals(0, user.getAgeInMonths(LocalDate.of(2014, 12, 10)));开始失败
  • 这可能是因为plusDays(1) - 您计算的年龄是 12 月 11 日,而不是 12 月 10 日。
  • 那是因为您在getAgeInMonths 中添加了一天:processingDate.plusDays(1)。你为什么要这么做?
  • API 对第二个字段表示“独占”。

标签: java java-time period


【解决方案1】:

我的版本可能是:

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

出于个人喜好,我发现声明参数final 完全是多余的。方法是否修改参数是与方法签名无关的实现细节。

我更喜欢 Math.toIntExact 作为从 long 转换为 int 的更安全的方式。 int溢出时会抛出异常。

另外,出于兴趣,当我们只对几个月感兴趣时,我们不需要通过 Period 类。

【讨论】:

    【解决方案2】:

    终于成功了

    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();
    
    }
    

    【讨论】:

    • 现在我愿意。我在找getTotalMonths
    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 2017-04-24
    • 2011-06-10
    • 2019-07-07
    • 1970-01-01
    • 2018-08-04
    相关资源
    最近更新 更多