java.text.ParseException:Unparseable date:yyyy-MM-dd HH:mm:ss.SSSSSS

时间:2011-12-22 17:41:34

标签: java simpledateformat parseexception

我收到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

我做错了什么?

5 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

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

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

答案 2 :(得分:3)

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

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

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

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

java docs中明确提到Number的演示文稿类型:

  

数字:对于格式化,模式字母的数量是最小的   数字和较短的数字被零填充到此数量。   对于解析,忽略模式字母的数量,除非它是   需要将两个相邻的区域分开。

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

  

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

答案 3 :(得分:2)

S仅用于milliseconds。如果你想要微秒,你必须编写自己的解析器。

答案 4 :(得分:0)

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

例如:

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

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