Как строго разбирать дату всего за год и неделю, когда первый день этой недели в прошлом году?
Моя цель - иметь строгий синтаксический анализ (и, например, запретить даты типа "98/99" ). Однако следующий код вызывает сообщение java.text.ParseException
с сообщением Unparseable date: "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 вместо этого (который будет первым днем недели в указанном году)?
Ответы
Ответ 1
Я думаю, что это должно сработать для вас (для этого вам нужно время для библиотеки):
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();
}
Ответ 2
Вы можете использовать четверг в качестве ссылки, вычесть 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);