在Java中用微秒解析时间

时间:2014-04-09 04:09:34

标签: java

我在解析Java格式为2013-01-09 09:15:03.000000的时间字符串时遇到问题。在我的数据中,最后三位数始终为0(意味着输入字符串只有毫秒精度),所以我将此格式传递给SimpleDateFormat:

formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS'000'");

但是formatter.parse("2013-01-09 09:15:02.500000");会抛出异常:

Unparseable date: "2013-01-09 09:15:02.500000"
    at java.text.DateFormat.parse(DateFormat.java:357)

任何人都知道如何正确地做到这一点?我可以使用格式yyyy-MM-dd HH:mm:ss.SSS并使用substring来摆脱最后三位数,但这真的很糟糕。

编辑:任何人都可以解释为什么格式字符串yyyy-MM-dd HH:mm:ss.SSS'000'不能用于解析时间"2013-01-09 09:15:02.500000"

3 个答案:

答案 0 :(得分:3)

尝试java.sql.Timestamp

     Timestamp ts = Timestamp.valueOf("2013-01-09 09:15:03.500000"); 
     Date date = new Date(ts.getTime())
与SimpleDateFormat

相比,它还具有线程安全性和快速性

答案 1 :(得分:1)

我已经弄明白了。仅供参考,Apache commons' FastDateFormat似乎接受SSS000格式并正确解析时间。

答案 2 :(得分:1)

java.time

我想提供现代答案。使用java.time,现代Java日期和时间API。一种选择,您可以使用格式化程序:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS");
    LocalDateTime dateTime = LocalDateTime.parse(timeString, formatter);
    System.out.println(dateTime);

使用问题"2013-01-09 09:15:02.500000"中的字符串时,打印出来:

2013-01-09T09:15:02.500

如果您希望在秒数上打印六位小数的值,即使最后三位小数为0,也可以使用相同的格式化程序将时间格式化为字符串:

    System.out.println(dateTime.format(formatter));

另一种选择,你可以利用你的字符串类似于ISO 8601格式的事实,即现代类解析为默认格式,即没有任何明确的格式化程序。只有ISO 8601有T来表示时间部分的开头,但我们可以轻松解决这个问题:

    LocalDateTime dateTime = LocalDateTime.parse(timeString.replace(' ', 'T'));

它给出了相同的结果,2013-01-09T09:15:02.500。它更短,但也更棘手。

为什么要这么麻烦?

课程DateTimestamp已经过时,特别是SimpleDateFormat已经证明很麻烦。它在你的情况下令人惊讶的行为只是一个小故事中的很多。现代API通常可以更好地使用。

为什么格式化程序不起作用?

虽然SimpleDateFormatDateTimeFormatter使用的格式模式字符串相似,但存在差异。一个是SimpleDateFormat将大写S理解为毫秒,无论其中有一个或九个,而DateTimeFormatter则表示小数秒。你的SimpleDateFormat进一步抓住了小数点后的所有六位数,忽略了你只键入了三个S的事实,所以没有剩下的零来匹配'000'(顺便说一下,撇号不是必需的,只有字母需要它们。)

链接

Oracle Tutorial