Joda-Time,Period计算问题?

huangapple go评论49阅读模式
英文:

Joda-time, Period calculate issue?

问题

以下代码返回相同的结果,相差5年。
应该是5Y、5Y1D和5Y2D吗?

val date1 = org.joda.time.LocalDate(2025, 2, 28)
val date2 = org.joda.time.LocalDate(2019, 11, 28).plusMonths(3)
val ddd = org.joda.time.Period(date2, date1)
println("${ddd.years} ${ddd.months} ${ddd.days}")

val date1 = org.joda.time.LocalDate(2025, 2, 28)
val date2 = org.joda.time.LocalDate(2019, 11, 29).plusMonths(3)
val ddd = org.joda.time.Period(date2, date1)
println("${ddd.years} ${ddd.months} ${ddd.days}")

val date1 = org.joda.time.LocalDate(2025, 2, 28)
val date2 = org.joda.time.LocalDate(2019, 11, 30).plusMonths(3)
val ddd = org.joda.time.Period(date2, date1)
println("${ddd.years} ${ddd.months} ${ddd.days}")
英文:

the below codes returns same result, a 5 years difference.
should be 5Y, 5Y1D and 5Y2D?

val date1 = org.joda.time.LocalDate(2025,2,28) 
val date2 = org.joda.time.LocalDate(2019,11,28).plusMonths(3) 
val ddd = org.joda.time.Period(date2, date1)
println("${ddd.years} ${ddd.months} ${ddd.days}")

val date1 = org.joda.time.LocalDate(2025,2,28) 
val date2 = org.joda.time.LocalDate(2019,11,29).plusMonths(3) 
val ddd = org.joda.time.Period(date2, date1) 
println("${ddd.years} ${ddd.months} ${ddd.days}")

val date1 = org.joda.time.LocalDate(2025,2,28) 
val date2 = org.joda.time.LocalDate(2019,11,30).plusMonths(3) 
val ddd = org.joda.time.Period(date2, date1) 
println("${ddd.years} ${ddd.months} ${ddd.days}")

答案1

得分: 2

不,不应该。

首先,在将三个月添加到2019年11月28日、29日或30日时,得到的结果是2020年2月28日、29日和29日(!)。 2020年是闰年,所以2月有29天,而不是30天。接下来,从2020年2月29日到2025年2月28日的时间段是什么?这并没有被很好地定义。你可能会争论它不到5年,也许是4年11个月30天?然而,Joda-Time选择将其视为5年,因为这两个日期都在月底。

英文:

No, it should not.

First, when adding three months to either 28, 29 or 30 November 2019, you are getting 28, 29 and 29(!) February 2020. 2020 is a leap year, so February has 29 days, not 30. Next, what is the period from 29 February 2020 to 28 February 2025? It’s not really well defined. You might argue that it is less than 5 years, perhaps 4 years 11 months 30 days? However, Joda-Time has chosen to regard it as 5 years since both dates are at the end of the month.

答案2

得分: 1

我建议使用 java.time 以获得更精确的结果。

您可以将您的代码重构为以下形式:

fun main() {
    var javaDate1 = java.time.LocalDate.of(2025,2,28)
    var javaDate2 = java.time.LocalDate.of(2019,11,28).plusMonths(3)
    var jd = java.time.Period.between(javaDate2, javaDate1)
    println(
        "Between ${javaDate2} and ${javaDate1} are ${jd.years} years, ${jd.months} months and ${jd.days} days")

    javaDate1 = java.time.LocalDate.of(2025,2,28)
    javaDate2 = java.time.LocalDate.of(2019,11,29).plusMonths(3)
    jd = java.time.Period.between(javaDate2, javaDate1)
    println(
        "Between ${javaDate2} and ${javaDate1} are ${jd.years} years, ${jd.months} months and ${jd.days} days")

    javaDate1 = java.time.LocalDate.of(2025,2,28)
    javaDate2 = java.time.LocalDate.of(2019,11,30).plusMonths(3)
    jd = java.time.Period.between(javaDate2, javaDate1)
    println(
        "Between ${javaDate2} and ${javaDate1} are ${jd.years} years, ${jd.months} months and ${jd.days} days")
}

运行它并获得以下结果:

Between 2020-02-28 and 2025-02-28 are 5 years, 0 months and 0 days
Between 2020-02-29 and 2025-02-28 are 4 years, 11 months and 30 days
Between 2020-02-29 and 2025-02-28 are 4 years, 11 months and 30 days
英文:

I recommend the use of java.time for more accurate results.

You can refactor your code to this:

fun main() {
    var javaDate1 = java.time.LocalDate.of(2025,2,28)
    var javaDate2 = java.time.LocalDate.of(2019,11,28).plusMonths(3)
    var jd = java.time.Period.between(javaDate2, javaDate1)
    println(
        "Between ${javaDate2} and ${javaDate1} are ${jd.years} years, ${jd.months} months and ${jd.days} days")

    javaDate1 = java.time.LocalDate.of(2025,2,28)
    javaDate2 = java.time.LocalDate.of(2019,11,29).plusMonths(3)
    jd = java.time.Period.between(javaDate2, javaDate1)
    println(
        "Between ${javaDate2} and ${javaDate1} are ${jd.years} years, ${jd.months} months and ${jd.days} days")

    javaDate1 = java.time.LocalDate.of(2025,2,28)
    javaDate2 = java.time.LocalDate.of(2019,11,30).plusMonths(3)
    jd = java.time.Period.between(javaDate2, javaDate1)
    println(
        "Between ${javaDate2} and ${javaDate1} are ${jd.years} years, ${jd.months} months and ${jd.days} days")
}

run it and get the following results:

Between 2020-02-28 and 2025-02-28 are 5 years, 0 months and 0 days
Between 2020-02-29 and 2025-02-28 are 4 years, 11 months and 30 days
Between 2020-02-29 and 2025-02-28 are 4 years, 11 months and 30 days

huangapple
  • 本文由 发表于 2020年5月5日 14:17:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/61606890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定