简体   繁体   中英

Formatter in DateTimeFormatter for ISO 8601 date format of the time

I have a question concerning DateTimeFormatter formatters.

In the SWAPI ( https://swapi.co/documentation#people ) you can read for the created and edited dates, that the format is something like this:

2014-12-09T13:50:51.644000Z

And the description for this dates is: 在此处输入图片说明

But in the doc of Class DateTimeFormatter in Predefined Formatters section, I can't see any formatter that matches the SWAPI dates example.

The problem is, when I try to parse it, is working with SSSSSS :

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'")

And with nnnnnn :

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnn'Z'")

Any idea of which one is the correct formatter?

Depending on your situation you may not need to specify a formatter at all. The classes of java.time parse (and print) ISO 8601 format as their default, that is, without any explicit formatter. As the description in your image says, this is the format you've got.

However two of the predefined formatters that you are linking to do match your example:

  1. ISO_INSTANT
  2. ISO_OFFSET_DATE_TIME

Which one to use depends on any requirements for the type you want to parse the string into. It's simplest to parse into an Instant . Don't specify a formatter, just use Instant.parse :

    String swapiCreatedString = "2014-12-09T13:50:51.644000Z";
    Instant created = Instant.parse(swapiCreatedString);
    System.out.println("Created " + created);

Output:

Created 2014-12-09T13:50:51.644Z

I you need to manipulate the parsed datetime further, for example format it for a user, OffsetDateTime offers more possibilities:

    OffsetDateTime created = OffsetDateTime.parse(swapiCreatedString);

Again no formatter is needed for parsing. Output is identical to the above.

I guess that the reasons why you didn't see that the two mentioned formatters match include:

  • None of the examples include fraction of second, but the formatters accept between 0 and 9 decimals (inclusive) of fraction of second.
  • The example offset date-time has offset +01:00 . You couldn't know that Z works as an offset too. It's pronounced “Zulu” and denotes UTC.

To answer your question more directly: None of your formats are quite correct. Since as I said Z is an offset, you will want to parse it as such and not as a literal so you get the offset information from the string. Without it you wouldn't know at which offset to interpret the 13:50:51.644. .SSSSSS is correct for fraction of second while .nnnnnn means nanosecond of second and is incorrect here. There are 10^9 nanoseconds in a second, so n only works if there are 9 digits of nanoseconds. Maybe your own example gives the best illustration:

    // nnnnnn is incorrect
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnn'Z'");
    String swapiCreatedString = "2014-12-09T13:50:51.644000Z";
    LocalDateTime created = LocalDateTime.parse(swapiCreatedString, formatter);
    System.out.println("Created " + created);

Created 2014-12-09T13:50:51.000644

You see that the 51.644 seconds have been incorrectly changed to 51.000644 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM