I am trying to check if the date has passed more than one day or not.
And I got these errosr while it parses the string.
java.lang.IllegalArgumentException: Pattern ends with an incomplete string literal: uuuu-MM-dd'T'HH:mm:ss'Z
org.threeten.bp.format.DateTimeParseException: Text '2020-04-04T07:05:57+00:00' could not be parsed, unparsed text found at index 19
My data example is here:
val lastDate = "2020-04-04T07:05:57+00:00"
val serverFormat = "uuuu-MM-dd'T'HH:mm:ss'Z"
val serverFormatter =
DateTimeFormatter
.ofPattern(serverFormat)
val serverDateTime =
LocalDateTime
.parse(
lastDate,
serverFormatter
)
.atZone(ZoneId.of("GMT"))
val clientDateTime =
serverDateTime
.withZoneSameInstant(ZoneId.systemDefault())
val timeDiff =
ChronoUnit.DAYS.between(
serverDateTime,
clientDateTime
I've tried with these:
uuuu-MM-dd\'T\'HH:mm:ss\'Z
yyyy-MM-dd\'T\'HH:mm:ss\'Z
uuuu-MM-dd\'T\'HH:mm:ss
uuuu-MM-dd'T'HH:mm:ss'Z
yyyy-MM-dd'T'HH:mm:ss'Z
uuuu-MM-dd'T'hh:mm:ss'Z
yyyy-MM-dd'T'hh:mm:ss'Z
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ss
yyyy-MM-dd'T'HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ss
And none of them worked... What is the correct way?
You don’t need any explicit formatter. In Java (because it’s what I can write):
Output in my time zone:
The format of the string from your server is ISO 8601. The classes of java.time parse the most common ISO 8601 variants as their default, that is, without any formatter being specified.
Since the string from your server has a UTC offset, +00:00, and no time zone, like Asia/Seoul,
OffsetDateTime
is the best and most correct time to use for it. On the other hand, the client time has got time zone, soZonedDateTime
is fine here.Since server and client time denote the same time, the difference will always be zero:
Read as a period of time of 0 seconds (this too is ISO 8601 format).
If you want to know the difference between the current time and the server time, use
now()
:What went wrong in your code?
First, the UTC offset in your string is
+00:00
. Neither one format pattern letterZ
nor a literalZ
will match this. So don’t try that. Second, never giveZ
as a literal enclosed in single quotes in your format pattern string. When aZ
appears as an offset, which is common, you need to parse it as an offset, not as a literal. Third, literal text in a format pattern string needs to have a single quote before and a single quote after it. You are doing it correctly for theT
in the middle. If you didn’t meanZ
to be a literal, don’t put a single quote before it. If you did mean it to be a literal — as I said, just don’t.Links
OffsetDateTime.parse()