To get the correct result
I understand that you want to store your date and time into your PostgreSQL database. You have observed correctly that you can store an OffsetDateTime. I believe that you have not mentioned your data type in PostgreSQL. I am assuming timestamp with time zone since this would fit with an OffsetDateTime in UTC (in most database engines timestamp with time zone really means “in UTC time zone”).
Obtaining the OffsetDateTime in UTC that you need is simple when you know how:
String transactionTime = "2019-02-26T13:43:12Z";
OffsetDateTime odt = OffsetDateTime.parse(transactionTime);
System.out.println(odt);
Output:
2019-02-26T13:43:12Z
You see that we don’t need any formatter nor any format pattern string.
The OffsetDateTime is ready to be saved to SQL. If in doubt, consult the link at the bottom.
What went wrong in your code?
You were using the format pattern yyyy-MM-dd'T'HH:mm:ss'Z'. However you must never enclose Z as a literal in your format pattern. Z is an offset of zero from UTC and must be parsed as an offset. java.time is on purpose less “friendly” than Joda-Time with providing defaults that you never intended, so throws an exception rather than giving you a wrong result. Thinking about it this is more helpful since it forces us to correct our errors. Enclosing Z in single quotes in the format was the reason why java.time could not extract the UTC offset needed for an OffsetDateTime from your string and therefore gave you the error “Text '2019-02-26T13:43:12Z' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2019-02-26T13:43:12 of type java.time.format.Parsed”.
To get the same wrong result as you got with your Joda-Time code
Your code using Joda-Time is wrong. Also with Joda-Time you need to parse Z as an offset and therefore must not enclose it in quotes as a literal. The Z in your string is there to tell you and us that your string is in UTC. Joda-Time used the time zone setting of your JVM instead of UTC and gave you a wrong result. When I ran your code on my computer, I got:
Tue Feb 26 13:43:12 CET 2019
It looks right because the time of day, 13:43:12, agrees with the string. But! Central European Time, abbreviated CET in the output, is 1 hour ahead of UTC. So the result is really 1 hour behind and equal to 12:43:12 UTC. So wrong. Possibly you were running the code on a server with UTC as its default time zone and thereby got the correct result. But you should not have your code rely on the time zone setting.
It’s not clear from your question whether you want the same wrong result. In case you do:
// This is wrong! Ignore the UTC offset in the
// string and use the default time zone instead
LocalDateTime ldt = LocalDateTime.parse(
transactionTime, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
OffsetDateTime odt = ldt.atZone(ZoneId.systemDefault())
.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odt);
Output on my computer:
2019-02-26T12:43:12Z
In the code I specified output in UTC, so got 12:43:12, so the same point in time as I got from your Joda-Time code.
Link
This is more for other readers, about saving the OffsetDateTime to an SQL database: Answer by Arvind Kumar Avinash to Dates with no time or timezone component in Java/MySQL showing how to store java.time types to SQL
Z, you should remove all usage of OffsetDateTime and use Instant.parse instead.java.timeclasses. It might be more useful if you could show what you eventually do with that dateOffsetDateTimebut I gather that in postgresql with type timestamp with timezone everything is converted to UTC and stored that way so the actual offset is lost. But you will have an instant in time stored