Reputation: 1442
Part 1:
I have a file which contains date as string in the following format: 2006-02-16T21:36:32.000+0000
I need to write this value to Postgres in a column which is of type Timestamp
. How do I go about doing this in Java?
Part 2:
I need to read the value saved in Part 1 from Postgres, and convert it to a string of the following format "2006-02-16T21:36:32.000+0000"
This is what I have tried:
Timestamp lastSyncDate = Timestamp.valueOf(2006-02-16T21:36:32.000+0000)
When I try to write it to postgres, it gives me the following error:
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
Upvotes: 0
Views: 5170
Reputation: 338181
myPreparedStatement.setObject(
… ,
OffsetDateTime.parse( "2006-02-16T21:36:32.000+0000" )
)
You said your column is of type TIMESTAMP
which is short for TIMESTAMP WITHOUT TIME ZONE
. This type purposely lacks any concept of time zone or offset-from-UTC. Not usually appropriate for common business purposes.
That is the wrong type for your input. Your input has an offset-from-UTC of zero hours which means UTC itself. Having an offset or zone, your data should only be stored in a TIMESTAMP WITH TIME ZONE
type column. In this …WITH…
type in Postgres, any submitted offset/zone info is used to adjust into UTC for storage, and then discarded.
Storing a date-time value with an offset or zone in a column of type TIMESTAMP WITHOUT TIME ZONE
is like storing a price/cost with a designated currency( USD, Euros, Rubles, etc.) in a column of numeric type. You are losing vital data, the currency. This renders your data worthless.
See the Postgres documentation page for these types.
Whenever possible, use objects to exchange data with your database rather than passing meter strings. Let your JDBC driver do it’s job in marshaling the data back-and-forth.
Parse the input string as an OffsetDateTime
object.
Your input strings are in a format defined by the ISO 8601 standard. The java.time classes use ISO 8601 formats by default when parsing/generating strings. No need to specify a formatting pattern.
String input = "2006-02-16T21:36:32.000+0000" ;
OffsetDateTime odt = OffsetDateTime.parse( input ) ;
Define your SQL as a prepared statement.
With JDBC 4.2 and later, you can directly exchange java.time objects with your database. No need to ever again use the troublesome legacy classes such as java.sql.Timestamp
.
You could pass an OffsetDateTime
. I like to extract an Instant
to demonstrate to the reader that I understand how Postgres always stores a TIMESTAMP WITH TIME ZONE
value in UTC.
Instant instant = odt.toInstant() ;
myPreparedStatement.setObject( … , instant ) ;
Retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Upvotes: 4
Reputation: 12392
2006-02-16T21:36:32.000+0000
looks like a ISO-8601 timestamp.
postgres understands this format. just treat it like any other string.
don't try to convert it into a java timestamp
Upvotes: 2