我正在存储来自亚马逊云的消息,并按照有序地图中的时间戳排序。
我正在使用以下代码解析云中的时间戳:
Date timestamp = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'", Locale.ENGLISH).parse(time);
然后我将它们存储在一个有序的地图中,其中键是日期。 问题是日期只能达到秒精度。 我可以在1秒内发送几条消息,所以我需要它们以毫秒精度订购。是否有允许这样的数据结构?
答案 0 :(得分:21)
只要您的信号源的分辨率高于1秒。看起来像是模式,但你没有向我们展示任何输入示例。
Date
只是自1970-01-01以来long
毫秒的包装器。所以你已经拥有了。 Date.getTime()
将以毫秒精度返回该值。
为什么你认为Date只有一秒精度? Date.compareTo(Date anotherDate)
在毫秒级别上进行比较。
所以你的SortedMap应该可以正常工作,除非你做了一些奇怪的事情。
答案 1 :(得分:1)
我不确定你是否已经这样做了,但你可以创建自己的比较器并使用它。
作为旁注,根据您的应用程序设置,您可能需要谨慎使用SimpleDateFormat,但是它存在一些问题。
答案 2 :(得分:0)
我正在提供现代的答案:使用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
仍然可以很好地满足您的目的,它会在分数为0.01,.002等的瞬间之前进行排序。
首先,您遇到的问题比错过毫秒要严重得多:您解析的时区错误。输入字符串中的末尾Z
是UTC偏移量0,需要这样解析。您的代码中发生的事情是,SimpleDateFormat
使用了JVM的时区设置而不是UTC,这导致长达14小时的错误。在大多数情况下,您的排序仍然是正确的。在您当地时区的夏令时(DST)过渡前后,时间可能会模棱两可,因此解析可能不正确,从而导致排序顺序错误。
正如Mattias Isegran Bergander在回答中所说,毫秒的解析应该在您的代码中起作用。您之所以不这么认为,可能是因为旧的Date
类的众多设计问题中只有一个很小:尽管内部精度为毫秒,其toString
方法仅打印秒,它省去了毫秒。