Junaid
Junaid

Reputation: 7860

Months elapsed function not giving proper result

I have two dates: (YYYY-dd-mm)

1)1960-11-11

2)1986-04-02

I have the following function which intends to calculate the months elapsed since arbitary dates, the above two are my test conditions. This function calculates months without considering the current month. That is a month is only added once its a complete month.

The function is:

public static final int months(Date date1) {// tricky
        
        Calendar calFirst = Calendar.getInstance(); 
        calFirst.setTime(date1); 
        System.out.println(""+calFirst.getTime());
        
        
        Calendar calNow = Calendar.getInstance(); 
        calNow.setTime(getCurrentDate()); 
        System.out.println(calNow.getTime());
        
        
        int m2 = calNow.get(Calendar.YEAR) * 12 + calNow.get((Calendar.MONTH));
        System.out.println(calNow.get(Calendar.YEAR) * 12 );
        System.out.println(calNow.get(Calendar.MONTH));
        //23832
        
        int m1 = calFirst.get(Calendar.YEAR) * 12 + (calFirst.get(Calendar.MONTH));
        System.out.println(calFirst.get(Calendar.YEAR) * 12 );
        System.out.println(calFirst.get(Calendar.MONTH));
        //24168
        
        return Math.abs(m2 - (m1));
    }

Result for 1986-04-02:

Wed Apr 02 00:00:00 IST 1986
Wed Jan 08 00:00:00 IST 2014
24168
0
23832
3
333

Which is correct

Result for 1960-11-11:

Fri Nov 11 00:00:00 IST 1960
Wed Jan 08 00:00:00 IST 2014
24168
0
23520
10
638

Which is wrong.

I want to consider April in case of 1986-04-02, however the current date that is January 2014 (Month January), it should calculate only till December 2013. Tricky.

Any hints where I am going wrong?

Benchmark

Upvotes: 0

Views: 88

Answers (3)

Basil Bourque
Basil Bourque

Reputation: 339382

tl;dr

ChronoUnit.MONTHS.between ( LocalDate.parse ( "1960-11-11" ) , LocalDate.parse ( "1986-04-02" ) )

java.time

In modern Java, use the java.time classes for all your date-time work.

For a date-only value, use java.time.LocalDate class.

LocalDate first = LocalDate.parse ( "1960-11-11" ) ;
LocalDate second = LocalDate.parse ( "1986-04-02" ) ;

Calculate months elapsed as a Period.

Period period = Period.between ( first , second ) ;
long months = period.toTotalMonths() ;
if ( months > 12 ) { … handle expiration … }

Or calculate just the months elapsed using ChronoUnit.MONTHS enum object.

long months = ChronoUnit.MONTHS.between ( first , second ) ;
if ( months > 12 ) { … handle expiration … }

Upvotes: 1

Grooveek
Grooveek

Reputation: 10094

I think that 333 and 638 are both good answers...

Let me explain :

April included to December 1986 = 9 months + 27 full years + 0 months in 2014 = 333.

Same thinking applied to the other :

November included to december 1960 = 2 months + 53 full years + 0 months in 2014 = 638.

Both numbers are right from the point of view : first month included, last month excluded

Upvotes: 1

Oleg Sklyar
Oleg Sklyar

Reputation: 10082

Why not use Joda Period instead as discussed here:

Period p = new Period(from, to, PeriodType.months().withDaysRemoved());
int months = p.getMonths() + 1;

Upvotes: 1

Related Questions