Почему SimpleDateFormat(MM/dd/yyyy) анализирует дату до 20.10.20128?

У меня есть этот код:

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

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

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


person goe    schedule 30.08.2013    source источник
comment
Если бы он разобрал его на 4 цифры, а не на 5, это был бы неправильный год.   -  person Josh M    schedule 30.08.2013
comment
Я считаю, что если вы беспокоитесь о том, чтобы сделать это 4, если пользовательский ввод или что-то опечатано, вам нужно будет проверить это, прежде чем устанавливать значение даты.   -  person sealz    schedule 30.08.2013
comment
Я не хочу, чтобы он анализировал его до 4 цифр, я хочу, чтобы он потерпел неудачу (дайте мне исключение), потому что значение, которое я предоставляю, не соответствует точному формату даты.   -  person goe    schedule 30.08.2013
comment
Вам нужно будет проверить значение самостоятельно и поймать собственное исключение в блоке Try. Сформируйте ответы, кажется, что Java поддерживает годы в 2 форматах: гг и полный год. Проверьте строку даты, прежде чем назначать ей дату.   -  person sealz    schedule 30.08.2013
comment
Это не будет. Вы должны закодировать его. Обновил мой ответ.   -  person Sajal Dutta    schedule 30.08.2013


Ответы (4)


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

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

Справочник.

Если вы хотите проверить, находится ли дата в лимите, вы можете определить ее и проверить:

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");            
}
person Sajal Dutta    schedule 30.08.2013
comment
Я понимаю это, но предоставленное значение не соответствует предоставленному мной формату MM/dd/yyyy, поэтому оно все равно должно завершиться ошибкой. - person goe; 30.08.2013
comment
@goe java интерпретирует все, что больше 2 лет, как полный год, который предоставляется. Я не могу проверить, но если бы вы сделали yyy, вы все равно получили бы все 5 номеров. - person sealz; 30.08.2013
comment
@goe Вот как они решили реализовать. Попробуйте следующее: System.out.println(new SimpleDateFormat(yyyyyyyyyy dddddd MMMMMMMM).format(new Date())); И вы получите 0000002013 000030 август - person Sajal Dutta; 30.08.2013
comment
@goe Если вы хотите проверить, вы можете создать календарь (скажем, 01 января 2150 г.) и getTimeInMillis () или просто жестко закодировать и сохранить значение и проверить, не является ли дата, которую вы проверяете, после сохраненной даты. Если да, то это неверная дата. - person Sajal Dutta; 30.08.2013
comment
Если вы пишете программу, для которой год должен быть четырехзначным, пожалуйста используйте 31.12.9999 в качестве maxDate. Нам не нужна еще одна проблема Y21K. - person Justin ᚅᚔᚈᚄᚒᚔ; 30.08.2013

См. документ по Java.

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

  • Для форматирования, если количество букв шаблона равно 2, год усекается до 2 цифр; в противном случае он интерпретируется как число.
  • При синтаксическом анализе, если количество букв шаблона больше 2, год интерпретируется буквально, независимо от количества цифр. Таким образом, используя шаблон "ММ/дд/гггг", "01/11/12" анализируется до 11 января 12 г. н.э.
  • Для синтаксического анализа с использованием сокращенного шаблона года ("y" или "yy") SimpleDateFormat должен интерпретировать сокращенный год относительно некоторого века. Он делает это, корректируя даты так, чтобы они находились в пределах 80 лет до и 20 лет после создания экземпляра SimpleDateFormat. Например, при использовании шаблона "ММ/дд/гг" и экземпляра SimpleDateFormat
    , созданного 1 января 1997 г., строка "01/11/12" будет
    интерпретироваться как 11 января 2012 г., а строка "04.05.64" будет
    интерпретирована как 4 мая 1964 года. Во время синтаксического анализа только строки, состоящие
    ровно из двух цифр, как определено в Character.isDigit(char), будут преобразованы в значения по умолчанию. век. Любая другая числовая строка, например строка из одной цифры, строка из трех и более цифр или строка из двух цифр, состоящая не только из цифр (например, "-1"), интерпретируется буквально.
    Итак, "02.01.3" или "02.01.003" анализируются с использованием того же шаблона, что и
    2 января 3 н.э. Точно так же «02.01.-3» анализируется как 2 января 4 г. до н.э.
  • В противном случае применяются формы, характерные для календарной системы. Как для форматирования, так и для синтаксического анализа, если количество букв шаблона равно 4 или
    больше, используется длинная форма, характерная для календаря. В противном случае используется короткая или сокращенная форма, характерная для календаря
    .

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

person Sotirios Delimanolis    schedule 30.08.2013

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

person Evgeniy Dorofeev    schedule 30.08.2013

Используя 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 по восточному поясному времени

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

person Vishal Kumar    schedule 18.09.2015