Get difference between two dates in years - without months - without days - java

I am using the following function in Joda-Time to get difference between two dates:
public static int getDiffYear(Date first) {
int yearsBetween = Years.yearsBetween(new DateTime(first), new DateTime()).getYears();
return yearsBetween;
}
The date supplied to function is: 0001-10-02 (YYYY-MM_DD)
I get the difference as 2013 as checked against today, however I find the correct result should be 2012. Because the day still is 01.
I have a separate function in pure Java, with the desired result:
public static int getDiffYear(Date first) {
Calendar a = Calendar.getInstance();
a.setTime(first);
Calendar b = Calendar.getInstance();
int diff = b.get(Calendar.YEAR) - a.get(Calendar.YEAR);
if (a.get(Calendar.MONTH) > b.get(Calendar.MONTH) ||
(a.get(Calendar.MONTH) == b.get(Calendar.MONTH) && a.get(Calendar.DATE) > b.get(Calendar.DATE))) {
diff--;
}
return diff;
}

Joda will take days into account with yearsBetween. Try this:
public static int getDiffYear() {
LocalDate firstDate = new LocalDate(1, 10, 2);
LocalDate today = new LocalDate();
int yearsBetween = Years.yearsBetween(firstDate, today).getYears();
return yearsBetween;
}
It will return 2012 as of today (2014/10/01). This indicates something is happening in the conversion from java.util.Date.
EDIT: This is due to what Marko Topolnik mentioned. When you do new DateTime(first) you are getting a DateTime of 0001-09-30.

The Years utility class is going to only check the difference in years. If you need to keep the days into account, you should use the Days class and recalculate the result to years.

Related

Java - get number of days between dates [duplicate]

This question already has answers here:
Calculating days between two dates with Java
(16 answers)
Closed 5 years ago.
I've got a list of dates in format "yyyy-MM-dd", I'd like to have a number of days between my today date "2017-04-15" and first date from list which is higher than mine today date.
I am assuming that your events are not sorted by date. I am assuming that you can use Java 8. This is one of the tasks that have become so much easier with the java.time classes introduced in Java 8 (and backported to Java 6 and 7).
Use LocalDate.now() to get today’s date.
Iterate through your events, all the time keeping track of the closest future event date. For each event use LocalDate.parse() to convert the event’s date to a LocalDate. The 1-arg parse method fits your format. Compare with today’s date and with the earliest future event date encountered so far; if between, store as the new closest date. Use isAfter() and/or isBefore for the comparisons.
After your loop, you will either know the date or you will know that there are no future events at all. In the former case, use ChronoUnit.DAYS.between() to get the number of days from the current date to the event date.
Solution 1
If you are using joda library, then it will be easy, you can use Days.daysBetween :
Date startDate = ...;
Date endDate = ...;
int nbrDays = Days.daysBetween(new LocalDate(startDate), new LocalDate(endDate)).getDays();
Solution 2
Date startDate = ...;
Date endDate = ...;
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
int day1 = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(endDate);
int day2 = cal.get(Calendar.DAY_OF_MONTH);
int nbrDays = day1 - day2;
System.out.println(nbrDays);
You have to import :
import java.util.Calendar;
import java.util.Date;
Solution 3
If your dates are in this format "yyyy-MM-dd" so you can have two dates like this :
String date1 = "1991-07-03";
String date2 = "2017-04-15";
What you should to do, split your dates with - :
String spl1[] = date1.split("-");
String spl2[] = date2.split("-");
Calculate the difference between the two dates :
int year1 = Integer.parseInt(spl1[0]);
int month1 = Integer.parseInt(spl1[1]);
int days1 = Integer.parseInt(spl1[2]);
int year2 = Integer.parseInt(spl2[0]);
int month2 = Integer.parseInt(spl2[1]);
int days2 = Integer.parseInt(spl2[2]);
//make some calculation and in the end you can get the diffidence, this work i will let it for you.
This should solve your problem.
SimpleDateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd");
List<Date> dateList = new ArrayList<Date>();
try {
beforeDate = myDateFormat.parse("2016-01-13");
dateList.add(myDateFormat.parse("2016-01-10"));
dateList.add(myDateFormat.parse("2016-01-11"));
dateList.add(myDateFormat.parse("2016-01-12"));
dateList.add(myDateFormat.parse("2016-01-19"));
dateList.add(myDateFormat.parse("2016-01-20"));
dateList.add(myDateFormat.parse("2016-01-21"));
} catch (ParseException e) {
System.out.println(e.getMessage());
}
//add here
boolean check = true;
for(int i = 0; check && i < dateList.size();i++){
if(dateList.get(i).after(beforeDate)){
afterDate = dateList.get(i);
check = false;
}
}
System.out.println(beforeDate+" "+afterDate);
long days = ChronoUnit.DAYS.between(LocalDate.parse(myDateFormat.format(beforeDate)), LocalDate.parse(myDateFormat.format(afterDate)));
if(days>0){
System.out.println(days);
}else{
System.out.println(0-days);
}
if you want to sort dateList then want to get afterDate then use this code after addition of date elements in dateList
Collections.sort(dateList,new Comparator<Date>() {
#Override
public int compare(Date o1, Date o2) {
return o1.compareTo(o2);
}
});
This will allow you to sort dates in ascending order..

How do I figure out whether the current time is in between two times? [duplicate]

This question already has answers here:
How can I determine if a date is between two dates in Java? [duplicate]
(11 answers)
Closed 9 years ago.
I'm trying to write a schedule program in Java and I need to figure out what time it is, and whether the current time is in between two set times. Figuring out the current time is pretty simple, but do you have any suggestions for figuring out whether it is between two times of day. For example, it is 9:33 AM on a Thursday. So I would need to figure out which scheduled section of the week that time corresponds to. How would I go about comparing the time to set periods during the week, for example an Array of sectioned times during a week such as {Monday from 9-10 AM, Tuesday from 3-4 PM, Thursday from 8-11 AM}, and seeing which section of time the current time falls between?
An efficient way to find which period any date lies within would be to have a class;
public class TimePeriod implements Comparable<TimePeriod>{
Date start;
Date end;
//Constructor, getters, setters
boolean isIn(Date date) {
return date.after(start) && date.before(end);
}
public int compareTo(TimePeriod other) {
return start.compareTo(other.start);
}
}
..and then create a sorted list of TimePeriod where you can perform a binary search.
edit:
This might make the binary search easier;
int check(Date date) {
if (isIn(date)) {
return 0;
} else if (start.after(date)) {
return -1;
} else if (end.before(date)) {
return 1;
} else {
throw new IllegalStateException("Time has gone badly wrong");
}
}
If you're using Date Class, you could do it like this
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
Date before = sdf.parse("07/05/2012 08:00");
Date after = sdf.parse("07/05/2012 08:30");
Date toCheck = sdf.parse("07/05/2012 08:15");
//is toCheck between the two?
boolean isAvailable = (before.getTime() < toCheck.getTime()) && after.getTime() > toCheck.getTime();
EDITED
As suggested by Jonathan Drapeau you could also use compareTo.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
Date before = sdf.parse("07/05/2012 08:00");
Date after = sdf.parse("07/05/2012 08:30");
Date toCheck = sdf.parse("07/05/2012 08:15");
//is toCheck between the two?
if you want to include the "initial" and "final" date range
boolean isAvailable = before.compareTo(toCheck) >= 0 && after.compareTo(toCheck) <= 0
if you want to exclude the "initial" and "final" date range
boolean isAvailable = before.compareTo(toCheck) > 0 && after.compareTo(toCheck) < 0
You could use it too on Calendar class.
Anyway, i highly recommend you to use Calendar. It's a way precise class
you could check it like this:
Calendar cal1 = Calendar.getInstance(); // for example 12:00:00
Calendar cal2 = Calendar.getInstance(); // for exmaple 12:30:00
Calendar userTime = Calendar.getInstance(); // time to test: 12:15:00
if(user.after(cal1)&& user.before(cal2)){
//...
}
And to initialize and set times to Calendar, check this:
http://www.tutorialspoint.com/java/util/calendar_settime.htm
I would suggest using the Epoch time.
For a definition of Epoch time: http://en.wikipedia.org/wiki/Epoch_time
Basically, its a number of seconds after a specific date, i believe in 1989. If you translate the 3 times (the current time and the 2 times to compare to) in epoch time you can just use > < = etc.
For information on getting epoch time, Try here (has many languages): http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
Unfortunately, my java is lacking or I'd give you some code :)
Edit:
Java epoch time code:
long epoch = System.currentTimeMillis()/1000;
Because my Java is bad and I don't have an interpreter where I am, I can only suggest using this site to help convert the other dates to epoch time: http://www.epochconverter.com/
There is before(Date) and after(Date) method in Date Class.
secondDate.before(firstDate)
If you use Calendar class, it has explicit before() and after() methods:
Calendar startDate = ...
Calendar endData = ...
isBetween = currentDate.after(startDate) && currentDate.before(endDate);

How to write a method that returns number (int) of days from provided day to the todays date?

Please help me to write a method that returns number (int) of days from a provided day to the todays date.
So let's say, I am providing into a method an int 110515 (for May 15, 2011). It should return 9 (inclusive or exclusive is not important to me).
If you can use Joda, this is super simple:
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
Of course you could combine these.
int days = Days.daysBetween(startDate, endDate).getDays();
Joda objects can go back and forth between the JDK's date class pretty easily.
For the first part, make a DateFormatter then parse the string based on it, like this:
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");
DateTime dt = fmt.parseDateTime(strInputDateTime);
(After turning the int into a string of course.)
Should dates in the future include the current day? Meaning if today is May 24th 2011, should 110529 result in 4 or 5?
public static long numberOfDays(final long date) throws ParseException {
final Calendar compare = Calendar.getInstance();
compare.setTime(new SimpleDateFormat("yyMMdd").parse(String.valueOf(date)));
final int dstOffset = compare.get(Calendar.DST_OFFSET);
final long currentTimeMillis = System.currentTimeMillis();
final long compareTimeInMillis = compare.getTimeInMillis();
long difference = 0;
if (currentTimeMillis >= compareTimeInMillis) {
difference = currentTimeMillis - compareTimeInMillis - dstOffset;
} else {
difference = compareTimeInMillis - currentTimeMillis + dstOffset;
}
return difference / (24 * 60 * 60 * 1000);
}
Since this seems like a homework question I will help you out. You will want to use Calendar.getTimeInMillis. Then you will want to create a constant that is NUMBER_OF_MILLIS_IN_DAY . From there you subtract the initialDate from the currentDate (both time in millis) and divide by the constant.

How can I calculate the age at death? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
How can I calculate the age of a person in year, month, days?
How can I calculate the difference between two dates
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
if(petDetails.getDateOfDeath() != null){
String formatedDateOfDeath = formatter.format(petDetails.getDateOfDeath());
String formateDateOfBirth = formatter.format(petDetails.getDateOfBirth());
}
How can i calculate the age of death from the above. I dont want to use any externallibraries
EDIT: please look at what I've got so far.none of the other threads are like mine. most of them are about date from DOB to today and not in the format im using.
Try this:
public class Age {
public static void main(String[] args) {
Calendar birthDate = new GregorianCalendar(1979, 1, 1);
Calendar deathDate = new GregorianCalendar(2011, 1, 1);
int age = deathDate.get(Calendar.YEAR) - birthDate.get(Calendar.YEAR);
if ((birthDate.get(Calendar.MONTH) > deathDate.get(Calendar.MONTH))
|| (birthDate.get(Calendar.MONTH) == deathDate.get(Calendar.MONTH) && birthDate.get(Calendar.DAY_OF_MONTH) > deathDate
.get(Calendar.DAY_OF_MONTH))) {
age--;
}
System.out.println(age);
}
}
You can solve this without converting them to strings.
since the getDateOfBirth and getDateOfDeath return date objects, you can use the .getTime() method on them which Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
A fairly simple way of doing this could be
long millisecondsDiff = petDetails.getDateOfDeath().getTime - petDetails.getDateOfBirth().getTime;
You can then either create a new date object directly from this long, or you can do the proper calculations to change milliseconds into days. ie
long age = millisecondsDiff / (1000 * 60* 60 * 24);

Java Date month difference

I have start date and end date.
I need the number of months between this two dates in Java.
For example
From date: 2009-01-29
To date: 2009-02-02
It has one jan date and one Feb date.
It should return 2.
As the rest say, if there's a library that will give you time differences in months, and you can use it, then you might as well.
Otherwise, if y1 and m1 are the year and month of the first date, and y2 and m2 are the year and month of the second, then the value you want is:
(y2 - y1) * 12 + (m2 - m1) + 1;
Note that the middle term, (m2 - m1), might be negative even though the second date is after the first one, but that's fine.
It doesn't matter whether months are taken with January=0 or January=1, and it doesn't matter whether years are AD, years since 1900, or whatever, as long as both dates are using the same basis. So for example don't mix AD and BC dates, since there wasn't a year 0 and hence BC is offset by 1 from AD.
You'd get y1 etc. either from the dates directly if they're supplied to you in a suitable form, or using a Calendar.
Apart from using Joda time which seems to be the the favorite suggestion I'd offer the following snippet:
public static final int getMonthsDifference(Date date1, Date date2) {
int m1 = date1.getYear() * 12 + date1.getMonth();
int m2 = date2.getYear() * 12 + date2.getMonth();
return m2 - m1 + 1;
}
EDIT: Since Java 8, there is a more standard way of calculating same difference. See my alternative answer using JSR-310 api instead.
I would strongly recommend Joda-Time (and as of Java 8, the Java Time apis) for this.
It makes this sort of work very easy (check out Periods)
It doesn't suffer from the threading issues plaguing the current date/time objects (I'm thinking of formatters, particularly)
It's the basis of the new Java date/time APIs to come with Java 7 (so you're learning something that will become standard)
Note also Nick Holt's comments below re. daylight savings changes.
Now that JSR-310 has been included in the SDK of Java 8 and above, here's a more standard way of getting months difference of two date values:
public static final long getMonthsDifference(Date date1, Date date2) {
YearMonth m1 = YearMonth.from(date1.toInstant().atZone(ZoneOffset.UTC));
YearMonth m2 = YearMonth.from(date2.toInstant().atZone(ZoneOffset.UTC));
return m1.until(m2, ChronoUnit.MONTHS) + 1;
}
This has a benefit of clearly spelling out the precision of the calculation and it is very easy to understand what is the intent of the calculation.
Java 8 solution:
#Test
public void monthBetween() {
LocalDate d1 = LocalDate.of(2013, Month.APRIL, 1);
LocalDate d2 = LocalDate.of(2014, Month.APRIL, 1);
long monthBetween = ChronoUnit.MONTHS.between(d1, d2);
assertEquals(12, monthBetween);
}
Based on the above suggested answers I rolled my own which I added to my existing DateUtils class:
public static Integer differenceInMonths(Date beginningDate, Date endingDate) {
if (beginningDate == null || endingDate == null) {
return 0;
}
Calendar cal1 = new GregorianCalendar();
cal1.setTime(beginningDate);
Calendar cal2 = new GregorianCalendar();
cal2.setTime(endingDate);
return differenceInMonths(cal1, cal2);
}
private static Integer differenceInMonths(Calendar beginningDate, Calendar endingDate) {
if (beginningDate == null || endingDate == null) {
return 0;
}
int m1 = beginningDate.get(Calendar.YEAR) * 12 + beginningDate.get(Calendar.MONTH);
int m2 = endingDate.get(Calendar.YEAR) * 12 + endingDate.get(Calendar.MONTH);
return m2 - m1;
}
And the associatiated unit tests:
public void testDifferenceInMonths() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
assertEquals(12, DateUtils.differenceInMonths(sdf.parse("2014/03/22"), sdf.parse("2015/03/22")).intValue());
assertEquals(11, DateUtils.differenceInMonths(sdf.parse("2014/01/01"), sdf.parse("2014/12/25")).intValue());
assertEquals(88, DateUtils.differenceInMonths(sdf.parse("2014/03/22"), sdf.parse("2021/07/05")).intValue());
assertEquals(6, DateUtils.differenceInMonths(sdf.parse("2014/01/22"), sdf.parse("2014/07/22")).intValue());
}
using joda time would be like this (i compared how many months between today and 20/dec/2012)
import org.joda.time.DateTime ;
import org.joda.time.Months;
DateTime x = new DateTime().withDate(2009,12,20); // doomsday lol
Months d = Months.monthsBetween( new DateTime(), x);
int monthsDiff = d.getMonths();
Result: 41 months (from july 6th 2009)
should be easy ? :)
ps: you can also convert your date using SimpleDateFormat
like:
Date x = new SimpleDateFormat("dd/mm/yyyy").parse("20/12/2009");
DateTime z = new DateTime(x);
If you don't want to use Joda (for whatever reason), you can convert your date to TimeStamp and then do the differences of milli seconds between both date and then calculate back to months. But I still prefer to use Joda time for the simplicity :)
tl;dr
ChronoUnit.MONTHS.between(
YearMonth.from( LocalDate.of( 2009 , 1 , 29 ) ) ,
YearMonth.from( LocalDate.of( 2009 , 2 , 2 ) )
)
Time Zone
The Answer by Roland Tepp is close but ignores the crucial issue of time zone. Determining a month and date requires a time zone, as for any given moment the date varies around the globe by zone.
ZonedDateTime
So his example of converting java.util.Date objects to java.time.Instant objects implicitly uses UTC. Values in either of those classes is always in UTC by definition. So you need to adjust those objects into the desired/intended time zone to be able to extract a meaningful date.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtStart = myJavaUtilDate1.toInstant().atZone( z );
ZonedDateTime zdtStop = myJavaUtilDate2.toInstant().atZone( z );
YearMonth
Since you want to know how many calendar months were touched by your date range rather than the number of 30-day chunks elapsed, convert to YearMonth objects.
YearMonth start = YearMonth.from( zdtStart );
YearMonth stop = YearMonth.from( zdtStop );
ChronoUnit
Calculate months between by calling on ChronoUnit enum.
long monthsBetween = ChronoUnit.MONTHS.between( start , stop );
1
Half-Open
You desired a result of 2 but we get 1 here. The reason is that in date-time work the best practice is to define spans of time by the Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive. I suggest you stick to this definition throughout your date-time work as doing so ultimately makes sense, eliminates confusing ambiguities, and makes your work easier to parse mentally and less error-prone. But if you insist on your definition, simply add 1 to the result assuming you have positive numbered results (meaning your spans of time go forward in time rather than backward).
LocalDate
The original Question is not clear but may require date-only values rather than date-time values. If so, use the LocalDate class. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate start = LocalDate.of( 2009 , 1 , 29 ) ;
LocalDate stop = LocalDate.of( 2009 , 2 , 2 ) ;
long monthsBetween = ChronoUnit.MONTHS.between( start , stop );
1
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Joda Time is a pretty cool library for Java Date and Time and can help you achieve what you want using Periods.
You can use a Calendar or Joda time library for this.
In Joda time you can use the Days.daysBetween() method. You can then calculate the months difference. You can also use DateTime.getMonthOfYear() and do a subtraction (for dates in the same year).
It depends on your definition of a month, but this is what we use:
int iMonths = 0;
Calendar cal1 = GregorianCalendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = GregorianCalendar.getInstance();
cal2.setTime(date2);
while (cal1.after(cal2)){
cal2.add(Calendar.MONTH, 1);
iMonths++;
}
if (cal2.get(Calendar.DAY_OF_MONTH) > cal1.get(Calendar.DAY_OF_MONTH)){
iMonths--;
}
return iMonths;
I had to write this implementation, becoz I had custom defined periods, which i had to look for within two dates.
Here you can define you custom period and put the logic, for calculation.
Here TimePeriod is a POJO which has start, end, period start, period End
public class Monthly extends Period {
public int getPeriodCount(String startDate, String endDate, int scalar) {
int cnt = getPeriods(startDate, endDate, scalar).size();
return cnt;
}
public List getPeriods(String startDate, String endDate, int scalar) {
ArrayList list = new ArrayList();
Calendar startCal = CalendarUtil.getCalendar(startDate);
Calendar endCal = CalendarUtil.getCalendar(endDate);
while (startCal.compareTo(endCal) <= 0) {
TimePeriod period = new TimePeriod();
period.setStartDate(startCal.getTime());
period.setPeriodStartDate(getPeriodStartDate((Calendar) startCal.clone()).getTime());
Calendar periodEndCal = getPeriodEndDate((Calendar) startCal.clone(), scalar);
period.setEndDate(endCal.before(periodEndCal) ? endCal.getTime() : periodEndCal.getTime());
period.setPeriodEndDate(periodEndCal.getTime());
periodEndCal.add(Calendar.DATE, 1);
startCal = periodEndCal;
list.add(period);
}
return list;
}
private Calendar getPeriodStartDate(Calendar cal) {
cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE));
return cal;
}
private Calendar getPeriodEndDate(Calendar cal, int scalar) {
while (scalar-- > 0) {
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
if (scalar > 0)
cal.add(Calendar.DATE, 1);
}
return cal;
}
}
it is not the best anwer but you can use unixtimestamp
First you find the unixtime's of the dates
then eject each other
Finally you should convert the unixtime(sum) to String
That's because the classes Java Date and Calendar use the Month indices from 0-11
January = 0
December = 1
Is recommended to use Joda Time!
Here's a solution using java.util.Calendar object:
private static Integer getMonthsBetweenDates(Date d1, Date d2) {
Calendar todayDate = getCalendar(d1);
Calendar pastDate = getCalendar(d2);
int yearDiff = todayDate.get(Calendar.YEAR) - pastDate.get(Calendar.YEAR);
if (pastDate.get(Calendar.MONTH) < 11 && pastDate.get(Calendar.DAY_OF_MONTH) < 31){ //if pastDate is smaller than 31/12
yearDiff++;
}
int monthCount = 0;
for (int year = 0 ; year < yearDiff ; year++){
if (year == 0) {
monthCount += 12 - pastDate.get(Calendar.MONTH);
} else if (year == yearDiff - 1){ //last year
if (todayDate.get(Calendar.MONTH) < pastDate.get(Calendar.MONTH)){
monthCount += todayDate.get(Calendar.MONTH) + 1;
} else if (todayDate.get(Calendar.MONTH) >= pastDate.get(Calendar.MONTH) && todayDate.get(Calendar.DAY_OF_MONTH) < pastDate.get(Calendar.DAY_OF_MONTH)){
monthCount += todayDate.get(Calendar.MONTH);
} else if (todayDate.get(Calendar.MONTH) >= pastDate.get(Calendar.MONTH) && todayDate.get(Calendar.DAY_OF_MONTH) >= pastDate.get(Calendar.DAY_OF_MONTH)){
monthCount += todayDate.get(Calendar.MONTH) + 1;
}
}
for (int months = 0 ; months < 12 ; months++){
if (year > 0 && year < yearDiff -1){
monthCount++;
}
}
}
return monthCount;
}
Why not calculate with full timedate
public static Integer calculateMonthDiff(Date begining, Date end) throws Exception {
if (begining.compareTo(end) > 0) {
throw new Exception("Beginning date is greater than the ending date");
}
if (begining.compareTo(end) == 0) {
return 0;
}
Calendar cEndCheckDate = Calendar.getInstance();
cEndCheckDate.setTime(begining);
int add = 0;
while (true) {
cEndCheckDate.add(Calendar.MONTH, 1);
add++;
if (cEndCheckDate.getTime().compareTo(end) > 0) {
return add - 1;
}
}
}
A full code snippet for finding the difference of months between two date is as follows:
public String getContractMonth(String contractStart, String contractEnd) {
SimpleDateFormat dfDate = new SimpleDateFormat("yyyy-MM-dd");
String months = "0";
try {
Date startDate = dfDate.parse(contractStart);
Date endDate = dfDate.parse(contractEnd);
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(startDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
int diffYear = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
int diffMonth = diffYear * 12 + endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
months = diffMonth + "";
} catch (ParseException e) {
e.printStackTrace();
} catch (java.text.ParseException e) {
e.printStackTrace();
}
return months;
}
below logic will fetch you difference in months
(endCal.get(Calendar.YEAR)*12+endCal.get(Calendar.MONTH))-(startCal.get(Calendar.YEAR)*12+startCal.get(Calendar.MONTH))
you can by 30 days or by months :
public static void main(String[] args) throws IOException {
int n = getNumbertOfMonth(LocalDate.parse("2016-08-31"),LocalDate.parse("2016-11-30"));
System.out.println("number of month = "+n);
n = getNumbertOfDays(LocalDate.parse("2016-08-31"),LocalDate.parse("2016-11-30"));
System.out.println("number of days = "+n);
System.out.println("number of 30 days = "+n/30);
}
static int getNumbertOfMonth(LocalDate dateDebut, LocalDate dateFin) {
LocalDate start = dateDebut;
LocalDate end = dateFin;
int count = 0 ;
List<String> lTotalDates = new ArrayList<>();
while (!start.isAfter(end)) {
count++;
start = start.plusMonths(1);
}
return count;
}
static int getNumbertOfDays(LocalDate dateDebut, LocalDate dateFin) {
LocalDate start = dateDebut;
LocalDate end = dateFin;
int count = 0 ;
List<String> lTotalDates = new ArrayList<>();
while (!start.isAfter(end)) {
count++;
start = start.plusDays(1);
}
return count;
}
long monthsBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2016-01-29").minusMonths(1),
LocalDate.parse("2016-02-02").plusMonths(1));
2016-01-29 to 2016-01-02 = months 1
2016-02-29 to 2016-02-02 = months 1
2016-03-29 to 2016-05-02 = months 5
Here a complete implementation for monthDiff in java without iterations. It returns the number of full month between two dates. If you want to include the number of incomplete month in the result (as in the initial question), you have to zero out the day, hours, minutes, seconds and millisecondes of the two dates before calling the method, or you could change the method to not compare days, hours, minutes etc.
import java.util.Date;
import java.util.Calendar;
...
public static int monthDiff(Date d1, Date d2) {
int monthDiff;
Calendar c1, c2;
int M1, M2, y1, y2, t1, t2, h1, h2, m1, m2, s1, s2, ms1, ms2;
c1 = Calendar.getInstance();
c1.setTime(d1);
c2 = Calendar.getInstance();
c2.setTime(d2);
M1 = c1.get(Calendar.MONTH);
M2 = c2.get(Calendar.MONTH);
y1 = c1.get(Calendar.YEAR);
y2 = c2.get(Calendar.YEAR);
t1 = c1.get(Calendar.DAY_OF_MONTH);
t2 = c2.get(Calendar.DAY_OF_MONTH);
if(M2 < M1) {
M2 += 12;
y2--;
}
monthDiff = 12*(y2 - y1) + M2 - M1;
if(t2 < t1)
monthDiff --; // not a full month
else if(t2 == t1) { // perhaps a full month, we have to look into the details
h1 = c1.get(Calendar.HOUR_OF_DAY);
h2 = c2.get(Calendar.HOUR_OF_DAY);
if(h2 < h1)
monthDiff--; // not a full month
else if(h2 == h1) { // go deeper
m1 = c1.get(Calendar.MINUTE);
m2 = c2.get(Calendar.MINUTE);
if(m2 < m1) // not a full month
monthDiff--;
else if(m2 == m1) { // look deeper
s1 = c1.get(Calendar.SECOND);
s2 = c2.get(Calendar.SECOND);
if(s2 < s1)
monthDiff--; // on enleve l'age de mon hamster
else if(s2 == s1) {
ms1 = c1.get(Calendar.MILLISECOND);
ms2 = c2.get(Calendar.MILLISECOND);
if(ms2 < ms1)
monthDiff--;
// else // it's a full month yeah
}
}
}
}
return monthDiff;
}
So many answers with long code when you can just do it with 1 line and some math:
LocalDate from = yourdate;
LocalDate to = yourotherdate;
int difference = to.getMonthValue() - from.getMonthValue()) + ((to.getYear() - from.getYear()) * 12) + 1;

Categories