Я отлаживал некоторый существующий код, для которого модульные тесты перестали работать в моей системе, но не в системах коллег. Первопричина состоит в том, что SimpleDateFormat бросает ParseExceptions при парсинге дат, которые должны быть parseable. Я создал модульный тест, который демонстрирует код, который перестал работать в моей системе:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import junit.framework.TestCase;
public class FormatsTest extends TestCase {
public void testParse() throws ParseException {
DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
formatter.setTimeZone(TimeZone.getDefault());
formatter.setLenient(false);
formatter.parse(formatter.format(new Date()));
}
}
Этот тест бросает ParseException на мою систему, но работает успешно в других системах.
java.text.ParseException: Unparseable date: "20100603100243.118 -0600"
at java.text.DateFormat.parse(DateFormat.java:352)
at FormatsTest.testParse(FormatsTest.java:16)
Я нашел, что могу setLenient(true)
и тест успешно выполнится. setLenient(false)
то, что используется в производственном коде, которому подражает этот тест, таким образом, я не хочу изменять его.
--- Отредактировано после ответа, указывающего, что разработчик использует виртуальную машину Java J9 1.5.0 от IBM ---
JVM IBM J9, похоже, имеет несколько ошибок и несовместимостей в подпрограмме синтаксического анализа DateFormat, которая, вероятно, наследуется, потому что это подкласс DateFormat. Некоторые свидетельства в поддержку того, что IBM J9 не работает так, как можно было бы ожидать от других JVM (например, Sun HotSpot JVM), можно увидеть здесь .
Обратите внимание, что эти ошибки и несовместимости даже не согласованы в J9 JVM, другими словами, логика форматирования IBM J9 может фактически генерировать форматированное время, несовместимое с логикой синтаксического анализа IBM J9.
Похоже, что люди, привязанные к JVM IBM J9, склонны обходить ошибку в JVM, не используя DateFormat.parse (...) (или SimpleDateFormat.parse (...)). Вместо этого они, как правило, используют java.util.regex.Matcher для ручного анализа полей.
Возможно, более поздний выпуск J9 JVM исправит проблему, а может, и нет.
--- Исходное сообщение следует ---
Забавно, тот же код изменен на:
import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
public class FormatsTest {
public void testParse() throws ParseException {
DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
formatter.setTimeZone(TimeZone.getDefault());
formatter.setLenient(false);
System.out.println(formatter.format(new Date()));
formatter.parse(formatter.format(new Date()));
}
public static void main(String[] args) throws Exception {
FormatsTest test = new FormatsTest();
test.testParse();
}
}
отлично работает в моей системе. Держу пари, что это что-то в вашем окружении. Либо вы компилируете код в одном основном выпуске JVM и запускаете его в другом (что может вызвать некоторые проблемы, поскольку библиотеки могут быть устаревшими), либо система, в которой вы его запускаете, может странно сообщать информацию о часовом поясе.
Наконец, вы можете подумать, используете ли вы очень раннюю версию JVM. Иногда ошибки проникают в различные версии, и они исправляются в более поздних выпусках.Не могли бы вы изменить свой вопрос, включив в него информацию о «java-версии» для вашей системы?
В любом случае, оба эти утверждения являются лишь обоснованными предположениями. Код должен работать так, как написано.
Вероятно, это ошибка в виртуальной машине IBM J9, касающаяся класса SimpleDateFormat.
Этот пост показывает аналогичную проблему и говорит, что она должна быть исправлена в v6.
Вы можете найти список изменений для нескольких выпусков здесь .
Я вижу, что есть номер, связанный с DateFormat. Так что вам, вероятно, следует отправить отчет об ошибке или что-то еще в IBM, чтобы они предоставили вам исправление.