Subject Re: [Firebird-Java] Re: time zone problem
Author Roman Rokytskyy
> Great! Be sure to change both the encodeTimestamp() and
> decodeTimestamp() methods appropriately - both are using the local
> machine's time zone inappropriately (they should not use it at all).

I did the following test case:

Connection connection = getConnectionViaDriverManager();
try {
PreparedStatement stmt = connection.prepareStatement(
"INSERT INTO test_blob(id, ts_field) VALUES (?, ?)");

try {
Calendar calendar = Calendar.getInstance();

Timestamp ts = new Timestamp(calendar.getTimeInMillis());

stmt.setInt(1, 1);
stmt.setTimestamp(2, ts);

stmt.execute();

stmt.setInt(1, 2);
stmt.setTimestamp(2, ts, calendar);

stmt.execute();

stmt.setInt(1, 3);
stmt.setTimestamp(2, ts,
Calendar.getInstance(TimeZone.getTimeZone("UTC")));

stmt.execute();


Statement selectStmt = connection.createStatement();
try {
ResultSet rs = selectStmt.executeQuery(
"SELECT id, CAST(ts_field AS VARCHAR(35)), ts_field
FROM test_blob");

while(rs.next()) {
System.out.println("ID " + rs.getInt(1) +
", time_str '" + rs.getString(2) +
"', time ts " + rs.getTimestamp(3) +
", time ts_cal " + rs.getTimestamp(3,
Calendar.getInstance()));
}
} finally {
selectStmt.close();
}

} finally {
stmt.close();
}

} finally {
connection.close();
}

Idea is to write a timestamp into the database, first time without the
calendar and next time with the same calendar that generated the timestamp.
Then I read the data, not as timestamps, but I let server convert them.

ID 1, time_str '2004-07-29 23:31:19.4410', time ts 2004-07-29 23:31:19.441,
time ts_cal 2004-07-29 23:31:19.441

ID 2, time_str '2004-07-29 23:31:19.4410', time ts 2004-07-29 23:31:19.441,
time ts_cal 2004-07-29 23:31:19.441

ID 2, time_str '2004-07-30 00:31:19.4410', time ts 2004-07-30 00:31:19.441,
time ts_cal 2004-07-30 00:31:19.441

So, the most strange is the last result. I must admit that I do not
understand " With a a Calendar object, the driver can calculate the
timestamp taking into account a custom timezone. ".

If driver in the third case should have written '2004-07-29 22:31:19.4410'
(well, that's also the question, what do we do with the daylight saving
time?), then there's a mistake in driver about the sign. Should be

long time = value.getTime() +
(cal.getTimeZone().getRawOffset() -
Calendar.getInstance().getTimeZone().getRawOffset());

and

long time = value.getTime() -
(cal.getTimeZone().getRawOffset() -
Calendar.getInstance().getTimeZone().getRawOffset());

I just checked the Oracle driver - it simply ignores the calendar, data are
written into the database using the local time zone in all cases.

So, unless somebody points me to an explanation of how should I understand
those words from the specification, I will make no changes into the driver
at this point.

Ron, if this behavior of the driver is unacceptable for you, please either
convince me that there's a mistake in a sign, or you have to create a custom
version of the driver (it is relatively easy to buid).

BTW, we do have to take the local time zone into account, so your suggested
patch is not correct - it produces different results when used with and
without calendar. This happens due to the fact that there is one more local
time zone conversion happening, however I cannot use UTC there, because
there is no possibility to obtain a GMT time zone with activated daylight
saving time.

Roman