java.text.ParseException:无法解析的日期:yyyy-MM-dd HH:mm:ss.SSSSSS

我得到以下代码的ParseException

  String dateStr = "2011-12-22 10:56:24.389362"; String formatStr = "yyyy-MM-dd HH:mm:ss.SSSSSS"; Date testDate = null; SimpleDateFormat sdf= new SimpleDateFormat(formatStr); sdf.setLenient(false); testDate = sdf.parse(dateStr); System.out.println("CHECK DATE " + sdf.format(testDate)); 

Exception in thread "main" java.text.ParseException: Unparseable date: "2011-12-22 10:56:24.389362" at java.text.DateFormat.parse(DateFormat.java:337)

如果我注释掉行sdf.setLenient(false) ,那么我会看到输出的时间差CHECK DATE 2011-12-22 11:02:53.000362

我究竟做错了什么??

‘S’是毫秒。 一秒钟内有1000(0到999)毫秒。 389362大于999.额外的389000毫秒转换为389秒,或6分29秒,并添加到时间。

S格式说明符是指毫秒。 当您允许宽松解析时,最后一部分被解释为389362毫秒。 当这个被添加到目前为止的日期时,最后3个数字(实际上,值为%1000)变为实际的毫秒数,并且您最终得到的日期约为389秒(~6 1/2分钟),比您预期的要晚。 (通过严格的解析,解析器知道389362毫秒没有意义,因此它会抛出错误。)

最简单的方法是,如果你可以保证日期总是这样,那就是砍掉最后3位数。 (大约一半的时间会给你一个毫秒的关闭日期。但这比编写日期解析器要好…)

您的日期输入毫秒是不正确的。 它应该是:-

String dateStr = "2011-12-22 10:56:24.389";

您也不需要模式中额外数量的“S”。 以下应该足够了:

String formatStr = "yyyy-MM-dd HH:mm:ss.S";

在java文档中明确提到了Number表示类型:

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

当你将lenient设置为true(或注释掉默认为true的行)时,它会起作用,因为你要求解析器对解析不严格。 来自setLenient()上的java文档: –

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

S仅用于毫秒 。 如果你想要微秒,你将不得不编写自己的解析器。

使用toISOString('HH:mm:ss.S')获得毫秒(3位数),然后根据需要使用0完成。

例如:

 new Date().toISOString('HH:mm:ss.S') 

返回“2012-02-10T12:16:39.124Z”