Как строго проанализировать дату только с номером года и номером недели, если первый день этой недели в предыдущем году? - PullRequest
10 голосов
/ 27 апреля 2011

Моя цель - провести строгий разбор (и запретить такие даты, как, например, '98/99').Однако следующий код вызывает java.text.ParseException с сообщением Неразборчивая дата: "98/01" :

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

Это действительно для первой недели 1998 года , который начинается в четверг.Однако разбор недели всегда возвращает дату первого дня этой недели.В этом случае это будет 12/29/1997 .И именно поэтому возникает исключение.

Кажется, эта проблема возникает из класса GregorianCalendar и, более конкретно, из метода computeTime(), который проверяет, совпадают ли исходные поля с полями, внешне установленными при анализе не снисходителен :

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));
    }
  }
}

Это ошибка?Я думаю, что разбор 1998/01 должен действительно возвращать 12/29/1997 и не вызывать никаких исключений.Однако знаете ли вы, как сделать синтаксический анализ 01/01/1998 вместо этого (который будет первым днем ​​недели в указанном году)?

Ответы [ 2 ]

3 голосов
/ 27 апреля 2011

Я думаю, что это должно сработать для вас (для этого вам нужно время в библиотеке):

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();
}
0 голосов
/ 04 января 2013

Вы можете использовать четверг в качестве ориентира, вычесть 3 дня, чтобы вычислить дату понедельника. ИСО 8601: определение недели 1 - это первая неделя, когда наступает четверг. Это исключит компенсирующий код. Приведенный ниже код найдет понедельник через неделю, даже если понедельник относится к «предыдущему» году.

String yearWeek = "201301";
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyywwEEE").withLocale(Locale.US);
DateTime mondayInWeek= fmt.parseDateTime(yearWeek + "Thu").minusDays(3);// ISO 8601 def of week 1 is first week where Thursday occurs
System.out.println(mondayInWeek);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...