joda Period returns 0 months

I have 2 joda.DateTimes, which I use to create a Duration. The Duration is then converted to a Period, and although the two dates are 3 years apart, the Period.getDays, Period.getMonths, and Period.getYears all return 0. why?

Example from the Scala REPL, but should be easy to understand/convert to Java (I can convert if needed)

import org.joda.time.format.PeriodFormat
import org.joda.time.{DateTime, Period}
import org.joda.time.Duration
import org.joda.time.format.PeriodFormatterBuilder

scala> val start = DateTime.now
start: org.joda.time.DateTime = 2017-02-22T16:09:13.131Z

scala>     val end = start.plusYears(2).plusMinutes(1).plusDays(3)
end: org.joda.time.DateTime = 2019-02-25T16:10:13.131Z

scala>     val duration = new Duration(start, end)
duration: org.joda.time.Duration = PT63331260S

scala>     duration.getMillis
res0: Long = 63331260000

scala>     duration.getStandardDays
res1: Long = 733

scala>     duration.getStandardHours
res2: Long = 17592

scala>     duration.getStandardMinutes
res3: Long = 1055521

scala>     duration.getStandardSeconds
res4: Long = 63331260

scala>     val period = duration.toPeriod()
period: org.joda.time.Period = PT17592H1M

scala>     period.getDays
res5: Int = 0

scala>     period.getHours
res6: Int = 17592

scala>     period.getMinutes
res7: Int = 1

scala>     period.getSeconds
res8: Int = 0

scala>     period.getMillis
res9: Int = 0

scala> val formatter = new PeriodFormatterBuilder()
            .appendMonths().appendSuffix(" month", " months").appendSeparator(" ")
            .appendDays().appendSuffix(" day", " days").appendSeparator(" ")
            .appendHours().appendSuffix("h")
            .appendMinutes().appendSuffix("m")
            .appendSeconds().appendSuffix("s")
            .toFormatter
formatter: org.joda.time.format.PeriodFormatter = org.joda.time.format.PeriodFormatter@3096d00d

scala>     formatter.print(duration.toPeriod())
res10: String = 17592h1m

scala> PeriodFormat.getDefault.print(duration.toPeriod)
res11: String = 17592 hours and 1 minute
Jon Skeet
people
quotationmark

You're calling AbstractDuration.toPeriod:

Converts this duration to a Period instance using the standard period type and the ISO chronology.

Only precise fields in the period type will be used. Thus, only the hour, minute, second and millisecond fields on the period will be used. The year, month, week and day fields will not be populated.

A Duration doesn't "know" its start and end points, so you can't expect variable-length values like months to be populated.

To get the period between start and end, you should just use:

new Period(start, end)

... possibly with a PeriodType to say which units you want.

people

See more on this question at Stackoverflow