【问题标题】:Parse time with microseconds in Java在 Java 中用微秒解析时间
【发布时间】:2014-04-09 04:09:33
【问题描述】:

我在解析2013-01-09 09:15:03.000000 格式的Java 时间字符串时遇到问题。在我的数据中,最后三位数字始终为 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 来摆脱最后三位数字,但这真的很hacky。

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

【问题讨论】:

  • 我能看到的最大问题是解析器不关心出现的位数(按说),所以你可以.S 它会解析5 ,500 或500000,但这会引入滚动时间值来补偿...
  • @MadProgrammer,是否意味着如果我传入一个字符串"2013-01-09 09:15:02.5,它会将其解析为 5 毫秒而不是 500 毫秒?这真是愚蠢。
  • 也许是这样,但它确实使它变得灵活,所以你也可以将它传递给2013-1-9 9:15:2.500,它会起作用。解析的工作方式和格式化程序的工作方式略有不同......

标签: java


【解决方案1】:

试试 java.sql.Timestamp

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

与 SimpleDateFormat 相比,它也是线程安全且快速的

【讨论】:

  • 我忘了说,时间字符串实际上不在UTC时区,而是在某个本地时区。我希望能够设置时区并转换为 UTC。 SimpleDateFormat 可以设置时区,但 Timestamp 不能。
  • 时间戳解析本地时区的输入,尝试 String s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(ts.getTime());你会得到同样的时间
【解决方案2】:

java.time

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

    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。它更短,但也更棘手。

何必呢?

Date 和 Timestamp 类早已过时,尤其是 SimpleDateFormat 已被证明很麻烦。它在你的情况下令人惊讶的行为只是众多故事中的一小部分。现代 API 通常更易于使用。

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

虽然SimpleDateFormat 和DateTimeFormatter 使用的格式模式字符串相似,但也有区别。一个是SimpleDateFormat 将大写的S 理解为毫秒,无论它们是一个还是九个,而对于DateTimeFormatter,它们表示秒的小数部分。您的SimpleDateFormat 还抓取了小数点后的所有六位数字,忽略了您只输入了三个S 的事实,因此没有零可以匹配'000'(顺便说一下,撇号不是必需的,只有字母需要它们)。

链接

Oracle Tutorial

【讨论】:

    【解决方案3】:

    我已经想通了。仅供参考,Apache commons 的 FastDateFormat 似乎接受 SSS000 格式并正确解析时间。

    【讨论】:

      猜你喜欢
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-20
      • 1970-01-01
      相关资源
      最近更新 更多