-2

I want to add the number of months based on the duration selected by the user.

I have written the following code, it is taking the current date and adding months based on duration selected by user but I want it to take the start date passed from front end and add the months based on duration.

String le=ra.getLease_period(); //duration
String ls=ra.getLeasestart(); // start date

if (le.equals("1"))
{         
    final SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd" );
    final Date dur1 = df.parse( ls ); // conversion from String
    System.out.println("Start date passed is:" + dur1);
    String m = df.format(dur1);
    System.out.println("Formatted dur1 is" + m);
    final java.util.Calendar cal1 = GregorianCalendar.getInstance();
    cal1.setTime( date );
    cal1.add(GregorianCalendar.MONTH, 1 ); // date manipulation
    System.out.println( "result: " + df.format( cal1.getTime() ) ); 
    ra.setLeaseend(df.format( cal1.getTime() ));       
}
Pragati Kerur
  • 145
  • 1
  • 13
  • 5
    Are you limited to Java 7? It's much better to do this using Java 8's `java.time` packages. – RealSkeptic Sep 11 '17 at 08:37
  • Why are you storing Date in String? – sForSujit Sep 11 '17 at 08:44
  • http://www.joda.org/joda-time/ Joda Time is a fantastic library if you aren't using Java8. – James Sep 11 '17 at 08:46
  • What is the current output? What is the expected output? – Adriaan Koster Sep 11 '17 at 08:47
  • @RealSkeptic, You can use the `java.time` functionality with Java 7, which I certainly recommend. See [the **ThreeTen Backport**](http://www.threeten.org/threetenbp/), the backport of `java.time` to Java 6 and 7. – Ole V.V. Sep 11 '17 at 08:55
  • 2
    And Pra, whether you opt for `java.time` in Java 8 or 9, ThreeTen Backport with Java 6 or 7 or Joda-Time, I certainly recommend you scrap the outdated classes `SimpleDateFormat` and `Date`. The modern alternatives are much nicer to work with and all offer better support for adding a number of months to a date. – Ole V.V. Sep 11 '17 at 08:58
  • @Adriaan Koster The current output is if the duration is 1 month it is adding 1 month to current date. Expected output is if the duration is 1 month it should add that 1 month to the "start date" passed.. I have mentioned start date in the comment in code.. – Pragati Kerur Sep 11 '17 at 09:17
  • Possible duplicate of [How can I increment a date by one day in Java?](https://stackoverflow.com/questions/428918/how-can-i-increment-a-date-by-one-day-in-java) – Paolo Forgia Sep 11 '17 at 15:06

4 Answers4

2

Thanks all for your help.. I resolved the issue by passing the start date in cal1.setTime() function.

Calendar cal1 = new GregorianCalendar();
cal1.setTime(ra.getLeasestart());
cal1.add(Calendar.MONTH, +1);
Date today1=cal1.getTime();

if(le.equals("1")){

            System.out.println("Lease end date if duratio is 1:"+today1);
            ra.setLeaseend(today1);
        }
// and so one
Pragati Kerur
  • 145
  • 1
  • 13
  • 1
    Thanks for posting your solution. I cannot help noting that the bug you made is one that you couldn’t have made with one of the modern date and time libraries. So repeating myself: get rid of `SimpleDateFormat`, `Date` and `Calendar` and start using something less errorprone. – Ole V.V. Sep 11 '17 at 10:55
1

The duration should no be Date. I would say it should be an int (number of months).

final Integer dur1 = Integer.parseInt( le ); // conversion from String
final java.util.Calendar cal1 = GregorianCalendar.getInstance();
cal1.setTime( date );
cal1.add(GregorianCalendar.MONTH, dur1 ); // date manipulation
StanislavL
  • 56,971
  • 9
  • 68
  • 98
1

The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.

If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it here).

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

First, you can parse the input String to a LocalDate (using a DateTimeFormatter) and then add the specified number of months using the method plusMonths. Finally, you format the resulting date with the same formatter:

// assuming "le" and "ls" are as described in the question
if (le.equals("1")) {
    // parse the input to a LocalDate
    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate dt = LocalDate.parse(ls, fmt);
    // add 1 month
    LocalDate nextMonth = dt.plusMonths(Integer.parseInt(le));
    // print it
    System.out.println(fmt.format(nextMonth));
}
0

@StanislavL has already answered this... So I'm just providing this to exhibit some simple explorative test wrapping:

package time;

import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import org.junit.Test;

public class TimeTest {

    @Test
    public void timeInputs1Month() throws ParseException {
        Inputs ra = spy(new Inputs("2017-09-11", "1"));
        stackOverflowQuestion(ra);
        verify(ra).setLeaseend(eq("2017-10-11"));
    }

    @Test
    public void timeInputs12Months() throws ParseException {
        Inputs ra = spy(new Inputs("2017-09-11", "12"));
        stackOverflowQuestion(ra);
        verify(ra).setLeaseend(eq("2018-09-11"));
    }

    private void stackOverflowQuestion(Inputs ra) throws ParseException {
        String le = ra.getLease_period(); //duration
        String ls = ra.getLeasestart(); // start date

        final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        final Date date = df.parse(ls); // conversion from String
        System.out.println("Start date passed is:" + date);
        final java.util.Calendar cal1 = GregorianCalendar.getInstance();
        cal1.setTime(date);
        cal1.add(GregorianCalendar.MONTH, Integer.parseInt(le)); // date manipulation
        ra.setLeaseend(df.format(cal1.getTime()));
    }

    private class Inputs {

        private final String leaseStart;
        private final String leasePeriod;

        Inputs(String leaseStart, String leasePeriod) {
            this.leaseStart = leaseStart;
            this.leasePeriod = leasePeriod;
        }

        String getLease_period() {
            return leasePeriod;
        }

        String getLeasestart() {
            return leaseStart;
        }

        void setLeaseend(String leaseEnd) {
            System.out.println("result: " + leaseEnd);
        }
    }
}

It's also worth noting that the SimpleDateFormat class isn't thread-safe.

James
  • 1,095
  • 7
  • 20