Почему Java SimpleDateFormat анализирует этот
Привет, у меня есть простой формат даты, настроенный с помощью строки пользовательского формата:
Ммддгг
и я даю ему следующее значение для синтаксического анализа:
4 1 01
Я не думаю, что это должно анализировать это из-за пробелов, но Simple Date Format возвращает дату
4 апреля 0001AD
любые идеи, почему?
Ответы
Ответ 1
Это ожидаемое поведение - вы указываете объекту DateFormat ожидать 6-символьное строковое представление даты, и это то, что вы передали. Пространства анализируются ОК. Однако, если вы использовали "4x1x01", вы получили бы ошибку. Обратите внимание, что при разборе значение lenity по умолчанию равно true, например.
DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("4 1 01"); // runs successfully (as you know)
DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("41 01"); // 5 character String - runs successfully
DateFormat df = new SimpleDateFormat("MMddyy");
df.setLenient(false);
Date date = df.parse("41 01"); // 5 character String - causes exception
DateFormat df = new SimpleDateFormat("MMddyy");
Date date = df.parse("999999"); // 6 character String - runs successfully
DateFormat df = new SimpleDateFormat("MMddyy");
df.setLenient(false);
Date date = df.parse("999999"); // 6 character String - causes exception
Когда сниженствуется значение true (поведение по умолчанию), синтаксический анализ делает попытку расшифровать недопустимый ввод, например. 35-й день 31-дневного месяца станет 4-м днем следующего месяца.
Ответ 2
для синтаксического анализа размер шаблона (количество повторяющихся символов) не является ожидаемым размером соответствующего текста. Из javadoc для разных соответствующих типов презентаций:
- Номер. Для синтаксического анализа число букв шаблона игнорируется, если только для разделения двух соседних полей не требуется.
- Год. Во время разбора только строки, состоящие из ровно двух цифр [...], будут проанализированы в течение столетия по умолчанию. Любая другая цифровая строка, такая как строка с одним символом, трехзначная строка или двухзначная строка, которая не является всеми цифрами (например, "-1" ), интерпретируется буквально, Таким образом, "01/02/3" или "01/02/003" анализируются с использованием того же шаблона
- Месяц. Если число букв шаблона равно 3 или более, месяц интерпретируется как текст; в противном случае оно интерпретируется как число.
Пробелы заставляют парсер останавливать синтаксический анализ реального поля (конечные пробелы недопустимы для чисел) и начинаются со следующего. Так как шаблон не имеет пробела между этими двумя полями, он не расходуется и является частью второго поля (допустимые пробелы). Таким образом, год получил не "ровно две цифры" и не будет анализироваться в столетие по умолчанию.
Анализ синтаксического анализа (lenient
установлен на false
):
FORMAT TEXT RESULT (ISO yyyy-MM-dd)
-------------------------------------------------
dddyy 01011 2011-01-10
dddyy 10 11 0011-01-10 (year is 3 chars: " 11")
dddyy 10 1 0001-01-10 (year is 2 char but not 2 digits: " 1")
dddy 01011 2011-01-10 ("y" same as "yy")
dd yy 10 11 2011-01-10 (ok, whitespace is consumed, year: "11")
d/y 3/4 0004-01-03 (year is not 2 digits)
d/y 3/04 2004-01-03
M/d/y 4/6/11 2011-04-06
Ответ 3
Двухзначный год неоднозначен - и поэтому предполагается, что 0001 - первый год, который закончился бы в 01 году. Можете ли вы преобразовать в 4-значные годы - возможно, используя манипуляции с строками?