SimpleDateFormat 未正确解析毫秒

发布于 2024-12-01 05:29:38 字数 838 浏览 0 评论 0原文

背景:

在我的数据库表中,我有两个时间戳,

timeStamp1 = 2011-08-23 14:57:26.662
timeStamp2 = 2011-08-23 14:57:26.9

当我执行“ORDER BY TIMESTAMP ASC”时,timeStamp2被认为是更大的时间戳(这是正确的)。

要求:我需要获取这些时间戳的差异(timeStamp2 - timeStamp1)

我的实现:

public static String timeDifference(String now, String prev) {
    try {
        final Date currentParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(now);
        final Date previousParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(prev);
        long difference = currentParsed.getTime() - previousParsed.getTime();
        return "" + difference;
    } catch (ParseException e) {
        return "Unknown";
    }
}

答案应该是238ms,但返回的值是-653ms。 我不确定我做错了什么。有什么建议吗?

Background:

In my database table, I have two timestamps

timeStamp1 = 2011-08-23 14:57:26.662
timeStamp2 = 2011-08-23 14:57:26.9

When I do an "ORDER BY TIMESTAMP ASC", timeStamp2 is considered as the greater timestamp(which is correct).

Requirement: I need to get the difference of these timestamps (timeStamp2 - timeStamp1)

My implementation:

public static String timeDifference(String now, String prev) {
    try {
        final Date currentParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(now);
        final Date previousParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(prev);
        long difference = currentParsed.getTime() - previousParsed.getTime();
        return "" + difference;
    } catch (ParseException e) {
        return "Unknown";
    }
}

The answer should have been 238ms, but the value that is returned is -653ms.
I'm not sure what I'm doing wrong. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

锦爱 2024-12-08 05:29:38

您正在解析的格式和使用的格式不匹配。您期望一个三位数字段,但只提供了一位数字。它采用 9 并假设您的意思是 009,而您想要的是 900。日期格式很复杂,当您以不同的格式证明日期时,它可能会以不同的方式解析它们。

文档说 S 表示毫秒数,该字段中的数字是 9,因此它的行为正确。


编辑:这个例子可能有助于

final SimpleDateFormat ss_SSS = new SimpleDateFormat("ss.SSS");
ss_SSS.setTimeZone(TimeZone.getTimeZone("GMT"));
for (String text : "0.9, 0.456, 0.123456".split(", ")) {
  System.out.println(text + " parsed as \"ss.SSS\" is "
      + ss_SSS.parse(text).getTime() + " millis");
}

打印

0.9 parsed as "ss.SSS" is 9 millis
0.456 parsed as "ss.SSS" is 456 millis
0.123456 parsed as "ss.SSS" is 123456 millis

The format you are parsing and the format uses doesn't match. You expect a three digit field and are only providing one digits. It takes 9 and assumes you mean 009 when what you want is 900. Date formats are complicated and when you prove dates in a different format it may parse them differently to you.

The documentation says S means the number of milli-seconds and the number in that field is 9, so it is behaving correctly.


EDIT: This example may help

final SimpleDateFormat ss_SSS = new SimpleDateFormat("ss.SSS");
ss_SSS.setTimeZone(TimeZone.getTimeZone("GMT"));
for (String text : "0.9, 0.456, 0.123456".split(", ")) {
  System.out.println(text + " parsed as \"ss.SSS\" is "
      + ss_SSS.parse(text).getTime() + " millis");
}

prints

0.9 parsed as "ss.SSS" is 9 millis
0.456 parsed as "ss.SSS" is 456 millis
0.123456 parsed as "ss.SSS" is 123456 millis
千秋岁 2024-12-08 05:29:38

我不完全确定,但 JavaDoc 指出了这一点:

对于解析,模式字母的数量将被忽略,除非需要分隔两个相邻字段。

这表示 2011-08-23 14:57:26.9 中的毫秒将被解析为 9 而不是 900。添加尾随零可能有效:2011-08-23 14:57:26.900

I'm not entirely sure, but the JavaDoc states this:

For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.

This indicates that the milliseconds from 2011-08-23 14:57:26.9 would be parsed as 9 instead of 900. Adding the trailing zeros might work: 2011-08-23 14:57:26.900.

岛歌少女 2024-12-08 05:29:38

我建议使用 Joda-Time。它可以正确处理这些情况。在以下示例中,毫秒被正确解析为 200ms。

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class ParseMillis {

  public static void main(String[] args) {
    String s = "00:00:01.2";
    DateTimeFormatter format = DateTimeFormat.forPattern("HH:mm:ss.S");
    DateTime dateTime = format.parseDateTime(s);
    System.out.println(dateTime.getMillisOfSecond());
  }
}

I'd suggest using Joda-Time. It handles these situations properly. In the following example, the milliseconds are correctly parsed as 200ms.

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class ParseMillis {

  public static void main(String[] args) {
    String s = "00:00:01.2";
    DateTimeFormatter format = DateTimeFormat.forPattern("HH:mm:ss.S");
    DateTime dateTime = format.parseDateTime(s);
    System.out.println(dateTime.getMillisOfSecond());
  }
}
戴着白色围巾的女孩 2024-12-08 05:29:38

我也遇到了同样的问题,日志文件中的时间太准确,只有 6 位数毫秒。解析时间相差高达 16 分钟!搞什么?

16-JAN-12 04.00.00.999999 PM GMT --> 16 Jan 2012 04:16:39 GMT

更改位数减少了错误的差异,并且多亏了这个线程,我可以识别问题:

16-JAN-12 04.00.00.99999 PM GMT --> 16 Jan 2012 04:01:39 GMT
16-JAN-12 04.00.00.9999 PM GMT --> 16 Jan 2012 04:00:09 GMT
16-JAN-12 04.00.00.999 PM GMT --> 16 Jan 2012 04:00:00 GMT

由于 SimpleDateFormat 内部仅处理 3 位数字,我用一个小正则表达式删除了不必要的数字(忽略舍入错误,工作1 最多 n 位):

str = str.replaceAll("(\\.[0-9]{3})[0-9]*( [AP]M)", "$1$2");

感谢@Peter Lawrey 的回答,防止我发疯:-)

I had the same problem with too accurate time from my logfiles with 6 digit milliseconds. Parsing Time gave up to 16 minutes difference! WTF?

16-JAN-12 04.00.00.999999 PM GMT --> 16 Jan 2012 04:16:39 GMT

Changing the number of digits reduced the erroneous difference and thanks to this thread I could identify the problem:

16-JAN-12 04.00.00.99999 PM GMT --> 16 Jan 2012 04:01:39 GMT
16-JAN-12 04.00.00.9999 PM GMT --> 16 Jan 2012 04:00:09 GMT
16-JAN-12 04.00.00.999 PM GMT --> 16 Jan 2012 04:00:00 GMT

As SimpleDateFormat internally handles only 3 digits I removed the unnecessary with a small regex (ignoring round-off errors, working for 1 up to n digits):

str = str.replaceAll("(\\.[0-9]{3})[0-9]*( [AP]M)", "$1$2");

Thanks to @Peter Lawrey for your answer, prevented me going insane :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文