Reputation: 36051
I have an Oracle DB that has a different timezone that the servers' timezones. The servers themselves have different timezones among themselves.
I tried several datatypes: DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE, all having different issues, when being used with JDBC. See issues below (my server is in IDT timezone and the DB is on PST timezone).
Which is the correct date data type when on multi-timezone architecture?
To create the table with the differernt date types:
create table ALIK_TZ (
D date default sysdate,
t timestamp default systimestamp,
tz timestamp with time zone default systimestamp,
ltz timestamp with local time zone default systimestamp
);
Insert value:
insert into ALIK_TZ (d) values (default);
Query:
select to_char(d, 'DD-MON-YYYY HH24:MI:SS') D_SECS, ALIK_TZ.* from ALIK_TZ;
Result:
"D_SECS" "D" "T" "TZ" "LTZ"
"01-JUN-2016 06:14:04" 01-JUN-16 01-JUN-16 06.14.04.920000000 AM 01-JUN-16 06.14.04.920000000 AM -07:00 01-JUN-16 04.14.04.920000000 PM
"01-JUN-2016 06:20:54" 01-JUN-16 01-JUN-16 06.20.54.181000000 AM 01-JUN-16 06.20.54.181000000 AM -07:00 01-JUN-16 04.20.54.181000000 PM
Query using JDBC:
preparedStatement = conn.prepareStatement("select * from ALIK_TZ");
resultSet = preparedStatement.executeQuery();
Results for getObject
:
D->java.sql.Timestamp(01-JUN-2016 06:14:04)
T->java.sql.Timestamp(2016-06-01 06:14:04.92)
TZ->oracle.sql.TIMESTAMPTZ
LTZ->oracle.sql.TIMESTAMPTZ
As you can see, I can't use D nor T, because I need the result in my timezone.
Regarding TZ, if I use ResultSet.getTimestamp(4), it returns java.sql.Timestamp(2016-06-01 16:14:04.92) - in the correct timezone!!! But the disadvantage is that I cannot use an index on TIMESTAMP WITH TIME ZONE.
Regarding LTZ, I cannot even use ResultSet.getTimestamp()
. I need to pass a Calendar. Doing resultSet.getTimestamp(5, Calendar.getInstance())
returns java.sql.Timestamp(2016-06-01 13:14:04.92) - wrong timezone (UTC instead of IDT).
So it seems that I can't find the perfect date-time data type to be used with JDBC. Ideas?
* BTW, using longs (millis from 1970 UTC) can be used but really cumbersome when viewing the data in the DB.
Upvotes: 1
Views: 456
Reputation: 4604
My personal recommendation would be to use TIMESTAMP WITH TIME ZONE
on the database side and java.time.ZonedDateTime
on the Java side. This makes you independent from any server and client settings and allows to to convert to any time zone later if you decide to do so.
The only issue is when you're computing and storing dates in the future and the time zone rules for the specific time zone change. However this can be corrected if you detect this early enough.
Upvotes: 0