Example of using JDBC Timezone
Posted by Steve Racanovic | Posted in JDBC | Posted on 11:46 AM
0
Recently I was working on a timezone issue there the values returned on the daylight saving change over where incorrect. Here is the example and steps to reproduce this problem.
There sql script looks like:
connect / as sysdbaand the java looks like:
drop user timezoneuser cascade;
grant connect,resource to timezoneuser identified by timezoneuser;
connect timezoneuser/timezoneuser
create table jdbc_test (
sequence_id number(2),
cbt timestamp,
cbt_utc timestamp);
alter session set NLS_DATE_FORMAT = 'MM/DD/YYYY HH24:MI:SS';
alter session set NLS_TIMESTAMP_TZ_FORMAT ='MM/DD/YYYY HH24:MI:SS';
alter session set NLS_TIMESTAMP_FORMAT = 'MM/DD/YYYY HH24:MI:SS';
select * from nls_session_parameters;
insert into jdbc_test values(1,'04/05/2009 00:00:00','04/04/2009 13:00:00');
insert into jdbc_test values(2,'04/05/2009 01:00:00','04/04/2009 14:00:00');
insert into jdbc_test values(3,'04/05/2009 02:00:00','04/04/2009 15:00:00');
insert into jdbc_test values(4,'04/05/2009 02:00:00','04/04/2009 16:00:00');
insert into jdbc_test values(5,'04/05/2009 03:00:00','04/04/2009 17:00:00');
insert into jdbc_test values(6,'04/05/2009 04:00:00','04/04/2009 18:00:00');
insert into jdbc_test values(7,'04/05/2009 05:00:00','04/04/2009 19:00:00');
insert into jdbc_test values(8,'04/05/2009 06:00:00','04/04/2009 20:00:00');
insert into jdbc_test values(9,'04/05/2009 07:00:00','04/04/2009 21:00:00');
insert into jdbc_test values(10,'04/05/2009 08:00:00','04/04/2009 22:00:00');
insert into jdbc_test values(11,'04/05/2009 09:00:00','04/04/2009 23:00:00');
insert into jdbc_test values(12,'04/05/2009 10:00:00','04/05/2009 00:00:00');
insert into jdbc_test values(13,'04/05/2009 11:00:00','04/05/2009 01:00:00');
insert into jdbc_test values(14,'04/05/2009 12:00:00','04/05/2009 02:00:00');
insert into jdbc_test values(15,'04/05/2009 13:00:00','04/05/2009 03:00:00');
insert into jdbc_test values(16,'04/05/2009 14:00:00','04/05/2009 04:00:00');
insert into jdbc_test values(17,'04/05/2009 15:00:00','04/05/2009 05:00:00');
insert into jdbc_test values(18,'04/05/2009 16:00:00','04/05/2009 06:00:00');
insert into jdbc_test values(19,'04/05/2009 17:00:00','04/05/2009 07:00:00');
column seq format 999
column cbt format a20
column cbt_utc format a20
column difference format a30
select sequence_id as seq,cbt ,cbt_utc , cbt - cbt_utc as difference from jdbc_test;
package example;Upon running the java code using JDK 1.6 and 11g JDBC drivers (ojdbc6.jar), the following results are show:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Properties;
public class JDBCTimeStamp {
private void queryDatabase() {
Connection conn = null;
String DRIVER = "oracle.jdbc.driver.OracleDriver";
String connectionName = "jdbc:comp:env:sys";
String URL_NAME = "jdbc:oracle:thin:@celcsol1.us.oracle.com:1521:tarsr3";
String userName = new String("timezoneuser");
String password = new String("timezoneuser");
Properties prop = new Properties();
prop.put("user", userName);
prop.put("password", password);
prop.put("connectionName", connectionName);
try {
try {
Class.forName(DRIVER);
} catch (Exception e) {
System.out.println("Exception in Class.forName : " + e);
}
try {
conn = DriverManager.getConnection(URL_NAME, prop);
} catch (Exception e) {
System.out.println("Exception in creating the connection : " + e);
}
String sqlString = " SELECT SEQUENCE_ID,CBT,CBT_UTC" + " FROM JDBC_TEST ";
PreparedStatement ps = conn.prepareStatement(sqlString.toString());
ResultSet rs = null;
try {
ps = conn.prepareStatement(sqlString);
rs = ps.executeQuery();
String sequenceId = null;
Timestamp cbtTimeStamp = null;
Timestamp cbtUtcTimeStamp = null;
long longValueOfUtc;
long longValueOfCbt;
Date cbtDateValueFromLong;
Date utcDateValueFromLong;
System.out.println("ID \tCBT(local time) \t\t\tCBT_UTC(GMT) \t\t\tTime Difference");
while (rs.next()) {
sequenceId = rs.getString(1);
cbtTimeStamp = rs.getTimestamp(2);
cbtUtcTimeStamp = rs.getTimestamp(3);
longValueOfUtc = cbtUtcTimeStamp.getTime();
longValueOfCbt = cbtTimeStamp.getTime();
cbtDateValueFromLong = new Date(longValueOfCbt);
utcDateValueFromLong = new Date(longValueOfUtc);
System.out.println(sequenceId + "\t" + cbtDateValueFromLong + "\t\t" + utcDateValueFromLong + "\t\t" + ((longValueOfCbt - longValueOfUtc) / 3600000));
}
} finally {
if (ps != null)
ps.close();
if (rs != null)
rs.close();
}
} catch (Exception e) {
System.out.println("Exception :::" + e);
e.printStackTrace();
}
}
public static void main(String[] args) {
JDBCTimeStamp main = new JDBCTimeStamp();
main.queryDatabase();
}
}
ID CBT(local time) CBT_UTC(GMT) Time Difference
1 Sun Apr 05 00:00:00 EST 2009 Sat Apr 04 13:00:00 EST 2009 11
2 Sun Apr 05 01:00:00 EST 2009 Sat Apr 04 14:00:00 EST 2009 11
3 Sun Apr 05 02:00:00 EST 2009 Sat Apr 04 15:00:00 EST 2009 12
4 Sun Apr 05 02:00:00 EST 2009 Sat Apr 04 16:00:00 EST 2009 11
5 Sun Apr 05 03:00:00 EST 2009 Sat Apr 04 17:00:00 EST 2009 11
6 Sun Apr 05 04:00:00 EST 2009 Sat Apr 04 18:00:00 EST 2009 11
7 Sun Apr 05 05:00:00 EST 2009 Sat Apr 04 19:00:00 EST 2009 11
8 Sun Apr 05 06:00:00 EST 2009 Sat Apr 04 20:00:00 EST 2009 11
9 Sun Apr 05 07:00:00 EST 2009 Sat Apr 04 21:00:00 EST 2009 11
10 Sun Apr 05 08:00:00 EST 2009 Sat Apr 04 22:00:00 EST 2009 11
11 Sun Apr 05 09:00:00 EST 2009 Sat Apr 04 23:00:00 EST 2009 11
12 Sun Apr 05 10:00:00 EST 2009 Sun Apr 05 00:00:00 EST 2009 11
13 Sun Apr 05 11:00:00 EST 2009 Sun Apr 05 01:00:00 EST 2009 11
14 Sun Apr 05 12:00:00 EST 2009 Sun Apr 05 02:00:00 EST 2009 10
15 Sun Apr 05 13:00:00 EST 2009 Sun Apr 05 03:00:00 EST 2009 10
16 Sun Apr 05 14:00:00 EST 2009 Sun Apr 05 04:00:00 EST 2009 10
17 Sun Apr 05 15:00:00 EST 2009 Sun Apr 05 05:00:00 EST 2009 10
18 Sun Apr 05 16:00:00 EST 2009 Sun Apr 05 06:00:00 EST 2009 10
19 Sun Apr 05 17:00:00 EST 2009 Sun Apr 05 07:00:00 EST 2009 10
This because the table was not created with local timezone. The column in the database is TIMESTAMP - which holds a non timezone specified value.When jdbc extracts values from a TIMESTAMP column into a java.sql.Timestamp via the getTimestamp method, it ensures that the value, when printed, shows the same DATE/TIME as that stored in the database.
The correct way to create the table would be:
create table jdbc_test (Now that I am using 'WITH LOCAL TIME ZONE', I need change my java code to include the timezone in the connection like '((OracleConnection)conn).setSessionTimeZone("Australia/Victoria");'
sequence_id number(2),
cbt TIMESTAMP WITH LOCAL TIME ZONE,
cbt_utc TIMESTAMP WITH TIME ZONE);
So the java code would now look like:
...Now when I run the java class, the correct results are shown:
try {
conn = DriverManager.getConnection(URL_NAME, prop);
} catch (Exception e) {
System.out.println("Exception in creating the connection : " + e);
}
((OracleConnection)conn).setSessionTimeZone("Australia/Victoria");
String sqlString = " SELECT SEQUENCE_ID,CBT,CBT_UTC" + " FROM JDBC_TEST ";
PreparedStatement ps = conn.prepareStatement(sqlString.toString());
ResultSet rs = null;
...
ID CBT(local time) CBT_UTC(GMT) Time Difference
1 Sun Apr 05 01:00:00 EST 2009 Sat Apr 04 14:00:00 EST 2009 11
2 Sun Apr 05 02:00:00 EST 2009 Sat Apr 04 15:00:00 EST 2009 11
3 Sun Apr 05 02:00:00 EST 2009 Sat Apr 04 16:00:00 EST 2009 11
4 Sun Apr 05 02:00:00 EST 2009 Sat Apr 04 17:00:00 EST 2009 10
5 Sun Apr 05 03:00:00 EST 2009 Sat Apr 04 18:00:00 EST 2009 10
6 Sun Apr 05 04:00:00 EST 2009 Sat Apr 04 19:00:00 EST 2009 10
7 Sun Apr 05 05:00:00 EST 2009 Sat Apr 04 20:00:00 EST 2009 10
8 Sun Apr 05 06:00:00 EST 2009 Sat Apr 04 21:00:00 EST 2009 10
9 Sun Apr 05 07:00:00 EST 2009 Sat Apr 04 22:00:00 EST 2009 10
10 Sun Apr 05 08:00:00 EST 2009 Sat Apr 04 23:00:00 EST 2009 10
11 Sun Apr 05 09:00:00 EST 2009 Sun Apr 05 00:00:00 EST 2009 10
12 Sun Apr 05 10:00:00 EST 2009 Sun Apr 05 01:00:00 EST 2009 10
13 Sun Apr 05 11:00:00 EST 2009 Sun Apr 05 02:00:00 EST 2009 10
14 Sun Apr 05 12:00:00 EST 2009 Sun Apr 05 02:00:00 EST 2009 10
15 Sun Apr 05 13:00:00 EST 2009 Sun Apr 05 03:00:00 EST 2009 10
16 Sun Apr 05 14:00:00 EST 2009 Sun Apr 05 04:00:00 EST 2009 10
17 Sun Apr 05 15:00:00 EST 2009 Sun Apr 05 05:00:00 EST 2009 10
18 Sun Apr 05 16:00:00 EST 2009 Sun Apr 05 06:00:00 EST 2009 10
19 Sun Apr 05 17:00:00 EST 2009 Sun Apr 05 07:00:00 EST 2009 10