"宽大"有什么用?

Bin*_*aya 58 java datetime date

lenient是在Java中使用的DateFormat.我检查了文档,但没有得到它的说法.

任何人都可以告诉我这有什么用处lenient,我们使用它的一个实时例子?

Buh*_*ndi 49

javadoc中明确指出:

指定日期/时间解析是否宽松.通过宽松的解析,解析器可以使用启发式来解释与该对象的格式不完全匹配的输入.通过严格的解析,输入必须与此对象的格式匹配.

因此,如果您有一个模式并创建一个严格匹配您的模式的日期对象,请将lenient设置为false.此外,DateFormat默认情况下是宽松的.

基本上,DateFormat集合Calendar.setLenient和Javadoc声明:

指定日期/时间解释是否宽松.通过宽松的解释,诸如"1996年2月942"之类的日期将被视为等同于1996年2月1日之后的第941天.通过严格(非宽松)解释,此类日期将导致例外被抛出.默认值是宽松的.

  • 我的问题是,为什么默认情况下`lenient` _true_!如果默认情况下它是_false_,那对我来说会更有意义,因为程序员,特别是初学者,倾向于使用SDF作为检查日期有效性的方法,并期望一个"宽大的可解析"日期失败(但它会通过).宽恕应该是一个**额外的**功能,对于那些了解它并且**实际需要使用它**.Java开发人员决定将其作为SDF系统的标准行为,迫使其他人学习并使用`setLenient(false)`,这是荒谬的.哎呀!... (45认同)

Tho*_*ung 23

例如:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
System.out.println(simpleDateFormat.parse("0"));
simpleDateFormat.setLenient(false);
System.out.println(simpleDateFormat.parse("0"));
Run Code Online (Sandbox Code Playgroud)

结果是:

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)
Run Code Online (Sandbox Code Playgroud)

  • 为什么以下代码有效.?SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy"); 的System.out.println(simpleDateFormat.parse( "4")); simpleDateFormat.setLenient(假); 的System.out.println(simpleDateFormat.parse( "4")); (2认同)

Ste*_*ell 20

我的建议是永远关闭宽容.我想不出你想要宽松的情况,这个设置永远不应该是像SimpleDateFormat这样的类的默认设置.宽松处理可以将垃圾解释为有效的时间字符串,并打开可能难以在测试中捕获的错误.此外,如果您使用宽松来容忍时间格式的变化,您将被烧毁.例如:

System.out.println(new SimpleDateFormat("yyyyMMdd").parse("2010-12-30"));
Run Code Online (Sandbox Code Playgroud)

收益率(您的时区可能会有所不同):

Mon Nov 02 00:00:00 EST 2009
Run Code Online (Sandbox Code Playgroud)

这个荒谬的结果似乎是2010年的减去一个月("-1"),第二天("2 - 2").第0个月是12月!

不幸的是,使用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"));
Run Code Online (Sandbox Code Playgroud)

产量:

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
Run Code Online (Sandbox Code Playgroud)

同样使用setLenient(false)"2010/01/5"接受模式"yyyy/MM/dd".并且忽略了数据分歧,例如"1999/2011",模式为"yyyy/yyyy"(答案是2011).

使用SimpleDateFormat来验证日期/时间字符串是不可靠的.如果您按照上面的链接,您将看到一些解决方案,包括我编写的更严格的SimpleDateFormat版本!


Sha*_*zeb 10

如果日期不宽松,如果你超出范围日期会抛出错误,但如果不是那么它会接受并修复它.例如August 61st,上面的评论将成为9月30日. Java doc如何设置它.默认为true.


ada*_*ost 8

默认情况下,DateFormat对象是宽松的.

宽恕(Javadoc - 日历)

Calendar有两种解释日历字段的模式,lenient和non-lenient.当日历处于宽松模式时,它接受比它产生的更广泛的日历字段值.当日历重新计算get()返回的日历字段值时,所有日历字段都会进行规范化.例如,宽松的GregorianCalendar将MONTH == JANUARY,DAY_OF_MONTH == 32解释为2月1日.

当日历处于非宽松模式时,如果日历字段中存在任何不一致,则会引发异常.例如,GregorianCalendar总是生成介于1和月长之间的DAY_OF_MONTH值.如果已设置任何超出范围的字段值,则非宽松的GregorianCalendar在计算其时间或日历字段值时会抛出异常.

  • @Joachim Sauer,谢谢你从不气馁. (3认同)
  • @Binaya:您不需要向每个帮助过的人发送"谢谢"消息.事实上它是*气馁*.只需提供帮助您的每个答案(并且可选择接受最有帮助的答案).请参阅[常见问题解答](http://stackoverflow.com/questions/how-to-answer)(向前付款)部分. (2认同)

Xel*_*ian 5

宽容是指在解析时是否将应用严格的规则。如果DateFormat对象是宽大的,它将接受2005年1月32日。实际上,将其自由转换为2006年2月1日。默认情况下,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) {
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

1/26/07
Jan 26, 2007
January 26, 2007
Friday, January 26, 2007
Run Code Online (Sandbox Code Playgroud)


tal*_*las 4

如果您希望日期解析器严格接受您提供的日期格式,您可以将日期解析器设置为不宽松。文档中对此进行了很好的解释:

默认情况下,解析是宽松的:如果输入不是该对象的 format 方法使用的形式,但仍然可以解析为日期,则解析成功。客户可以通过致电坚持严格遵守格式setLenient(false)