Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joda Time - difference in months between two dates [duplicate]

Tags:

java

jodatime

I need to get the difference in months between two dates, I'm using Joda Time, the problem is this:

DateTime date1 = new DateTime().withDate(2015, 2, 1);
DateTime date2 = new DateTime().withDate(2015, 1, 1);
Months m = Months.monthsBetween(date1, date2);
int monthDif = m.getMonths();//this return 0 

it returns 0 because there is no month in the middle of the two dates, I need to return the difference in months not a few months in between, and add 1 would be problematic when the dates are the same.

like image 857
Carlos Lopez Avatar asked Jan 13 '16 17:01

Carlos Lopez


People also ask

How do I get days between two dates in Joda-Time?

How do I get number of days between two dates in Joda-Time? The following code snippet show you how to get days between two dates. You can use the Days.daysBetween () method and pass the dates you want to calculate. This method return a Days object.

How to get the number of days in days in Joda?

This method return a Days object. To get the number in days you call the getDays () method. package org.kodejava.joda; import org.joda.time.DateMidnight; import org.joda.time.Days; import org.joda.time.LocalDate; public class DaysBetweenDemo { public static void main(String [] args) { // Define the start and end dates.

How to create a date without time in Joda?

It creates DateTime instance of current moment and then changes it (leaving time fields as is). If you want to create just new specific date without time then just use LocalDate and then Months.monthsBetween (date1, date2) will work fine. Changing the first date to 2015-02-02, Joda correctly returns 1 month:

How to change the first date to 2015-02-02 in Joda?

Changing the first date to 2015-02-02, Joda correctly returns 1 month: DateTime date1 = new DateTime ().withDate (2015, 2, 2); DateTime date2 = new DateTime ().withDate (2015, 1, 1); System.out.println (Months.monthsBetween (date2, date1).getMonths ()); // Returns 1.


2 Answers

Changing the first date to 2015-02-02, Joda correctly returns 1 month:

DateTime date1 = new DateTime().withDate(2015, 2, 2);
DateTime date2 = new DateTime().withDate(2015, 1, 1);

System.out.println(Months.monthsBetween(date2, date1).getMonths());
// Returns 1.

So my guess is that because you didn't provide a time portion, Joda cannot be precise about exactly which point in time of 2015-01-01 date2 refers to. You might have as well referred to 23:59:59, in which case a full month wouldn't have elapsed yet, technically.

If you provide a zero time portion explicitly, it works as you initially expected:

DateTime date1 = new DateTime().withDate(2015, 2, 1).withTime(0, 0, 0, 0);
DateTime date2 = new DateTime().withDate(2015, 1, 1).withTime(0, 0, 0, 0);

System.out.println(Months.monthsBetween(date2, date1).getMonths());
// Returns 1.

Therefore, I recommend you specify a 00:00:00 time portion in each date explicitly.

like image 170
raulk Avatar answered Oct 22 '22 04:10

raulk


While other answers are correct they still mask the real problem.

it returns 0 because there is no month in the middle of the two dates

No. It returns 0 because there is time part of DateTime object. You creating two istances of DateTime filled with current moment in time (with hours, minutes, seconds and milliseconds) and then modify just date part. There is no reasons to do it if you want to compare just two dates. use LocalDate instead.

LocalDate date1 = new LocalDate(2015, 2, 1);
LocalDate date2 = new LocalDate(2015, 1, 1);
Months m = Months.monthsBetween(date1, date2);
int monthDif = Math.abs(m.getMonths());//this return 1

Also need to pay attention to the fact that despite the fact that Months docs say nothing about it, Month can contain negative value if first date is after second date. So we need to use Math.abs to really count the number of months between two dates.

The docs say:

Creates a Months representing the number of whole months between the two specified partial datetimes.

But it isn't true. It really calculates the difference in months. Not the number of months.

like image 34
Ruslan Stelmachenko Avatar answered Oct 22 '22 03:10

Ruslan Stelmachenko