0

I want to calculate the difference between 2 dates in months and days, I don't want to consider a month is 30 days and get the time in milliseconds and convert them, and I don't want to use a library such as Joda, and I also found a solution that uses LocalDate, however I am using Java 7. I looked for answers to my question but could not find any, and I tried many approaches, I tried creating a calendar and passed the time in milliseconds the difference between my 2 dates, but if I tried for example getting the difference between 15/04 and 15/5 I would get 30 days and not 1 month, below is the code

Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2013);
c.set(Calendar.MONTH, Calendar.APRIL);
c.set(Calendar.DAY_OF_MONTH, 15);

Date startDate = c.getTime();

c.set(Calendar.YEAR, 2013);
c.set(Calendar.MONTH, Calendar.MAY);
c.set(Calendar.DAY_OF_MONTH, 15);

Date lastDate = c.getTime();

Calendar diffCal = Calendar.getInstance();
diffCal.setTimeInMillis(lastDate.getTime() - startDate.getTime());

int months = ((diffCal.get(Calendar.YEAR) - 1970) * 12) + diffCal.get(Calendar.MONTH);
int days   = diffCal.get(Calendar.DAY_OF_MONTH) - 1;

System.out.println("month(s) = " + months); // month(s) = 0
System.out.println("day(s)   = " + days);   // day(s)   = 30

What can I use to get the difference in months first then in days between 2 dates?

EDIT: I wrote the below code and seems to give me what I want, could this be used

Date startDate = sdf.parse("31/05/2016");
Date endDate   = sdf.parse("1/06/2016");

Calendar startCalendar = Calendar.getInstance();
Calendar endCalendar   = Calendar.getInstance();

startCalendar.setTime(startDate);
endCalendar.setTime(endDate);

int months = 0, days = 0;

months += ((endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR)) * 12);

int startDays = startCalendar.get(Calendar.DAY_OF_MONTH);
int endDays   = endCalendar.get(Calendar.DAY_OF_MONTH);

if(endDays >= startDays) {
    months += (endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH));
    days   += (endDays - startDays);
} else {
    months += (endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH) - 1);
    days   += ((startCalendar.getActualMaximum(Calendar.DAY_OF_MONTH) - startDays) + endDays);
}

System.out.println("Difference");
System.out.println("Month(s): " + months);
System.out.println("Day(s):   " + days);
hakuna matata
  • 3,243
  • 13
  • 56
  • 93
  • You could try and use the `Joda-Time` lib which is quite useful when it comes to dates – DamCx Nov 15 '16 at 15:28
  • 3
    I know you said you checked everywhere, but the first result of my Google search delivers this post: http://stackoverflow.com/questions/20165564/calculating-days-between-two-dates-with-in-java They extract the time from Calendar to a Date object and use methods from Date to get the difference in days (check the first solution). Second solution: http://stackoverflow.com/questions/3796841/getting-the-difference-between-date-in-days-in-java – Babyburger Nov 15 '16 at 15:28
  • 1
    @DamCx He does not want to use Joda. – Babyburger Nov 15 '16 at 15:28
  • @Babyburger oops, sorry, read too quick... :( My Bad – DamCx Nov 15 '16 at 15:29
  • Keep adding 1 to the month of the earlier date until adding another month would take you past the later date, counting the number of months you added; then, keep adding 1 to the day until adding one more would take you past the later date. – Andy Turner Nov 15 '16 at 15:34
  • But these approaches will convert to days, I don't want divide them by 30 and consider a month to be 30 days, I want to get actual months passed, for example if I use dates 15 may to 15 july, I get 61 days and I don't know if to divide by 30 or 31, and want to get just 2 months – hakuna matata Nov 15 '16 at 15:38
  • Why don't you want to use Joda-Time? `Period p = new Period(startDate, endDate, PeriodType.yearMonthDay());` – Modus Tollens Nov 15 '16 at 15:52
  • @hakunamatata Your Question makes no sense. You explicitly say you do *not* define a “month” as 30 days, which leaves the only other logical definition to be the number of calendar months touched by your span of time. Yet you say 15 May to 15 July should be two months. How is that? The span touches three months, not two: May, June, and July. So how do you define “months” if (a) not 30 days, and (b) not calendar months? Move to 1st of each month & count as half-open? Please **explicitly state your business logic rules as complete sentences** rather than dropping a few arbitrary examples. – Basil Bourque Nov 15 '16 at 21:36

1 Answers1

2

You answered your own question in your research. JDK7 does not support what you want. You have three options:

  1. Write your own (do not do this because you will make many mistakes that have been made before)
  2. Use a library like Joda-Time which has been recommended many times
  3. Upgrade to JDK8 and use java.time.Period
joseph
  • 2,429
  • 1
  • 22
  • 43
  • Im trying to keep libraries to a minimum and keep using jdk 7. I wrote my own a moment ago and si far it seems to be working, could this be used, the code is in the main post – hakuna matata Nov 15 '16 at 16:25
  • 1
    This is why you should use a library or JDK8. You need to test this code for the cases you think the code will have to handle. Do you need to handle durations longer than 1 year? Do leaps need to work (every 4, 100, 400 years) (https://en.wikipedia.org/wiki/Leap_year)? – joseph Nov 15 '16 at 16:37
  • The duration will be less than 1 year for the dates I'm using, as for leap years, I tried the 'startCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)' for different years and it returns 28 or 29 based on the year, so doesn't that mean it handles leap years? – hakuna matata Nov 15 '16 at 16:44