Какая польза от «снисхождения»? - PullRequest
54 голосов
/ 30 сентября 2011

Здесь lenient используется в Java DateFormat.Я проверил документ, но не понял, о чем он говорит.

Может ли какой-нибудь орган, скажите, пожалуйста, в чем польза этого lenient, с одним примером реального времени, где мы его используем?

Ответы [ 7 ]

45 голосов
/ 30 сентября 2011

В javadoc четко указано:

Укажите, должен ли анализ даты / времени быть снисходительным.При мягком анализе синтаксический анализатор может использовать эвристику для интерпретации входных данных, которые точно не соответствуют формату этого объекта.При строгом разборе входные данные должны соответствовать формату этого объекта.

Итак, если у вас есть шаблон и создается объект даты, который строго соответствует вашему шаблону, установите значение lenient равным false,Кроме того, DateFormat является снисходительным, по умолчанию.

В основном, DateFormat устанавливает Calendar.setLenient и состояния Javadoc:

Указывает, является ли или нетинтерпретация даты / времени должна быть снисходительной.При мягком толковании такая дата, как «9 февраля 1996 года», будет считаться эквивалентной 941-му дню после 1 февраля 1996 года. При строгом (не мягком) толковании такие даты приводят к исключению.По умолчанию снисходительно.

23 голосов
/ 30 сентября 2011

Например, это:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
System.out.println(simpleDateFormat.parse("0"));
simpleDateFormat.setLenient(false);
System.out.println(simpleDateFormat.parse("0"));

Результат:

Thu Jan 01 00:00:00 CET 1
Exception in thread "main" java.text.ParseException: Unparseable date: "0"
    at java.text.DateFormat.parse(Unknown Source)
    at net.java.quickcheck.generator.support.X.main(X.java:28)
18 голосов
/ 22 октября 2013

Мой совет всегда выключать снисхождение. Я не могу вспомнить случай, когда вы хотите снисхождения, и этот параметр никогда не должен был использоваться по умолчанию для таких классов, как SimpleDateFormat. Простая обработка может интерпретировать мусор как допустимые временные строки и выявляет ошибки, которые могут быть трудно обнаружить при тестировании. Кроме того, если вы используете снисходительный, чтобы терпеть изменения в формате времени, вы будете обожжены. Например:

System.out.println(new SimpleDateFormat("yyyyMMdd").parse("2010-12-30"));

Дает это (ваш часовой пояс может отличаться):

Mon Nov 02 00:00:00 EST 2009

Этот абсурдный результат выглядит как минус один месяц ("-1"), второй день ("2-") 2010 года. Нулевой месяц - декабрь!

К сожалению, использование setLenient (false) не приводит к строгой интерпретации шаблона. SimpleDateFormat будет переносить мусор после сопоставления с шаблоном, как обсуждено здесь:

SimpleDateFormat.parse () игнорирует количество символов в шаблоне

Кроме того, оно не является строгим в отношении количества символов шаблона, таких как «d» вместо «dd»:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/d");
sdf.setLenient(false);
System.out.println("For 5:  " + sdf.parse("2010/01/5"));
System.out.println("For 05: " + sdf.parse("2010/01/05"));
System.out.println("For 15: " + sdf.parse("2010/01/15"));

Урожайность:

For 5:  Tue Jan 05 00:00:00 EST 2010
For 05: Tue Jan 05 00:00:00 EST 2010
For 15: Fri Jan 15 00:00:00 EST 2010

Также с setLenient (false) «2010/01/5» принимается с шаблоном «гггг / мм / дд». И несогласованность данных игнорируется, например, «1999/2011» с шаблоном «гггг / гггг» (ответ 2011).

Использование SimpleDateFormat для проверки строк даты / времени, к сожалению, ненадежно. Если вы перейдете по ссылке выше, вы увидите некоторые решения, в том числе более строгую версию SimpleDateFormat, написанную мной!

10 голосов
/ 30 сентября 2011

Если дата не снисходительна, она выдаст ошибку, если вы выйдете за пределы диапазона, но если это не так, она примет и исправит ее. например, August 61st из комментария выше станет 30 сентября. Java документ о том, как его установить. По умолчанию установлено значение true.

8 голосов
/ 30 сентября 2011

Объект DateFormat по умолчанию снисходительный.

Милосердие (Javadoc - Календарь)

Календарь имеет два режима интерпретации полей календаря, снисходительный и не снисходительный. Когда Календарь находится в мягком режиме, он принимает более широкий диапазон значений календарного поля, чем он производит. Когда календарь пересчитывает значения полей календаря для возврата методом get (), все поля календаря нормализованы. Например, снисходительный GregorianCalendar интерпретирует MONTH == ЯНВАРЬ, DAY_OF_MONTH == 32 как 1 февраля.

Когда календарь находится в не снисходительном режиме, он выдает исключение, если в полях календаря есть несоответствия. Например, GregorianCalendar всегда создает значения DAY_OF_MONTH от 1 до продолжительность месяца. Не снисходительный GregorianCalendar бросает исключение при расчете значений времени или поля календаря, если таковые имеются значение поля вне диапазона было установлено.

5 голосов
/ 24 апреля 2017

Терпеливость относится к тому, будет ли применяться строгое правило при разборе.Если объект DateFormat является снисходительным, он примет 32 января 2005 года. Фактически он преобразует его в формат 1 февраля 2006 года. По умолчанию объект DateFormat является снисходительным.

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;

public class MainClass {
  public static void main(String[] args) {
    DateFormat shortDf = DateFormat.getDateInstance(DateFormat.SHORT);

    DateFormat mediumDf = DateFormat.getDateInstance(DateFormat.MEDIUM);
    DateFormat longDf = DateFormat.getDateInstance(DateFormat.LONG);
    DateFormat fullDf = DateFormat.getDateInstance(DateFormat.FULL);
    System.out.println(shortDf.format(new Date()));
    System.out.println(mediumDf.format(new Date()));
    System.out.println(longDf.format(new Date()));
    System.out.println(fullDf.format(new Date()));

    // parsing
    try {
      Date date = shortDf.parse("Jan 32, 2005");
    } catch (ParseException e) {
    }
  }
}

И результат:

1/26/07
Jan 26, 2007
January 26, 2007
Friday, January 26, 2007
4 голосов
/ 30 сентября 2011

Вы можете установить синтаксический анализатор даты как не снисходительный, если вы хотите, чтобы он строго принимал формат даты, который вы указали.Это хорошо объяснено в документе :

По умолчанию синтаксический анализ является мягким: если входные данные не в форме, используемой методом формата этого объекта, но все еще могут быть проанализированы каксвидание, тогда разбор проходит успешно.Клиенты могут настаивать на строгом соблюдении формата, позвонив по номеру setLenient(false).

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...