我正在存储来自亚马逊云的消息,并在排序的地图中按时间戳对它们进行排序。
我正在使用以下代码从云中解析时间戳:
Date timestamp = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'", Locale.ENGLISH).parse(time);
然后我将它们存储在一个排序的地图中,关键是日期。问题是日期只能归结为秒精度。我可以在 1 秒内发送多条消息,因此我需要以毫秒精度对它们进行排序。是否有允许这样做的数据结构?
我正在存储来自亚马逊云的消息,并在排序的地图中按时间戳对它们进行排序。
我正在使用以下代码从云中解析时间戳:
Date timestamp = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'", Locale.ENGLISH).parse(time);
然后我将它们存储在一个排序的地图中,关键是日期。问题是日期只能归结为秒精度。我可以在 1 秒内发送多条消息,因此我需要以毫秒精度对它们进行排序。是否有允许这样做的数据结构?
好吧,只要您的源具有高于 1 秒的分辨率。从模式看起来像这样,但您没有向我们展示任何输入示例。
Date
long
自 1970-01-01 以来,它只是一个毫秒左右的包装器。所以你已经有了。Date.getTime()
将以毫秒精度返回。
为什么你会认为 Date 只有一秒的精度?Date.compareTo(Date anotherDate)
在毫秒级别上进行比较。所以你的 SortedMap 应该可以正常工作,除非你在做一些奇怪的事情。
我不确定你是否已经这样做了,但你可以创建自己的比较器并使用它。
附带说明一下,根据您的应用程序设置,您可能需要小心使用SimpleDateFormat的方式,它存在一些问题。
我提供了现代答案:使用 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
方法只打印秒,它忽略了毫秒。