I've since discovered that this issue is somehow related to the JDK 1.4's
java.sql.Timestamp object. Under JDK 1.3, it appears to work as advertised,
but this is not true under 1.4. I don't think this is a JDBC driver issue
as it's giving me the right time, but when I compute the time from the
java.sql.Timestamp object, I get different values depending on the JDK.
For clarity, both JDKs were tested under RedHat Linux using Sun's JDK
1.3.1_07 and Sun's JDK 1.4.1_02.
Here is a quote from the Javadocs on java.sql.Timestamp, and it's the same
wording in the 1.3 and 1.4 javadocs:
"Only integral seconds are stored in the java.util.Date component. The
fractional seconds - the nanos - are separate. The getTime method will
return only integral seconds. If a time value that includes the fractional
seconds is desired, you must convert nanos to milliseconds (nanos/1000000)
and add this to the getTime value."
Why a Timestamp has this odd functionality when it's a subclass of
java.util.Date is beyond me, but they even caution us with the following:
"Due to the differences between the Timestamp class and the java.util.Date
class mentioned above, it is recommended that code not view Timestamp values
generically as an instance of java.util.Date. The inheritance relationship
between Timestamp and java.util.Date really denotes implementation
inheritance, and not type inheritance."
This implies the following code to convert a simple java.sql.Timestamp into
a java.util.Date:
// where 't' is a java.sql.Timestamp object
java.util.Date date = new java.util.Date( t.getTime() +
(t.getNanos()/1000000) );
But, when you read the 1.3 javadocs, there's no mention of the method
getTime() -- and it's only implied through it's inheritance from Date (again
making one wonder why the subclassing only not to allow a Timestamp to be a
Date!).
However, the 1.4 javadocs now have the method getTime() included, presumably
a specialization of the Date's version, and it's documentation reads just
like Date.getTime():
public long getTime()
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
represented by this Timestamp object.
So, what's happening now under JDK 1.4 is that date like April 23, 2003
10:45:58.688 AM PST (long value of 1051119957688) is being treated such that
getTime() returns the full long 1051119957688, and getNanos() returns
688,000,000, so when the addition occurs as before, I'll get a number
counting the milliseconds twice.
Under JDK 1.3 getTime() returns 1051119957000 and getNanos() returns
688,000,000, so the addition of those two values results in the correct time
including milliseconds.
Has anybody else seen this? Is this a Linux version issue or has the
meaning of getTime() actually changed in the two JDKs?
Thanks,
David
----- Original Message -----
From: "David Wall" <d.wall@computer.org>
To: "pgsql-jdbc" <pgsql-jdbc@postgresql.org>
Sent: Wednesday, April 23, 2003 12:17 PM
Subject: [JDBC] PG 7.3.2 JDBC timestamp problems between JDK 1.3.1 and 1.4.1
> I'm using the same JDBC driver (build 109 for JDK 1.3 under PG 7.3.2) and
I
> get two different results when querying a TIMESTAMP field.
>
> >From psql, here is what we have for that particular column in my table:
>
> Column | Type | Modifiers
> -----------------------------+--------------------------+-----------
> sent_timestamp | timestamp with time zone | not null
>
> ...and here is what it reports when I run the query:
>
> sent_timestamp
> ----------------------------
> 2003-04-23 10:45:57.688-07
>
>
> When running my code under JDK 1.3.1_07 on Linux using that JDBC driver, I
> get the following values for my program:
> As a string: Apr 23, 2003 10:45:57 AM
> As a long: 1051119957688
>
> That would appear to be correct, and mirrors the values shown in psql's
> select.
>
> But when I run my same program under JDK 1.4.1_07, the values are slightly
> different with:
> As a string: Apr 23, 2003 10:45:58 AM
> As a long: 1051119958376
>
> This appears to be incorrect and doesn't match psql's select value (note
> that this doesn't even get the seconds correct as it's different by 688
> milliseconds). I generally don't care about the millisecond accuracy
> (though I ought to be able to!), but in this case, it results in a
different
> value as of the seconds, and that's a big problem for me since the
timestamp
> seconds is used in a digital signature which won't compute with different
> values.
>
> Is there any idea on why the same driver would give different values
> depending on whether it was run under JDK 1.3 versus 1.4?
>
> Thanks,
> David
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/docs/faqs/FAQ.html