0

Basically, i want to set dates and save it to a list. From my code below:

public List<RecordList> createRecord(BigDecimal yr){

    for (int index = 0; index <= 14; index++) {
        RecordList value = new RecordList();
        if(index == 0){
            value.setStartDt(toDate(("01-04-" + yr)));
            value.setEndDt(toDate(("30-04-" + yr)));
        }
        if(index == 1){
            value.setStartDt(toDate(("01-05-" + yr.add(new BigDecimal(1)))));
            value.setEndDt(toDate(("31-05-" + yr.add(new BigDecimal(1)))));
        }
        createRecord.add(newRecordValue);
    return createRecord;
}

private Date toDate(String date) {
    Date newDate = null;
    try {
        newDate = new SimpleDateFormat("dd-MM-YYYY").parse(date);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }
    return newDate;
}

what happens is, when I set the year to 2017, the output doesnt match with what I set:

"StartDate": "30-12-2017",
 "EndDate": "30-12-2017"

and it doesnt increment to next year, instead it decrement to:

"StartDate": "30-12-2016",
 "EndDate": "30-12-2016"
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
newbie
  • 201
  • 2
  • 4
  • 12
  • Ooh, this would be much easier and more natural to do with `LocalDate` from JSR-310 (built-in with Java 8, also backported to Java 6 and 7). These days you shouldn’t use `SimpleDateFormat` and in particular not for a task like this one. – Ole V.V. Jun 08 '17 at 14:06

2 Answers2

5

upper case Y is week year. You have to use lower case y for the calendar year:

newDate = new SimpleDateFormat("dd-MM-yyyy").parse(date);

For more Information read the Javadoc of SimpleDateFormat

Jens
  • 67,715
  • 15
  • 98
  • 113
2

The answer of @Jens is correct and should be accepted.

I add some proposals how to improve the error handling. As you can see, SimpleDateFormat is silent about what is wrong with your code. And I am sure that this behaviour has already caused many people to release tons of parsing code with sometimes "surprising" behaviour. Fortunately you have found just by accident that something is wrong.


Java-8

The new built-in library java.time (available since Java-8) would not parse but throw an exception

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-YYYY");
LocalDate d = LocalDate.parse("30-12-2017", dtf);

with following error message:

Exception in thread "main" java.time.format.DateTimeParseException: Text '30-12-2017' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {MonthOfYear=12, WeekBasedYear[WeekFields[MONDAY,4]]=2017, DayOfMonth=30}...

The existence of the field "WeekBasedYear" in the error message should enlighten you what is wrong so you go to the documentation to look for the right pattern symbol.

By the way, there is also a backport Threeten-BP available for Java-6+7. And I have now also tested the popular library Joda-Time:

DateTimeFormatter dtf = DateTimeFormat.forPattern("dd-MM-YYYY");
System.out.println(dtf.parseLocalDate("30-12-2017")); // 2017-12-30 (don't use it!)

So Java-8 is also an improvement for Joda-Time which does not see any problem in your pattern.


My library Time4J

ChronoFormatter<PlainDate> cf =
    ChronoFormatter.ofDatePattern("dd-MM-YYYY", PatternType.CLDR, Locale.ROOT);
LocalDate d = cf.parse("30-12-2017").toTemporalAccessor(); // not even executed

Here the construction of the parser fails with following message:

java.lang.IllegalArgumentException:
Y as week-based-year requires a week-date-format: dd-MM-YYYY

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126