tags:

views:

1453

answers:

4

I have a JDBC Date column, which if a i use getDate is get the 'date' part only 02 Oct 2009 but if i use getTimestamp i get the full 'date' 02 Oct 2009 13:56:78:890. This is excatly what i want.

However the 'date' returned by getTimestamp 'ignores' the GMT values, suppose date; 02 Oct 2009 13:56:78:890, i end up getting 02 Oct 2009 15:56:78:890

My date was saved as a +2GMT date on the database but the application server is on GMT i.e 2hrs behind

How can still get my date as is, 02 Oct 2009 13:56:78:890

Edit

I get the date +2 on the client side that is on GMT +2

A: 

You should be aware that java.util.Date (and also java.sql.Date and java.sql.Timestamp, which are subclasses of java.util.Date) don't know anything about timezones, or rather, they are always in UTC.

java.util.Date and its subclasses are nothing more than a container for a "number of milliseconds since 01-01-1970, 12:00 AM UTC" value.

To display a date in a specific timezone, convert it to a string by using a java.text.DateFormat object. Set the timezone on that object by calling the setTimeZone() method. For example:

Date date = ...;  // wherever you get this from

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

// Make the date format show the date in CET (central European time)
df.setTimeZone(TimeZone.getTimeZone("CET"));

String text = df.format(date);
Jesper
+1  A: 

That's the difference between Timestamp and other temporal types in MySQL. Timestamp is saved as Unix time_t in UTC but other types store date/time literally without zone information.

When you call getTimestamp(), MySQL JDBC driver converts the time from GMT into default timezone if the type is timestamp. It performs no such conversion for other types.

You can either change the column type or do the conversion yourself. I recommend former approach.

ZZ Coder
keyword **converts**, which is why i get the +2 hours
n002213f
I'm confused, if conversion is working properly, shouldn't he seeing a date that is 2 hours less, instead of more?
wds
@wds - check my edit and response
n002213f
this was close enough and guided me to my final solution
n002213f
A: 
n002213f
+1  A: 

I ran into a similar problem the other day where the time component was being truncated from some dates.

We narrowed it down to a difference in Oracle Driver versions.

On Oracle's FAQ there is a section about this:


select sysdate from dual; ...while(rs.next())

Prior to 9201, this will return: getObject for sysdate : java.sql.Timestamp <<<< getDate for sysdate : java.sql.Date getTimetamp for sysdate : java.sql.Timestamp

As of 9201 onward the following will be returned

getObject for sysdate : java.sql.Date <<<<< getDate for sysdate :java.sql.Date >> no change getTimetamp for sysdate :java.sql.Timestamp >> no change

Note: java.sql.Date has no time portion whereas java.sql.Timestamp does.

With this change in Datatype mapping, some application will fail and/or generate incorrect results when JDBC driver is upgraded from 8i/ 9iR1 to 920x JBDC driver. To maintain compatibility and keep applications working after upgrade, a compatibility flag was Provided. Developers now have some options:

  1. Use oracle.jdbc.V8Compatible flag.

JDBC Driver does not detect database version by default. To change the compatibility flag for handling TIMESTAMP datatypes, connection property

'oracle.jdbc.V8Compatible'

can be set to 'true' and the driver behaves as it behaved in 8i, 901x, 9 200 (with respect to TIMESTAMPs).

By default the flag is set to 'false'. In OracleConnection constructor the driver obtains the server version and set the compatibility flag appropriately.

java.util.Properties prop=newjava.util.Properties(); 
prop.put("oracle.jdbc.V8Compatible","true"); 
prop.put("user","scott"); 
prop.put("password","tiger");
String url="jdbc:oracle:thin:@host:port:sid"; 
Connection conn = DriverManager.getConnection(url,prop);

With JDBC 10.1.0.x, instead of the connection property, the following system property can be used: java -Doracle.jdbc.V8Compatible=true.....Note: This flag is a client only flag that governs the Timestamp and Date mapping. It does not affect any Database feature.

'2. Use set/getDate and set/getTimestamp when dealing with Date and TimeStamp column data type accordingly.

9i server supports both Date and Timestamp column types DATE is mapped to java.sql.Date and TIMESTAMP is mapped to java.sql.Timestamp.


So for my situation, I had code like this:

import java.util.Date; 
Date d = rs.getDate(1);

With 9i I was getting a java.sql.Timestamp (which is a subclass of java.util.Date) so everything was groovy and I had my hours and minutes.

But with 10g, the same code now gets a java.sql.Date (also a subclass of java.util.Date so it still compiles) but the HH:MM is TRUNCATED!!.

The 2nd solution was pretty easy for me - just replace the getDate with getTimestamp and you should be OK. I guess that was a bad habit.

Jim P
thanks for that one Jim, most appreciated.
n002213f