Почему Java SimpleDateFormat анализирует это - PullRequest
11 голосов
/ 06 апреля 2011

Привет, у меня есть простой формат даты, настроенный с помощью строки произвольного формата: Ммддгг

и я даю ему следующее значение для разбора: 4 1 01

Я не думаю, что это следует анализировать из-за пробелов, но простой формат даты возвращает дату

4 апреля 0001AD

есть идеи почему?

Ответы [ 3 ]

10 голосов
/ 06 апреля 2011

Это ожидаемое поведение - вы указываете объекту DateFormat ожидать шестнадцатизначное строковое представление даты, и это то, что вы передали. Пробелы анализируются ОК. Однако, если вы использовали «4x1x01», вы получите ошибку. Обратите внимание, что при разборе снисходительность по умолчанию равна 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

Если для параметра lenidity задано значение true (поведение по умолчанию), анализ выполняет попытку расшифровки неверного ввода, например 35-й день 31-дневного месяца становится 4-м днем ​​следующего месяца.

2 голосов
/ 06 апреля 2011

для анализа размер шаблона (количество повторяющихся символов) не является ожидаемым размером соответствующего текста. Из 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
0 голосов
/ 06 апреля 2011

Двузначный год является неоднозначным - и поэтому он предполагает 0001 - первый год, который закончился бы в 01. Можете ли вы преобразовать в четырехзначный год - возможно, используя манипуляции со строками?

...