问题
I am trying to convert string value "2018-10-11T12:00:00Z"; to ZonedDateTime. If I use the default ZonedDateTime.parse(zonedDateTime) then ss portion i.e. 00 is removed and I get "2018-10-11T12:00Z" as output.
Can you please help how to retain 00 as SS part.
String zonedDateTime = "2018-10-11T12:00:00Z";
ZonedDateTime z = ZonedDateTime.parse(zonedDateTime);
System.out.println(z); // return 2018-10-11T12:00Z
ZonedDateTime z1 = ZonedDateTime.parse (zonedDateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ") );
System.out.println(z1); // Exception : Text '2018-10-11T12:00:00Z' could not be parsed at index 19
回答1:
Printing the seconds
When you just print a ZonedDateTime
using System.out.println
, you are implicitly calling its toString
method. When the seconds and fraction of second are 0, toString
leaves them out. To print them anyway, use a formatter for formatting (as opposed to using one for parsing):
DateTimeFormatter formatterWithSeconds = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX");
System.out.println("z with seconds: " + z.format(formatterWithSeconds));
Output is:
z with seconds: 2018-10-11T12:00:00Z
The important distinction here is between the ZonedDateTime
object and its string representation. The ZonedDateTime
object always contains seconds and nanoseconds, also when they are 0. The string representation may or may not include them. The one-arg ZonedDateTime.parse
has parsed the 00
seconds. BTW, it accepts strings both with and without seconds.
Use Instant or OffsetDateTime
As an aside, since your string contains an offset (Z
) and no time zone (like Africa/Nairobi), an OffsetDateTime
matches more precisely as representation. The code will work fine if you just search/replace ZonedDateTime
with OffsetDateTime
throughout since the APIs are similar.
If the offset is always Z
(for “Zulu time zone” or offset 0 from UTC), use Instant
:
String instantString = "2018-10-11T12:00:00Z";
Instant i = Instant.parse(instantString);
System.out.println("As Instant: " + i);
I have given your String
variable a name that is more appropriate for this snippet; it’s still the same string. Output:
As Instant: 2018-10-11T12:00:00Z
Curiously Instant.toString
does print the seconds even when they are 0.
Please read more about the correct type to use in the answer by @Basil Bourque.
What went wrong in your code? Pattern letter for parsing Z
// Exception : Text '2018-10-11T12:00:00Z' could not be parsed at index 19
The problem here is not with the seconds, nor with the ss
. Index 19 is where the Z
is in your string. The two-arg ZonedDateTime.parse
objects because pattern letter Z
does not match a Z
in the date-time string. If you do need to supply a format pattern string for parsing Z
, use uppercase X
(one or more of them depending on how a non-zero offset looks). From the documentation of pattern letters:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
Z zone-offset offset-Z +0000; -0800; -08:00
Links
- DateTimeFormatter documentation
- Related question: Parse Date String in Java
回答2:
The Answer by Ole V.V. is correct and should be accepted. I will add one thought and a handy reference table.
Instant
I want to emphasize the point made in that other Answer, that ZonedDateTime
technically works but is not the most appropriate class to parse a string such as 2018-10-11T12:00:00Z
. This format is define in the ISO 8601 standard. That Z
on the end, pronounced “Zulu”, means UTC (an offset of zero hours-minutes-seconds).
The ISO 8601 standard formats are used by default in the java.time classes. No need to specify a formatting pattern.
Instant
is the appropriate class to represent a moment in UTC.
Instant instant = Instant.parse( "2018-10-11T12:00:00Z" ) ;
Generate a String in the same ISO 8601 standard format.
String output = instant.toString() ;
The OffsetDateTime
class represents a moment in UTC or with other offset-from-UTC values, any number of hours-minutes-seconds. This class is also more flexible such as in generating strings with various formats via DateTimeFormatter
class. And this class is required to be supported by JDBC 4.2 and later drivers, whereas Instant
and ZonedDateTime
support is optional in JDBC.
Be clear on the difference between offset and time zone.
- Offset-from-UTC
Simply a number of hours-minutes-seconds. Positive for being ahead of UTC (towards the east) and negative for being behind UTC (towards the west). - Time zone
A time zone is much more. A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region.
Date-time types in Java
Here is a reference table for the basic date-time data types in Java, both modern and legacy. Avoid the legacy types: They are terrible, designed by people who did not understand the complexities and subtleties of date-time handling.
来源:https://stackoverflow.com/questions/57325267/zoneddatetime-ignores-00-for-ss-part