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

时间:2018-02-14 09:43:57

标签: 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 = 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作为millis或.SSS的两个日期的最佳方法是什么,比如使用try / catch多次解析?

2 个答案:

答案 0 :(得分:3)

SimpleDateFormat默认情况下不严格,因为默认情况下属性lenienttrue。但是您可以将属性lenient设置为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

请参阅DateFormat.parse(String, ParsePosition)

  

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

答案 1 :(得分:2)

你基本上问为什么SimpleDateFormat接受一个数字毫秒的值,当模式显示" .SSS"。

原因在于SimpleDateFormat的javadoc:

  

模式字母通常会重复,因为它们的数字决定了确切的呈现方式:

     

...

     

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

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

相比之下,DateTimeFormatter的javadoc简单地说"模式字母的数量决定格式",格式化和解析没有区别。

为什么他们不一样?您需要询问设计DateTimeFormatter API的人员,但我想是设计师考虑了{em> ad hoc 和SimpleDateFormat(默认)宽松解析的未指定性质模式是有害的。

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

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