7

我正在获取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

我究竟做错了什么??

4

5 回答 5

8

“S”代表毫秒。一秒钟有 1000(0 到 999)毫秒。389362 大于 999。额外的 389000 毫秒将转换为 389 秒,即 6 分 29 秒并添加到时间中。

于 2011-12-22T17:48:44.940 回答
5

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

最简单的解决方法是,如果你能保证日期总是这样,那就是去掉最后 3 位数字。(这将有大约一半的时间为您提供一个相差一毫秒的日期。但这比编写日期解析器要好......)

于 2011-12-22T17:52:37.527 回答
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 文档:-

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

于 2011-12-22T17:49:11.370 回答
2

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

于 2011-12-22T17:53:38.257 回答
0

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

例如:

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

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

于 2012-02-10T12:18:56.830 回答