Java Date to milliseconds

喜夏-厌秋 提交于 2021-01-02 05:01:48

问题


I'm storing messages from an amazon cloud and ordering them by their timestamp in a sorted map.

I am parsing the timestamp from the cloud with the following code:

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

and then I am storing in them in a sorted map with the key being the date. The issue is that the date only comes down to seconds precision. I can have several messages sent in 1 second, so I need them to be ordered with millisecond precision. Is there a data structure that allows this?


回答1:


Well as long as your source has a higher resolution than 1 second. Looks like that from the pattern, but you haven't shown us any input example.

Date is just a wrapper around a long milliseconds since 1970-01-01. So you have that already. Date.getTime() will return that, with millisecond precision.

Why would you think that Date only has one second precision? Date.compareTo(Date anotherDate) compares on a millisecond level. So your SortedMap should work fine unless you are doing something strange.




回答2:


I am not sure if you have done this, but you can create your own comparator and use that.

As a side note, depending on your applications setup you may want to be careful with how you use SimpleDateFormat, there are some issues with it.




回答3:


java.time

I am providing the modern answer: use java.time, the modern Java date and time API, for your date and time work. First of all because it is so much nicer to work with than the old date and time classes like Date and (oh, horrors) SimpleDateFormat, which are poorly designed. We’re fortunate that they are long outdated. An added advantage is: Your date-time string is in ISO 8601 format, and the classes of java.time parse this format as their default, that is, without any explicit formatter.

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

Output:

Parsed timestamp: 2014-06-14T08:55:56.789Z

Now it’s clear to see that the string has been parsed with full millisecond precision (Instant can parse with nanosecond precision, up to 9 decimals on the seconds). Instant objects will work fine as keys for your SortedMap.

Corner case: if the fraction of seconds i 0, it is not printed.

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

Parsed timestamp: 2014-06-14T08:56:59Z

You will need to trust that when no fraction is printed, it is because it is 0. The Instant will still work nicely for your purpose, being sorted before instants with fraction .001, .002, etc.

What went wrong in your parsing?

First, you’ve got a problem that is much worse than missing milliseconds: You are parsing into the wrong time zone. The trailing Z in your incoming string is a UTC offset of 0 and needs to be parsed as such. What happened in your code was that SimpleDateFormat used the time zone setting of your JVM instead of UTC, giving rise to an error of up to 14 hours. In most cases your sorting would still be correct. Around transition from summer time (DST) in your local time zone the time would be ambiguous and parsing may therefore be incorrect leading to wrong sort order.

As the Mattias Isegran Bergander says in his answer, parsing of milliseconds should work in your code. The reason why you didn’t think so is probably because just a minor one of the many design problems with the old Date class: even though internally it has millisecond precision, its toString method only prints seconds, it leaves out the milliseconds.

Links

  • Oracle tutorial: Date Time explaining how to use java.time.
  • Wikipedia article: ISO 8601


来源:https://stackoverflow.com/questions/11031608/java-date-to-milliseconds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!