Solved

Java Calendar: Calculate Number of Months

Posted on 2010-11-17
12
782 Views
Last Modified: 2012-06-22
Hello Experts:

I'm trying to accurately calculate the number of months between two dates and I"m running into a tricky situation:

Let's say I have two dates:
start: 11/01/2010
end: 12/02/2010

I converted these dates strings into a Date object.  Now, I'm using the GregorianCalendar to calculate the number of months like so:

int months = ((end.get(Calendar.YEAR) - start.get(Calendar.YEAR)) *  end.getMaximum(Calendar.MONTH) ) + end.get(Calendar.MONTH) - start.get(Calendar.MONTH);

This gives me the correct number of months, which is 1.

But if I change the dates like so:
start: 11/15/2010
end: 12/01/2010

I still get the number of months as 1, when really it should be 0.

Can anyone suggest a different and accurate way to calculate the number of months between two dates?  

Thank you!
0
Comment
Question by:Greengiants15
  • 4
  • 3
  • 2
  • +2
12 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 34155837
Define 'month' please so that we help accurately
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 34155862
try this,

int noOfMonth = TimeUnit.MONTH.convert( date1.getTime() - date2.getTime(), TimeUnit.MILLISECONDS ) ;
0
 

Author Comment

by:Greengiants15
ID: 34155887
Month would be the total number of months.

For example:
10/15/2010
to
12/15/2011

The number of months 14.

but
10/25/2010
to
12/15/2011
would be 13 months
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34155927
>>TimeUnit.MONTH

Which version of Java has the above?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34155939
>>Month would be the total number of months.

That's circular, so can't be used as the definition of month
0
 
LVL 51

Assisted Solution

by:HainKurt
HainKurt earned 100 total points
ID: 34155949
add a condition after you get the month:

if (day2<day1) {month = month - 1}
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:Greengiants15
ID: 34156120
I'm running java 1.4.  TimeUnit is only good with 1.5
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34156152
>>TimeUnit is only good with 1.5

That's academic. afaics TimeUnit.MONTH doesn't exist
0
 
LVL 16

Accepted Solution

by:
HackneyCab earned 400 total points
ID: 34156401
I was bored, so I put this together. It satisfies all of your example dates and results, but you probably want to improve the error checking (such as better checking that the end date is actually later than the start date). Oh, and you'll need to change the exception handling, because my instant response to exceptions is to terminate the JVM.

public static int wholeMonthsPassed(String startDate, String endDate) {
	DateFormat df = new SimpleDateFormat("y/M/d");
	GregorianCalendar start = new GregorianCalendar();
	GregorianCalendar end = new GregorianCalendar();
	try {
		start.setTime(df.parse(startDate));
		end.setTime(df.parse(endDate));
	} catch (ParseException pe) {
		System.out.println("Failed to parse one or both date strings!");
		System.exit(1);
	}
	int startYear, startMonth, startDay;
	int endYear, endMonth, endDay;
	startYear = start.get(Calendar.YEAR);
	startMonth = start.get(Calendar.MONTH);
	startDay = start.get(Calendar.DAY_OF_MONTH);

	endYear = end.get(Calendar.YEAR);
	endMonth = end.get(Calendar.MONTH);
	endDay = end.get(Calendar.DAY_OF_MONTH);

	int yearsInMonths = 12 * (endYear - startYear);

	endMonth += yearsInMonths;

	int monthsPassed = endMonth - startMonth;

	if(endDay < startDay) {
		--monthsPassed;
	}

	if(monthsPassed < 0) {
		System.out.println("Cannot have end year earlier than start year!");
		System.exit(1);
	}

	return monthsPassed;
}

public static void main(String[] args) {
	String start = "2010/10/25";
	String end =   "2011/12/15";

	System.out.println("Result: "+wholeMonthsPassed(start, end));
}

Open in new window

0
 

Author Comment

by:Greengiants15
ID: 34156443
HainKurt: I like your suggestion.  That works but then it brings up another problem.

If the date is the following:
start: 10/5/2010
end: 11/1/2010

The number of months comes out as 0 (using your calculations) but if I try to calculate the number of days (start.get(Calendar.DAY_OF_MONTH) - end.get(Calendar.DAY_OF_MONTH))
I get 4 when I should get 27.
0
 
LVL 16

Expert Comment

by:HackneyCab
ID: 34156508
Oh, I should point out that my code is currently configured to parse dates in the most sensible format: year/month/date so if you must use the (very confusing) US format month/date/year, you'll need to change the call to SimpleDateFormat from ("y/M/d") to ("M/d/y").
0
 
LVL 51

Expert Comment

by:HainKurt
ID: 34156543
you get 4 (5-1 = 4)

if (start.get(Calendar.DAY_OF_MONTH) > end.get(Calendar.DAY_OF_MONTH)) {month = month - 1};

it does not calculate how many days between two dates, just checks the day number...
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
bitbucket vs gitbucket 3 55
VB Script to add site to Java Exception List 4 48
servlet filter example 37 34
arguments to jar 5 7
For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now