Java “有什么用?”;宽大;?

Java “有什么用?”;宽大;?,java,date,datetime,Java,Date,Datetime,这里lenient用于JavaDateFormat。我查了一下医生,但没听清楚医生说了什么 任何人都可以告诉我这个lenient的用途是什么,并给出一个我们使用它的实时示例吗?如果您希望它严格接受您提供的日期格式,您可以将日期解析器设置为notlenent。这一点在以下章节中有很好的解释: 默认情况下,解析是宽松的:如果输入不是此对象的format方法使用的格式,但仍然可以作为日期进行解析,则解析成功。客户可以通过调用setLenient(false)来坚持严格遵守格式 例如: SimpleDa

这里
lenient
用于Java
DateFormat
。我查了一下医生,但没听清楚医生说了什么


任何人都可以告诉我这个
lenient
的用途是什么,并给出一个我们使用它的实时示例吗?

如果您希望它严格接受您提供的日期格式,您可以将日期解析器设置为notlenent。这一点在以下章节中有很好的解释:

默认情况下,解析是宽松的:如果输入不是此对象的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)
报告明确指出:

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

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

基本上,
DateFormat
set和Javadoc声明:

指定日期/时间解释是否宽松。 在宽大的解释下,诸如“1996年2月942日”之类的日期将被删除 被视为相当于2月1日后的第941天, 1996在严格(不宽容)的解释下,此类日期将导致 要抛出的异常。默认为宽松


若日期不宽松,若您传递的日期超出范围,它将抛出错误;若日期不宽松,它将接受并修复该日期。e、 g
8月61日
上述评论将变为9月30日。
关于如何设置它。默认值为true。

日期格式对象默认为宽松

(Javadoc-日历)

Calendar有两种解释日历字段的模式:lenient 不宽容。当日历处于宽松模式时,它接受 日历字段值的范围比它产生的范围更广。当日历 重新计算get()返回的日历字段值,所有 日历字段是标准化的。例如,宽大 GregorianCalendar将月份==1月,月份中的日期==32解释为 二月一号

当日历处于非宽容模式时,如果 其日历字段中存在任何不一致。例如,一个 GregorianCalendar始终生成介于1和 一个月的长度。一个不宽容的格雷戈里安·卡伦达抛出了一个 计算其时间或日历字段值(如有)时出现异常 已设置超出范围的字段值


我的建议是永远关闭宽恕。我想不出有哪种情况需要对其进行宽松处理,对于SimpleDataFormat之类的类,此设置永远不应该是默认设置。宽松处理可以将垃圾解释为有效的时间字符串,并打开在测试中可能难以捕获的错误。此外,如果你使用“宽容”来容忍时间格式的变化,你会被烧死。例如:

System.out.println(new SimpleDateFormat("yyyyMMdd").parse("2010-12-30"));
产生以下结果(您的时区可能会有所不同):

这个荒谬的结果似乎是2010年的零下一个月(“1”),第二天(“2-”)。第零个月是十二月

不幸的是,使用setLenient(false)不会导致对模式的严格解释。SimpleDataFormat将容忍模式匹配后的垃圾,如下所述:

此外,对于模式字符的数量也不严格,例如“d”而不是“dd”:

收益率:

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

使用SimpleDataFormat验证日期/时间字符串是非常不可靠的。如果您遵循上面的链接,您将看到一些解决方案,包括我编写的更严格版本的SimpleDataFormat

宽大是指是否会在任何时候实施严格的规则 解析。如果DateFormat对象比较宽松,它将接受Jan 32, 2005事实上,它将采取自由转换到2006年2月1日。默认情况下,DateFormat对象是宽松的

结果是:

1/26/07
Jan 26, 2007
January 26, 2007
Friday, January 26, 2007

@比纳娅:你不需要给每一个帮助过你的人发“谢谢”的短信。事实上,这是令人沮丧的。只需对每个对你有帮助的答案进行投票(并有选择地接受帮助最大的答案)。请参阅(付费部分)。@Theelette绅士:我不确定我是否同意(这确实增加了噪音),但更重要的是,应该注意,在我发表这篇评论时,这个答案的得票率为零(并且OP有足够的代表投票支持)。我的问题是,默认情况下,为什么
宽容
正确!如果它在默认情况下为false,那么对我来说就更有意义了,因为程序员,尤其是初学者,倾向于使用SDF作为检查日期有效性的一种方法,并期望“宽松可解析”的日期失败(但它会过去)。宽大应该是那些理解它并实际需要使用它的人的额外特征。Java开发人员决定将其作为SDF系统的标准行为,迫使其他人学习并使用
setLenient(false)
,这是荒谬的。啊@ADTC:创建一个工厂,为您创建的每个组件设置您自己的适当默认值。“一个例外”-您必须喜欢这样的文档。见鬼,我想抓住它,所以给我类型。我希望
set()
已经抛出异常。相反,该方法抛出一个IllegalArgumentException?SimpleDataFormat SimpleDataFormat=新SimpleDataFormat(“yyyy”);System.out.println(simpleDataFormat.parse(“4”);SimpleDataFormat.setLenient(假);System.out.println(simpleDataFormat.parse(“4”);原因(在公历中,这是Java的默认设置)
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
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