-4

Query regarding calculate months but with some conditions. with Joda Date-time or date util.

Start Date : 01/01/2018
End Date : 31/12/2020

Total Period difference between above date: 36 months and 0 days so total month =36

Start Date : 01/01/2018
End Date : 02/01/2021

Total Period difference between above date: 36 months and 2 days. if there are days remaining then it consider single month. so total month 36+1= 37

 Date issueDate1=03/06/2017;  
     Date dateTo1=02/06/2020;


int investmentPeriod = Months.monthsBetween(issueDate1, dateTo1).getMonths();

By joda above months are coming 35 which is wrong.

Date start=23/06/2017;
Date end=06/07/2017;

here difference less than a month . so it consider as single month.

Bachas
  • 233
  • 6
  • 16
  • What your question exactly ? – Prashant Gupta Aug 24 '18 at 07:07
  • 1
    Possible duplicate of [Java Date month difference](https://stackoverflow.com/questions/1086396/java-date-month-difference) – Nicholas K Aug 24 '18 at 07:08
  • if days>0 months++ ? I think it took more to write that post than actually resolve it. – Antoniossss Aug 24 '18 at 07:09
  • Any reason not to use java.time, the modern Java date and time API? It may be considered the successor of Joda-Time. In any case it’s much nicer to work with than `java.util.Date` and friends; I consider those long outdated. And I consider java.time the future-proof API. – Ole V.V. Aug 24 '18 at 07:22
  • Whichever library you use (with the possible exception of [Time4J](http://time4j.net)) will calculate the length of time from the first date, inclusive, to the last, exclusive. Since you want to include both, you need to add one day before calculating the difference. Or maybe it will work for you to do as you already do and then just always add 1 month? – Ole V.V. Aug 24 '18 at 07:25
  • @Ole V.V. i can use any of the use java.time. I am using both Joda and java.time – Bachas Aug 24 '18 at 07:38
  • no body giving ans just giving negative points. don't understand. – Bachas Aug 24 '18 at 07:52
  • @Ole V.V. this is not true for the ChronoUnit of the java.time package. It only takes the months in consideration – Thomas W. Aug 24 '18 at 08:03
  • I didn’t downvote. Many here expect a greater effort from an asker than what you are showing: search and research before asking, and a [MCVE](https://stackoverflow.com/help/mcve). – Ole V.V. Aug 24 '18 at 08:03
  • What should be the result from 31/03/2018 to 30/04/2018? – Ole V.V. Aug 24 '18 at 08:06
  • @ThomasW. I didn’t get your point, sorry? Of course `ChronoUnit.MONTHS.between` will calculate the months (only) from the first date, inclusive, to the last, exclusive (and truncates to whole months). Similarly `ChronoUnit.DAYS.between` will calculate the days from the first date, inclusive, to the last, exclusive. – Ole V.V. Aug 24 '18 at 08:09
  • @ Ole V.V. for 31/03/2018 to 30/04/2018 there is 1 month and 1 days coming. so return should be 2 month. If the dates are 31/03/2018 to 25/04/2018 .these are less than a month. here return month will be 1. – Bachas Aug 24 '18 at 08:09
  • @Bachas is Java 8 an option? – Thomas W. Aug 24 '18 at 08:44
  • @Thomas W. yes there is an option of java 8.I got the correct ans. – Bachas Aug 24 '18 at 08:52

2 Answers2

1
 ZoneId defaultZoneId = ZoneId.systemDefault();
           String issueDate1="01/01/2017";  
            Date issueDate2=new SimpleDateFormat("dd/MM/yyyy").parse(issueDate1);
            String dateTo1="31/12/2018";  
            Date dateTo2=new SimpleDateFormat("dd/MM/yyyy").parse(dateTo1);

here year month days can find easily.This giving ans of all question.

            Instant instant = issueDate2.toInstant();
            LocalDate localDatestart = instant.atZone(defaultZoneId).toLocalDate();

            Instant instant1 = dateTo2.toInstant();
            LocalDate localDateend = instant1.atZone(defaultZoneId).toLocalDate().plusDays(1);

        Period diff = Period.between(localDatestart, localDateend);

         System.out.printf("\nDifference is %d years, %d months and %d days old\n\n", 
                        diff.getYears(), diff.getMonths(), diff.getDays());
Bachas
  • 233
  • 6
  • 16
  • Thx for posting your own solution. Since you use java.time, I recommend you do that exclusively and avoid the outdated and notoriously troublesome classes like `Date` and in particular `SimpleDateFormat`. It will also simplify your code somewhat. – Ole V.V. Aug 24 '18 at 09:00
  • @ Ole V.V. all your effort is appreciated.And thanks to help me out. – Bachas Aug 24 '18 at 09:05
0

With Java Util Date the solution could like this...

final Date start = Date.from(ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")).toInstant());
final Date end = Date.from(ZonedDateTime.of(2021, 1, 2, 0, 0, 0, 0, ZoneId.of("UTC")).toInstant());

final Calendar startCal = new GregorianCalendar();
startCal.setTime(start);

final Calendar endCal = new GregorianCalendar();
endCal.setTime(end);

final int yearOffset = (endCal.get(Calendar.YEAR) - startCal.get(Calendar.YEAR)) * 12;
final int monthOffset = endCal.get(Calendar.MONTH) - startCal.get(Calendar.MONTH);
final int dayOffset = (endCal.get(Calendar.DAY_OF_MONTH) - startCal.get(Calendar.DAY_OF_MONTH)) > 0 ? 1 : 0;
final int offset = yearOffset + monthOffset + dayOffset;

(I used a ZonedDateTime for the consturction of the Date but you can use a timestamp or whatever of course)

With Java 8 you would use DateTimes and ChronoUnits to do the trick. The solution could look like this:

final ZonedDateTime start = ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"));
final ZonedDateTime end = ZonedDateTime.of(2021, 1, 2, 0, 0, 0, 0, ZoneId.of("UTC"));

final long monthOffset = ChronoUnit.MONTHS.between(start, end);
final int dayOffset = (end.getDayOfMonth() - start.getDayOfMonth()) > 0 ? 1 : 0;
final long offset = monthOffset + dayOffset;
Thomas W.
  • 652
  • 1
  • 7
  • 18
  • The terrible `Date` and `Calendar` classes were supplanted years ago by the *java.time* classes. No reason to be using them, nor suggesting them, in 2018. – Basil Bourque Aug 24 '18 at 17:09
  • If your intention is UTC, just use `Instant` class, or perhaps `OffsetDateTime`. Using `ZonedDateTime` for UTC is misleading. – Basil Bourque Aug 24 '18 at 17:11