什么是“宽松”的使用?

Java DateFormat使用了DateFormat 。 我检查了文档,但没有得到它所说的。

请问任何人都可以告诉我这个lenient的用途是什么,我们用一个实时的例子来说明这个用法呢?

javadoc明确指出:

指定date/时间parsing是否是宽松的。 通过宽松的parsing,parsing器可以使用启发式来解释不精确匹配该对象格式的input。 严格的parsing,input必须匹配这个对象的格式。

所以,如果你有一个模式,并创build一个严格匹配你的模式的date对象,请将lenient设置为false 。 此外,默认情况下, DateFormat是宽松的。

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

指定date/时间解释是否宽松。 如果解释宽松,那么1996年2月942这个date就等同于1996年2月1日之后的第941天。由于严格的(非宽松的)解释,这样的date将会引发exception。 默认是宽松的。

比如这个:

 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) 

我的build议是永远放松宽松。 我想不出你想要宽松的情况,这个设置不应该是像SimpleDateFormat这样的类的默认值。 宽松处理可以将垃圾解释为有效的时间string,并打开在testing中可能难以捕捉的错误。 另外,如果你使用宽松来容忍时间格式的变化,你将会被烧毁。 例如:

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

产生这个(你的时区可能会有所不同):

 Mon Nov 02 00:00:00 EST 2009 

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

不幸的是,使用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”被模式“yyyy / MM / dd”接受。 数据分歧被忽略,如“1999/2011”模式“yyyy / yyyy”(答案是2011)。

使用SimpleDateFormat来validationdate/时间string是可悲的不可靠的。 如果你按照上面的链接,你会看到一些解决scheme,包括由我写的更严格的SimpleDateFormat版本!

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

DateFormat对象默认是宽松的。

宽容 (Javadoc – 日历)

日历有两种解释日历字段的模式,宽松和不宽松。 当日历处于宽松模式时,它接受的日历字段值的范围比它产生的范围更广。 当日历重新计算由get()返回的日历字段值时,所有的日历字段都被标准化。 例如,宽松的GregorianCalendar将MONTH == JANUARY,DAY_OF_MONTH == 32解释为2月1日。

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

如果您希望它严格接受您提供的date格式,则可以将dateparsing器设置为不宽松。 这在文档中有很好的解释:

默认情况下,parsing是宽松的:如果input的格式不是该对象的格式方法使用的格式,但仍可以parsing为date,则parsing成功。 客户可以通过调用setLenient(false)来坚持严格遵守格式。

宽松是指在parsing时是否应用严格的规则。 如果一个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) { } } } 

结果是:

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