2013-08-30 3 views
19

У меня есть этот код:Почему SimpleDateFormat («MM/dd/yyyy») анализирует дату до 10/20/20128?

DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); 
    dateFormat.setLenient(false); 
    Date date = dateFormat.parse("10/20/20128"); 

, и я ожидаю, что вызов dateFormat.parse бросить ParseException с года я обеспечиваю 5 символов вместо 4, как в формате я определен. Но по какой-то причине даже при условии, что lenient установлен на false, этот вызов возвращает объект Date из 10/20/20128.

Почему? Это не имеет большого значения для меня. Есть ли еще одна настройка, чтобы сделать ее еще более строгой?

+2

Если нужно разобрать его на 4 цифры, а не на 5, это будет не год. –

+0

Я верю, что если вы беспокоитесь о том, чтобы сделать его 4-кратным пользователем, или что-то не так, вам нужно будет проверить это, прежде чем устанавливать значение даты. – sealz

+1

Я не хочу, чтобы он анализировал его до 4 цифр, я хочу, чтобы он завершился неудачей (дайте мне исключение), потому что значение, которое я предоставляю, не соответствует формату точной даты. – goe

ответ

36

20128 год действителен, и Java надеется, что мир так долго будет жить.

Если число букв шаблона больше 2, то год интерпретируется буквально, независимо от количества цифр.

Reference.

Если вы хотите проверить, если дата в пределе, вы можете определить один и чек-

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); 
Date maxDate = sdf.parse("01/01/2099"); // This is the limit 

if(someDate.after(maxDate)){    
    System.out.println("Invalid date");    
} 
+0

Я понимаю это, но предоставленное значение не соответствует формату MM/dd/yyyy, который я предоставил, поэтому он все равно должен потерпеть неудачу. – goe

+1

@goe java интерпретирует что-либо большее, чем 2 года, как полный год, который поставляется. Я не могу проверить, но если вы сделали yyy, вы все равно получите все 5 номеров. – sealz

+1

@goe Вот как они решили реализовать. Попробуйте это: System.out.println (новый формат SimpleDateFormat ("yyyyyyyyyy dddddd MMMMMMMM"). Format (new Date())); И вы получите «0000002013 000030 август» –

7

См. java.text.SimpleDateFormat API, буква шаблона y: для разбора, если число букв шаблона больше 2, год интерпретируется буквально, независимо от количества цифр.

11

См javadoc

Год: Если Календарь форматирования - это григорианский календарь, применяются следующие правила: .

  • Для форматирования, если количество букв шаблона равно 2, год усечен до 2 цифр; в противном случае оно интерпретируется как число.
  • Для синтаксического анализа, если число букв шаблона больше 2, год интерпретируется буквально, независимо от количества цифр. Таким образом, с использованием шаблона «MM/dd/yyyy», «01/11/12» анализируется до 11 января, 12 AD
  • Для анализа с использованием шаблона сокращенного года («y» или «yy») SimpleDateFormat должен интерпретировать сокращенный год относительно некоторого век. Это делается путем корректировки дат в течение 80 лет до и 20 лет с момента создания экземпляра SimpleDateFormat. Например, используя шаблон «MM/dd/yy» и экземпляр SimpleDateFormat
    , созданный 1 января 1997 года, строка «01/11/12» будет
    интерпретирована как 11 января 2012 г., а строка «05/04/64» будет
    интерпретируется как 4 мая 1964 года. Во время разбора только строки, состоящие из
    ровно две цифры, как определено Character.isDigit (char), будут проанализированы в столетие по умолчанию. Любая другая числовая строка, такая как
    , буквально содержит цифру в виде строки с цифрой, цифрой из трех или более цифр или двухзначной строкой , которая не является всеми цифрами (например, «-1»).
    Так «01/02/3» или «01/02/003» анализируются по той же схеме, что и
    2 января, 3 года нашей эры.Аналогично, «01/02/-3» анализируется как 2 января 4 года до нашей эры.
  • В противном случае применяются конкретные формы системы календаря. Для форматирования и разбора, если число букв шаблона равно 4 или
    больше, используется длинная форма для календаря. В противном случае используется календарный
    конкретная короткая или сокращенная форма.

Таким образом, он будет читать все символы, которые приходят после последнего / как год.

0

Используя SimpleDateFormat в java, вы можете получить ряд человекочитаемых форматов. Рассмотрим следующий фрагмент кода:

 Date curDate = new Date(); 

     SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd"); 

     String DateToStr = format.format(curDate); 
     System.out.println(DateToStr); 

     format = new SimpleDateFormat("dd-M-yyyy hh:mm:ss"); 
     DateToStr = format.format(curDate); 
     System.out.println(DateToStr); 

     format = new SimpleDateFormat("dd MMMM yyyy zzzz", Locale.ENGLISH); 
     DateToStr = format.format(curDate); 
     System.out.println(DateToStr); 

     format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z"); 
     DateToStr = format.format(curDate); 
     System.out.println(DateToStr); 

Посмотрите на различные выходы, генерируемых различными форматами:

2014/05/11

11-5-2014 11:11:51

11 мая 2014 Восточной Европы летнее время

Вс, 11 мая 2014 23:11:51 EEST

Не стесняйтесь изменять строку формата, и вы можете получить желаемый результат.