I have the below program and looks like ZonedDateTime is not able to parse the date string. Should I use a different date format or different library to parse?
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
class Scratch {
public static void main(String[] args) {
final String inputDate = "2022-03-12T03:59:59 0000Z";
ZonedDateTime.parse(inputDate, DateTimeFormatter.ISO_DATE_TIME).toEpochSecond();
}
}
Exception in thread "main" java.time.format.DateTimeParseException: Text '2022-03-12T03:59:59 0000Z' could not be parsed, unparsed text found at index 19 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2053) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952) at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:599) at Scratch.main(scratch_29.java:7)
Process finished with exit code 1
CodePudding user response:
That isn't a ISO_DATE_TIME format. That would require something like 2022-03-12T03:59:59 0000
(no 'Z'). A formatter that works looks something like:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
class Scratch {
public static void main(String[] args) {
final String inputDate = "2022-03-12T03:59:59 0000Z";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendPattern(".SSS")
.optionalEnd()
.optionalStart()
.appendZoneOrOffsetId()
.optionalEnd()
.optionalStart()
.appendOffset(" HHMM", "0000")
.optionalEnd()
.optionalStart()
.appendLiteral('Z')
.optionalEnd()
.toFormatter();
long epochSecond = ZonedDateTime.parse(inputDate, formatter).toEpochSecond();
System.out.println("epochSecond is " epochSecond);
}
}
as derived from this post. You can create that formatter in one place and use it over again.
CodePudding user response:
tl;dr
Your input happens to be a screwy variation of the standard IS0 8601 format used by default with the java.time.Instant
class. Fix your input string, and parse.
Instant.parse( "2022-03-12T03:59:59 0000Z".replace( " 0000Z" , "Z" ) )
Or, reformatted:
Instant
.parse
(
"2022-03-12T03:59:59 0000Z"
.replace( " 0000Z" , "Z" )
)
See this code run live at IdeOne.com.
2022-03-12T03:59:59Z
Details
ZonedDateTime
inappropriate here
ZonedDateTime
is the wrong class for your input. Your input has a Z
which is a standard abbreviation for an offset from UTC of zero hours-minutes-seconds. But no time zone indicated, only a mere offset. So use OffsetDateTime
or Instant
rather than ZonedDateTime
.
0000
and Z
redundant
The 0000
also means an offset of zero hours-minutes-seconds. This is the same meaning as the Z
. So this part is redundant. I suggest you educate the publisher of your data about the standard ISO 8601 formats. No need to invent formats such as seen in your input.
String manipulation rather than custom formatter
If all your inputs have the same ending of 0000Z
, I suggest you clean the incoming data rather than define a formatting pattern.
String input = "2022-03-12T03:59:59 0000Z".replace( " 0000Z" , "Z" ) ;
Instant instant = Instant.parse( input ) ;