提问者:小点点

Java 日期到毫秒


我正在存储来自亚马逊云的消息,并在排序后的地图中按时间戳排序。

我正在使用以下代码从云中解析时间戳:

Date timestamp = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'", Locale.ENGLISH).parse(time);

然后我将它们存储在一个排序的地图中,关键是日期。问题是日期只能归结为秒精度。我可以在1秒内发送几条消息,所以我需要它们以毫秒精度排序。有没有数据结构允许这样做?


共3个答案

匿名用户

只要你的源的分辨率高于1秒。从模式上看是这样的,但是你没有给我们看任何输入示例。

Date只是自1970-01-01以来long毫秒的包装器。所以你已经有了。Date.getTime()将返回它,精度为毫秒。

为什么你认为Date只有一秒的精度?Date.compareTo(Date antherDate)在毫秒级别上进行比较。所以你的SortedMap应该可以正常工作,除非你在做一些奇怪的事情。

匿名用户

我不确定您是否已经这样做了,但您可以创建自己的比较器并使用它。

作为旁注,根据您的应用程序设置,您可能需要小心使用 SimpleDateFormat,它存在一些问题。

匿名用户

我提供了一个现代的答案:使用java.time,这是一个现代的java日期和时间API,用于日期和时间工作。首先是因为它比旧的日期和时间类(如< code>Date和(哦,太可怕了)< code>SimpleDateFormat)好用得多,这些类的设计很差。幸运的是,它们早已过时了。一个额外的优点是:您的日期-时间字符串是ISO 8601格式,java.time的类将这种格式解析为默认格式,也就是说,没有任何显式的格式化程序。

    String stringFromCloud = "2014-06-14T08:55:56.789Z";
    Instant timestamp = Instant.parse(stringFromCloud);
    System.out.println("Parsed timestamp: " + timestamp);

输出:

解析的时间戳:2014-06-14T08:55:56.789Z

现在可以清楚地看到字符串已以全毫秒精度解析(Instant 可以以纳秒精度解析,最多 9 位小数)。即时对象可以很好地用作排序地图的键。

角盒:如果秒i的分数为0,则不打印。

    String stringFromCloud = "2014-06-14T08:56:59.000Z";

解析时间戳:2014-06-14T08:56:59Z

您需要相信,当没有分数被打印时,这是因为它是0。Instant仍然可以很好地满足您的需要,在使用分数.001、.002等的瞬间之前进行排序。

首先,您遇到了一个比丢失毫秒更糟糕的问题:您解析到了错误的时区。传入字符串中的尾部< code>Z是0的UTC偏移量,需要照此进行解析。在您的代码中发生的事情是< code>SimpleDateFormat使用了您的JVM的时区设置而不是UTC,这导致了长达14小时的错误。在大多数情况下,你的排序仍然是正确的。在您当地时区的夏令时(DST)前后,时间可能不明确,因此解析可能不正确,导致错误的排序顺序。

正如Mattias Isegran Bergander在他的回答中所说,毫秒的解析应该在代码中起作用。您不这么认为的原因可能是因为旧的<code>Date</code>类存在许多设计问题中的一个小问题:即使它在内部具有毫秒精度,其<code>toString</code〕方法只打印秒,但它忽略了毫秒。

  • Oracle教程:Date Time解释如何使用java.Time.
  • 维基百科文章:ISO 8601