What is the use of “lenient ”?

2019-01-03 10:45发布

Here lenient is used in Java DateFormat. I checked the doc, but didn't get what it was saying.

Can any body please tell me what is the use of this lenient, with one real time example where we use it?

7条回答
男人必须洒脱
2楼-- · 2019-01-03 10:59

The javadoc clearly states:

Specify whether or not date/time parsing is to be lenient. With lenient parsing, the parser may use heuristics to interpret inputs that do not precisely match this object's format. With strict parsing, inputs must match this object's format.

So, if you have a pattern and create a date object that strictly matches your pattern, set lenient to false. Also, DateFormat is lenient, by default.

Basically, DateFormat sets Calendar.setLenient and the Javadoc states:

Specifies whether or not date/time interpretation is to be lenient. With lenient interpretation, a date such as "February 942, 1996" will be treated as being equivalent to the 941st day after February 1, 1996. With strict (non-lenient) interpretation, such dates will cause an exception to be thrown. The default is lenient.

查看更多
叛逆
3楼-- · 2019-01-03 11:04

You can set the date parser as not lenient if you want it to accept strictly a date format you provided. It is well explained in the doc:

By default, parsing is lenient: If the input is not in the form used by this object's format method but can still be parsed as a date, then the parse succeeds. Clients may insist on strict adherence to the format by calling setLenient(false).

查看更多
孤傲高冷的网名
4楼-- · 2019-01-03 11:04

Leniency refers to whether or not a strict rule will be applied at parsing. If a DateFormat object is lenient, it will accept Jan 32, 2005. In fact, it will take the liberty of converting it to Feb 1, 2006. By default, a DateFormat object is lenient.

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) {
    }
  }
}

And the result:

1/26/07
Jan 26, 2007
January 26, 2007
Friday, January 26, 2007
查看更多
叛逆
5楼-- · 2019-01-03 11:06

If date is not lenient it will throw error if you pass out of range date but if is not then it will accept is and fix it . e.g August 61st from comment above will become September 30th. Java doc on how to set it . Default is true.

查看更多
放荡不羁爱自由
6楼-- · 2019-01-03 11:12

DateFormat object is lenient by default.

Leniency (Javadoc - Calendar)

Calendar has two modes for interpreting the calendar fields, lenient and non-lenient. When a Calendar is in lenient mode, it accepts a wider range of calendar field values than it produces. When a Calendar recomputes calendar field values for return by get(), all of the calendar fields are normalized. For example, a lenient GregorianCalendar interprets MONTH == JANUARY, DAY_OF_MONTH == 32 as February 1.

When a Calendar is in non-lenient mode, it throws an exception if there is any inconsistency in its calendar fields. For example, a GregorianCalendar always produces DAY_OF_MONTH values between 1 and the length of the month. A non-lenient GregorianCalendar throws an exception upon calculating its time or calendar field values if any out-of-range field value has been set.

查看更多
Explosion°爆炸
7楼-- · 2019-01-03 11:13

My advice is to always turn lenient off. I cannot think of a case where you want lenient on, and this setting should never have been the default for classes like SimpleDateFormat. Lenient processing can interpret garbage as valid time strings and opens up errors that may be difficult to catch in testing. Also, if you are using lenient to tolerate variations in time format you are going to get burned. For example:

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

Yields this (your time zone may vary):

Mon Nov 02 00:00:00 EST 2009

This absurd result appears to be the minus one month ("-1"), second day ("2-") of 2010. The zeroth month is December!

Unfortunately, using setLenient(false) does not lead to strict interpretation of the pattern. SimpleDateFormat will tolerate garbage following the pattern match, as discussed here:

SimpleDateFormat.parse() ignores the number of characters in pattern

Also, it is not strict about the number of pattern characters, such as "d" instead of "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"));

Yields:

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

Also with setLenient(false) "2010/01/5" is accepted with the pattern "yyyy/MM/dd". And data disagreement is ignored, like "1999/2011" with the pattern "yyyy/yyyy" (answer is 2011).

Using SimpleDateFormat to validate date/time strings is sadly unreliable. If you follow the link above you will see some solutions, including a stricter version of SimpleDateFormat written by me!

查看更多
登录 后发表回答