“仁慈”有什么用?

这里的 lenient是在 JavaDateFormat中使用的。我检查了文档,但是没有得到它所说的内容。

有没有人能告诉我这个 lenient的用途,我们在哪里使用它的一个实时示例?

107913 次浏览

如果希望日期解析器严格接受您提供的日期格式,可以将日期解析器设置为不宽松。这在 医生中得到了很好的解释:

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

例如:

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)

Javadoc明确指出:

指定日期/时间解析是否要宽松 如果解析过程比较宽松,解析器可能会使用启发式方法来解释输入 并不精确匹配此对象的格式。通过严格的解析, 输入必须匹配此对象的格式。

因此,如果您有一个模式并创建了一个与 严格来说匹配的日期对象,那么将宽松设置为 false。而且,在默认情况下,DateFormat是宽大的。

基本上,DateFormat设置 Calendar.setLenient,Javadoc 的状态是:

指定是否对日期/时间进行宽松的解释。 由于释义宽松,例如「942年2月,1996年」 视为相等于2月1日后的第941天, 在严格(非宽容)的解释下,这些日期将会导致 要引发的异常。默认值是宽松的。

如果日期不宽松,它会抛出错误,如果你超出范围日期,但如果不是那么它将接受是,并修复它。例如,上述评论中的 August 61st将成为9月30日。 Java 文档 关于如何设置它。

我的建议是永远不要手下留情。我想不出有什么情况需要宽大处理,而且这个设置永远不应该是 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 将容忍模式匹配之后的垃圾,如下所述:

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”被接受为模式“ yyyy/MM/dd”。数据不一致被忽略,比如“1999/2011”的模式是“ yyyy/yyyy”(答案是2011)。

遗憾的是,使用 SimpleDateFormat 来验证日期/时间字符串是不可靠的。如果你点击上面的链接,你会看到一些解决方案,包括我写的更严格的 SimpleDateFormat 版本!

宽大处理是指是否将严格的规则适用于 如果 DateFormat 对象比较宽松,它将接受1月32日, 二零零五年。事实上,它将采取自由转换为二零零六年二月一日。默认情况下,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