什么是“宽松”的使用?
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