Java DateTimeFormatter比SimpleDateFormat更严格吗?以毫秒为单位分析日期

Java DateTimeFormatter比SimpleDateFormat更严格吗?以毫秒为单位分析日期,java,java-8,Java,Java 8,我有一个简单的测试用例: public static void main(String[] args) { String pattern = "yyyy-MM-dd HH:mm:ss.SSS"; String date = "2017-01-15 15:15:15.5"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); DateTimeFormatter dateTimeFormatter =

我有一个简单的测试用例:

public static void main(String[] args) {
  String pattern = "yyyy-MM-dd HH:mm:ss.SSS";
  String date = "2017-01-15 15:15:15.5";

  SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
  DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
  FastDateFormat fastDateFormat = FastDateFormat.getInstance(pattern);
  try {
    System.out.println("SFD: " + simpleDateFormat.parse(date));
  }catch (Exception e) {
    System.err.println("SDF failed");
  }
  try {
    System.out.println("DTF: " + dateTimeFormatter.parse(date));
  }catch (Exception e) {
    System.err.println("DTF failed");
  }
  try {
    System.out.println("FDF: " + fastDateFormat.parse(date));
  }catch (Exception e) {
    System.err.println("FDF failed");
  }
}
输出如下:

SFD: Thu Jan 15 15:15:15 CET 1970
DTF failed
FDF: Thu Jan 15 15:15:15 CET 1970

根据结果,Java的8 DateTimeFormatter比SimpleDateFormat更严格。我的问题是,为什么在这种情况下,最好的方法是将
.S
中的两个日期都接受为毫秒或
.SSS
,就像使用try/catch多次解析一样?

SimpleDateFormat
不是严格的默认值,因为每个默认值的属性
lenient
都是
true
。但是您可以将属性
lencient
设置为false以使其严格

SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
simpleDateFormat.setLenient(false);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
try {
    System.out.println("SFD: " + simpleDateFormat.parse(date));
} catch (Exception e) {
    System.err.println("SDF failed");
}
try {
    System.out.println("DTF: " + dateTimeFormatter.parse(date));
} catch (Exception e) {
    System.err.println("DTF failed");
}
结果将是

SDF failed
DTF failed

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


您基本上是在问,当模式显示“.SSS”时,为什么
SimpleDateFormat
接受一位毫秒值

原因在javadoc中的
SimpleDataFormat

图案字母通常是重复的,因为它们的数量决定了确切的表示方式:

数字:对于格式化,图案字母的数量是最小位数,较短的数字将被零填充到此数量。对于解析,忽略模式字母的数量,除非需要分隔两个相邻字段

显然,您可以通过调用
setLenient(false)
来更改此设置。然而,javadocs并没有具体说明宽大的实际效果

相比之下,
DateTimeFormatter
的javadoc只是简单地说“模式字母的计数决定了格式”,而不区分格式和解析


为什么它们不同?您可能需要询问设计
DateTimeFormatter
API的人员,但我认为设计者认为
SimpleDateFormat
(默认)宽松解析模式的特殊性和未指定性是有害的


如何让
DateTimeFormatter
接受具有一位或三位毫秒值的日期


一种方法是使用
DateTimeFormatterBuilder
创建格式化程序。这允许您为格式中的任何字段指定最小和最大宽度。

我可以为DTF设置Lenent行为吗?@kamil看一看谢谢,发现了这个问题,但我认为有更奇特的方法