Re: Timestamp vs. Java Date/Timestamp - Mailing list pgsql-jdbc
| From | Andreas Reichel |
|---|---|
| Subject | Re: Timestamp vs. Java Date/Timestamp |
| Date | |
| Msg-id | 1360119691.14635.25.camel@localhost Whole thread Raw |
| In response to | Re: Timestamp vs. Java Date/Timestamp (Dave Cramer <pg@fastcrypt.com>) |
| List | pgsql-jdbc |
Dave, my apologies for a rather long posting, perhaps I found what
happens:
//--------------------------------------------------------------------
// Step 1: hand over a Date calls setDate without Calendar, good:
case Types.DATE:
if (in instanceof java.sql.Date)
setDate(parameterIndex, (java.sql.Date)in);
else
{
java.sql.Date tmpd;
if (in instanceof java.util.Date) {
tmpd = new
java.sql.Date(((java.util.Date)in).getTime());
} else {
tmpd = connection.getTimestampUtils().toDate(null,
in.toString());
}
setDate(parameterIndex, tmpd);
}
break;
//--------------------------------------------------------------------
// Step 2: setDate calls setDate with Calendar==NULL:
public void setDate(int parameterIndex, java.sql.Date x) throws
SQLException
{
setDate(parameterIndex, x, null);
}
//--------------------------------------------------------------------
// Step 3: setDate with Calendar==NULL calls TimeStampUtils with empty
TimeZone:
public void setDate(int i, java.sql.Date d, java.util.Calendar cal)
throws SQLException
{
checkClosed();
if (d == null)
{
setNull(i, Types.DATE);
return;
}
if (connection.binaryTransferSend(Oid.DATE)) {
byte[] val = new byte[4];
TimeZone tz = cal != null ? cal.getTimeZone() : null;
connection.getTimestampUtils().toBinDate(tz, val, d);
preparedParameters.setBinaryParameter(i, val, Oid.DATE);
return;
}
if (cal != null)
cal = (Calendar)cal.clone();
// We must use UNSPECIFIED here, or inserting a
Date-with-timezone into a
// timestamptz field does an unexpected rotation by the server's
TimeZone:
//
// We want to interpret 2005/01/01 with calendar +0100 as
// "local midnight in +0100", but if we go via date it
interprets it
// as local midnight in the server's timezone:
// template1=# select '2005-01-01+0100'::timestamptz;
// timestamptz
// ------------------------
// 2005-01-01 02:00:00+03
// (1 row)
// template1=# select '2005-01-01+0100'::date::timestamptz;
// timestamptz
// ------------------------
// 2005-01-01 00:00:00+03
// (1 row)
bindString(i, connection.getTimestampUtils().toString(cal, d),
Oid.UNSPECIFIED);
}
//--------------------------------------------------------------------
// Step 4: when TimeZone is empty, the defaultTZ is used --> Why?! I
have a field which is WITHOUT Timezone for good reasons
public void toBinDate(TimeZone tz, byte[] bytes, Date value) throws
PSQLException {
long millis = value.getTime();
if (tz == null) {
tz = defaultTz;
}
millis += tz.getOffset(millis);
long secs = toPgSecs(millis / 1000);
ByteConverter.int4(bytes, 0, (int) (secs / 86400));
}
I would like to suggest to modify the toBinDate() and to add
tz.getOffset(millis) ONLY if a Timezone was specified, but not when
NULL:
public void toBinDate(TimeZone tz, byte[] bytes, Date value) throws
PSQLException {
long millis = value.getTime();
if (tz != null) {
millis += tz.getOffset(millis);
}
long secs = toPgSecs(millis / 1000);
ByteConverter.int4(bytes, 0, (int) (secs / 86400));
}
What do you think?
Best regards
Andreas
pgsql-jdbc by date: