Solved

Java Calendar: Calculate Number of Months

Posted on 2010-11-17
12
790 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
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 
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
 

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

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
VB Script to add site to Java Exception List 4 79
jar file executable 12 52
map related example 6 49
oracle 11g 23 84
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…
INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

831 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