16

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

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

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

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

4

3 回答 3

26

好吧,只要您的源具有高于 1 秒的分辨率。从模式看起来像这样,但您没有向我们展示任何输入示例。

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

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

于 2012-06-14T11:03:18.090 回答
1

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

附带说明一下,根据您的应用程序设置,您可能需要小心使用SimpleDateFormat的方式,它存在一些问题。

于 2012-06-14T11:04:35.817 回答
0

java.time

我提供了现代答案:使用 java.time,现代 Java 日期和时间 API,为您的日期和时间工作。首先是因为它比旧的日期和时间类(如Date和(哦,恐怖))好用得多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 位小数)。Instant对象将作为您的SortedMap.

极端情况:如果秒 i 的分数为 0,则不打印。

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

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

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

你的解析出了什么问题?

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

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

链接

于 2020-04-06T12:29:05.903 回答