Reputation: 2300
I am trying to call a PL/SQL procedure (with the signature mentioned below) using JDBC. It takes a parameter of type TIMESTAMP WITH LOCAL TIME ZONE
. I am using Oracle 11g
and Oracle 12c Jdbc Driver Version 12.1.0.2
.
-- PURPOSE: Takes a timestamp and returns the formatted string
PROCEDURE deal_With_TimeStamp(intime TIMESTAMP WITH LOCAL TIME ZONE , outTimeString OUT VARCHAR2)
I have written a Java method a that calls the above procedure using JDBC. I eventually want to expose this method in a web service.
I am trying to understand how does one deal with a parameter of type TIMESTAMP WITH LOCAL TIME ZONE
in such scenarios.
From what I have read it seems like TIMESTAMP WITH LOCAL TIME ZONE
will have all Timestamps normalized based on the timezone in which the database instance operates.It will discard the client timezone information (when supplied) , once it is taken into account for the normalization process. So if the client requests for this info they will have to pass their timezone info again along with the request.
In such a case should I be accepting both timestamp and timezone from a web service client ? This way the info stored in the database will be accurate.
What happens when no timezone information is sent ? Is there a way to set the timezone for a Jdbc connection ? One can pass that to the database in absence of a client's timezone information.
Here is the relevant parts of my Java method that uses JDBC.
public void dealWithTimeStamp(Timestamp currentTimestampValue , String clientTimeZone)
{
Connection conn = null;
CallableStatement callStmt = null;
// Create a Database connection
conn = DriverManager.getConnection(DB_URL , DB_USER , DB_PWD);
// Create a query string
String callProc = "{call HR.EMP_PKG.deal_With_TimeStamp ( ? , ?) }";
// Create a Callable statement
callStmt = conn.prepareCall(callProc);
// Bind values to the IN parameter
callStmt.setTimestamp(1, currentTimestampValue , Calendar.getInstance(TimeZone.getTimeZone(clientTimeZone)));
// Register OUT parameters
callStmt.registerOutParameter(2, java.sql.Types.VARCHAR);
// Execute the Callable Statement
callStmt.execute();
// Retrieve the values from the OUT parameter
String curTimestampStr = callStmt.getString(2);
System.out.println("Current Timestamp : " + curTimestampStr);
}
Please note I have striped the try catch blocks , cleaning up of database resources for the sake of readability:
Upvotes: 0
Views: 1924
Reputation: 180201
From what I have read it seems like TIMESTAMP WITH LOCAL TIME ZONE will have all Timestamps normalized based on the timezone in which the database instance operates.It will discard the client timezone information (when supplied) , once the normalization is done.
Yes, the docs specify that this data type holds only the timestamp itself, not the timezone fields. It differs from TIMESTAMP
in that incoming values are converted from the client session time zone to the database time zone, and outgoing values are converted the other direction.
So if the client requests for this info they will have to pass their timezone info again along with the request.
It depends which "client" you mean. The web service host is client to the database. Its time zone is a property of the database session, so you don't have to explicitly "pass" it at all.
If you mean the web service client, however, AND if the web service client is expected to submit and receive timestamps relative to its own local time zone that must be interpreted as such, then the web service must convert timestamps between its client's zone and its own zone where the corresponding Oracle data type is TIMESTAMP WITH LOCAL TIME ZONE
. For that to work, the web service client must provide its time zone to the web service.
I would be uncomfortable with modifying the session properties of your database connections according to the characteristics of the web service client. That seems prone to errors. If you must deal with time zone issues then I suggest you approach the problem by standardizing the time zone:
ALTER SESSION
statement), once per connection, or it might do it in Java.TIMESTAMP
s, which are understood to be expressed in UTC. Then you don't need to worry about time zones at all (in combination with the previous).There is no standard sense of a connection time zone in JDBC, but connections do have generic "client properties". It is possible that the Oracle driver exposes the session time zone as such a property, in which case you could set it via Connection.setClientProperties()
. Again, I would personally avoid doing that based on web service client data, but I would be ok with doing it based on the web service host.
Upvotes: 1