Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to strictly parse a date with only a year and a week number when the first day of this week is in the previous year?

My goal is to have a strict parsing (and forbid dates like '98/99' for example). However, the following code raises a java.text.ParseException with the message Unparseable date: "98/01":

SimpleDateFormat sdf = new SimpleDateFormat("yy/ww");
sdf.setLenient(false);
sdf.parse("98/01");

This is indeed for the first week of 1998, which starts on a Thursday. However, the parsing of a week always returns the date of the first day of this week. In that case, it would be 12/29/1997. And this is why an exception is raised.

It seems this problem comes from the GregorianCalendar class and more specifically from the computeTime() method which checks if the original fields match the fields externally set when the parsing is not lenient:

if (!isLenient()) {
  for (int field = 0; field < FIELD_COUNT; field++) {
    if (!isExternallySet(field)) {
      continue;
    }

    if (originalFields[field] != internalGet(field)) {
      // Restore the original field values
      System.arraycopy(originalFields, 0, fields, 0, fields.length);
      throw new IllegalArgumentException(getFieldName(field));
    }
  }
}

Is this a bug? I think parsing 1998/01 should indeed return 12/29/1997 and not raise any exception. However, do you know how to make the parsing returns 01/01/1998 instead (which would be the first day of the week in the specified year)?

like image 970
Stéphane Avatar asked Apr 27 '11 09:04

Stéphane


1 Answers

I think this should work for you (you need the library joda time for this):

public static Date parseYearWeek(String yearWeek) {
    DateTime dateTime = DateTimeFormat.forPattern("yy/ww").parseDateTime(yearWeek);

    if (dateTime.getWeekOfWeekyear() == 1 && dateTime.getMonthOfYear() == 12) {
        dateTime = DateTimeFormat.forPattern("yyyy/mm").parseDateTime((dateTime.getYear() + 1) + "/01");
    }

    return dateTime.toDate();
}
like image 104
Matej Tymes Avatar answered Oct 19 '22 06:10

Matej Tymes