代码之家  ›  专栏  ›  技术社区  ›  Luke

Java时间段(十进制年数)

  •  1
  • Luke  · 技术社区  · 6 年前

    如果我计算2之间的差值 LocalDate java.time

    Period p = Period.between(testDate, today);
    

    然后我得到一个年、月、日的输出,比如:

    Days = 9
    Months = 6
    Years = 18
    

    有人知道一种干净的方法来表示十进制类型的值吗(即,上面的值可能是周围的某个值) 18.5... )?

    3 回复  |  直到 6 年前
        1
  •  7
  •   Oleg    6 年前

    您在一条评论中提到,如果需要可以使用的当前季度,则需要季度年精度 IsoFields.QUARTER_YEARS :

    double yearAndQuarter = testDate.until(today, IsoFields.QUARTER_YEARS) / 4.0;
    

    通过这种方式,您将实际使用时间api,始终获得正确的结果 @Mike

        2
  •  7
  •   Mike Strobel    6 年前

    请不要这样做。

    将两个日期之间的差异表示为“年数”乘数是有问题的,因为两个日期之间一年的平均长度取决于要比较的日期。这很容易出错,而且很难拿出所有必要的测试用例来证明你做对了。

    大多数程序员不应该手动执行日期/时间计算。你实际上是 把它弄错。说真的,有 so many ways horribly wrong . 这个星球上只有少数程序员完全理解其中的许多微妙之处。你问这个问题的事实证明你不是他们中的一员,这没关系——我也不是。你和我们大多数人一样,应该依赖一个可靠的日期/时间API,比如 java.util.time .

    需要一个数字值,那么我能想到的最安全的选择是使用天数,因为 LocalDate API可以为您计算该数字:

    long differenceInDays = testDate.until(today, ChronoUnit.DAYS)
    

    请注意,这个差异是 只有

    LocalDate today = testDate.plus(differenceInDays, ChronoUnit.DAYS)
    

    不要 Period 将年、月和日组件转换为整数天。正确答案取决于所涉及的日期,这就是为什么我们希望


    当精度不重要时

    根据您的评论,精度对您来说不是问题,因为您只想显示某人的年龄,精确到四分之一年左右。你不是想代表一个

    类似于@VGR的近似值应该足以满足这些目的:“年数”应该精确到3天以内(<0.01年),除非人们开始活几十万年,在这种情况下,你可以切换到 double

    @Oleg的方法也很有效,它会给你整个季度的日期差,你可以除以 4 转换成年。这可能是最容易得到正确答案的解决方案,因为您不需要舍入或截断结果。我认为,这是最接近直接解决方案的方法 Java语言util。时间 正确性 :它们将提供完整的单位,但由于浮点类型中涉及的固有错误,它们通常避免提供分数近似值(也有例外,如.NET的) System.TimeSpan ).

    然而,如果你的目标是为人类用户呈现某人的年龄,并且你想要比整年更精确,我认为 18 years, 9 months 18 yr, 9 mo )是一个比 18.75 years .

        3
  •  4
  •   VGR    6 年前

    我会避免使用句号,而只计算天数的差异:

    float years = testDate1.until(today, ChronoUnit.DAYS) / 365.2425f;