JDBC Driver and timezones

Lists: pgsql-jdbc
From: Thomas Kellerer <spam_eater(at)gmx(dot)net>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: JDBC Driver and timezones
Date: 2010-05-18 09:29:37
Message-ID: hstmm1$96v$1@dough.gmane.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Hi,

I have a little problem regarding timezones in the JDBC driver.

I have a locally installed Postgres server (PG 8.4.3 on Windows XP), so there is no difference between the timezone of the server and the client application.

When I run the following in psql:

select current_time, localtime;

I get the following output:

timetz | time
-----------------+--------------
11:15:30.464+02 | 11:15:30.464
(1 row)

which is fine.

Now when I run the same statement through JDBC :

Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select current_time, localtime");
if (rs.next())
{
System.out.println("current_time: " + rs.getTime(1).toString());
System.out.println("localtime: " + rs.getTime(2).toString());
}

I get the following output:

current_time: 10:18:49
localtime: 11:18:49

My expectation would have been to get the same display, but the current_time is one our off, which seems to be a problem with the daylight savings time.I

The timezone for my computer is setup correctly (the clock is showing the correct time, and apparently psql has the correct time as well)

The display from Java only works if I explicitely set the timezone when starting the JVM using -Duser.timezone=GMT+2

Is this a Java/JDK problem, a Windows problem or a driver problem?
I'm using JDK 1.6.0_18

Regards
Thomas


From: Oliver Jowett <oliver(at)opencloud(dot)com>
To: Thomas Kellerer <spam_eater(at)gmx(dot)net>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-18 12:37:39
Message-ID: 4BF28A13.9050002@opencloud.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Thomas Kellerer wrote:

> My expectation would have been to get the same display, but the
> current_time is one our off, which seems to be a problem with the
> daylight savings time.

The JDK and the postgres server use independent timezone databases.
Perhaps they just have different daylight savings rules.

-O


From: Thomas Kellerer <spam_eater(at)gmx(dot)net>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-18 16:55:06
Message-ID: hsugp9$gmh$1@dough.gmane.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Oliver Jowett wrote on 18.05.2010 14:37:
> Thomas Kellerer wrote:
>
>> My expectation would have been to get the same display, but the
>> current_time is one our off, which seems to be a problem with the
>> daylight savings time.
>
> The JDK and the postgres server use independent timezone databases.
> Perhaps they just have different daylight savings rules.
>
Sounds a bit strange given the fact that the German DST rules haven't been changed for ages...

Regards
Thomas


From: "Carsten Klein" <carsten(dot)klein(at)axn-software(dot)de>
To: "Thomas Kellerer" <spam_eater(at)gmx(dot)net>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-18 21:35:35
Message-ID: e979a6b62190fc12d767b1aa28fb724e.squirrel@webmail.axn-software.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc


Hi,

actually, your application server is not using the system's default
timezone, see the configuration of your server.

I actually have filed this in the past as either bug or enhancement.
Basically the problem lies within the PGSQL JDBC driver, which will use
the application server's timezone setting when interpreting the data in
the timezone enabled table attributes.

In order to overcome this problem, I have adjusted a db layer that we are
using in the OSS VerA.Web project so that it will use proxies for the most
relevant objects (resultset and so on) that then will just drop the
timezone information in the data received from the database, so that when
instantiating the datetime object in the application server, it will
automatically take over the configured timezone. That way, you will
experience no timeshift, whatsoever.

See
https://evolvis.org/scm/viewvc.php/tags/tarent-database-1.5.4verawebpl3/src/main/java/de/tarent/dblayer/engine/proxy/?root=tarentdatabase

for more information.

Regards,

Carsten

--

Carsten Klein
Mobil +491 577 666 256 5
carsten(dot)klein(at)axn-software(dot)de

axn software UG (haftungsbeschränkt)
Wipperfürther Str. 278, 51515 Kürten

Geschäftsführung Carsten Klein
HRB 66732, Gerichtsstand Amtsgericht Bergisch Gladbach
Steuernr. 204/5740/0835, USt-IdNr. DE 266 540 939

Telefon +492 268 801 285, Telefax +492 268 801 285
www.axn-software.de, info(at)axn-software(dot)de


From: Thomas Kellerer <spam_eater(at)gmx(dot)net>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-18 22:01:29
Message-ID: hsv2np$qhq$1@dough.gmane.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Carsten Klein wrote on 18.05.2010 23:35:

> actually, your application server is not using the system's default
> timezone, see the configuration of your server.

The timezone is correct. The DST information seems to be "broken".

Besides: I'm not using an application server. It's a Swing application that retrieves the data via JDBC

The output from my initial post was from a very simply main() class, only runs that single statement I posted in my initial post.
Even then it only works when I manually set user.timezone=GMT+2

And for the test case the client application _and_ Postgres were running on the same physical machine. So the JVM (and thus the JDBC driver) and Postgres should use the same timezone information from my Windows.

When I output the value of user.timezone (when not setting it manually) it does report the correct one: Europe/Berlin, but for some reason it does not apply the DST settings correctly.

> In order to overcome this problem, I have adjusted a db layer that we are
> using in the OSS VerA.Web project so that it will use proxies for the most
> relevant objects (resultset and so on) that then will just drop the
> timezone information in the data received from the database, so that when
> instantiating the datetime object in the application server, it will
> automatically take over the configured timezone. That way, you will
> experience no timeshift, whatsoever.
>
> See
> https://evolvis.org/scm/viewvc.php/tags/tarent-database-1.5.4verawebpl3/src/main/java/de/tarent/dblayer/engine/proxy/?root=tarentdatabase

Thanks for the link, but as I said: this is a Swing application that directly connects to the Postgres server.
But I'm curious: why didn't you simply change the timezone for the JVM running your appserver?

Regards
Thomas


From: Oliver Jowett <oliver(at)opencloud(dot)com>
To: Thomas Kellerer <spam_eater(at)gmx(dot)net>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-19 00:00:21
Message-ID: 4BF32A15.8010502@opencloud.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Thomas Kellerer wrote:

> And for the test case the client application _and_ Postgres were running
> on the same physical machine. So the JVM (and thus the JDBC driver) and
> Postgres should use the same timezone information from my Windows.

The JVM has its own separate timezone database. It does not use the
OS-provided timezone data in general.

-O


From: Thomas Kellerer <spam_eater(at)gmx(dot)net>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-19 06:17:22
Message-ID: hsvvp4$4lq$1@dough.gmane.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Oliver Jowett, 19.05.2010 02:00:
> Thomas Kellerer wrote:
>
>> And for the test case the client application _and_ Postgres were
>> running on the same physical machine. So the JVM (and thus the JDBC
>> driver) and Postgres should use the same timezone information from my
>> Windows.
>
> The JVM has its own separate timezone database. It does not use the
> OS-provided timezone data in general.
>

Thanks.

Yes that's what I assume as well. But I'm still surprised the JVM doesn't apply the DST settings correctly (the timezone *is* correct)

Regards
Thomas


From: Thomas Kellerer <spam_eater(at)gmx(dot)net>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-19 06:43:40
Message-ID: ht01ae$9oq$1@dough.gmane.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Thomas Kellerer, 19.05.2010 08:17:
>>> And for the test case the client application _and_ Postgres were
>>> running on the same physical machine. So the JVM (and thus the JDBC
>>> driver) and Postgres should use the same timezone information from my
>>> Windows.
>>
>> The JVM has its own separate timezone database. It does not use the
>> OS-provided timezone data in general.
>>
>
> Yes that's what I assume as well. But I'm still surprised the JVM
> doesn't apply the DST settings correctly (the timezone *is* correct)
>

Hmm, I just tested this and apparently my assumption is wrong (Java *is* using the correct DST setting)

When I run:

System.out.println("DST active: " + TimeZone.getDefault().useDaylightTime());
System.out.println("DST delta: " + TimeZone.getDefault().getDSTSavings());

it correctly shows me that the JDK knows that DST is active and that it should add one hour
(without setting a timezone when starting the JVM)

So either that information is not used by the JDK, or there is something going on in the driver.

Thomas


From: "Marc Mamin" <M(dot)Mamin(at)intershop(dot)de>
To: "Thomas Kellerer" <spam_eater(at)gmx(dot)net>, <pgsql-jdbc(at)postgresql(dot)org>
Subject: Re: JDBC Driver and timezones
Date: 2010-05-19 07:18:42
Message-ID: C4DAC901169B624F933534A26ED7DF31034BB629@JENMAIL01.ad.intershop.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Hello,

I guess the issue is a logical one.
java Time has basically no date associated and rs.getTime(n) hence does not expect a timezone information as with PG current_time.
Maybe there is a hidden fallback to rs.getTime(n, Calendar) ?

HTH,

Marc Mamin

java Time:
A thin wrapper around the java.util.Date class that allows the JDBC API to identify this as an SQL TIME value.
The Time class adds formatting and parsing operations to support the JDBC escape syntax for time values.

!! The date components should be set to the "zero epoch" value of January 1, 1970 and should not be accessed.

-----Original Message-----
From: pgsql-jdbc-owner(at)postgresql(dot)org [mailto:pgsql-jdbc-owner(at)postgresql(dot)org] On Behalf Of Thomas Kellerer
Sent: Mittwoch, 19. Mai 2010 08:44
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: [JDBC] JDBC Driver and timezones

Thomas Kellerer, 19.05.2010 08:17:
>>> And for the test case the client application _and_ Postgres were
>>> running on the same physical machine. So the JVM (and thus the JDBC
>>> driver) and Postgres should use the same timezone information from my
>>> Windows.
>>
>> The JVM has its own separate timezone database. It does not use the
>> OS-provided timezone data in general.
>>
>
> Yes that's what I assume as well. But I'm still surprised the JVM
> doesn't apply the DST settings correctly (the timezone *is* correct)
>

Hmm, I just tested this and apparently my assumption is wrong (Java *is* using the correct DST setting)

When I run:

System.out.println("DST active: " + TimeZone.getDefault().useDaylightTime());
System.out.println("DST delta: " + TimeZone.getDefault().getDSTSavings());

it correctly shows me that the JDK knows that DST is active and that it should add one hour
(without setting a timezone when starting the JVM)

So either that information is not used by the JDK, or there is something going on in the driver.

Thomas

--
Sent via pgsql-jdbc mailing list (pgsql-jdbc(at)postgresql(dot)org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-jdbc


From: Kris Jurka <books(at)ejurka(dot)com>
To: Thomas Kellerer <spam_eater(at)gmx(dot)net>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-19 07:27:51
Message-ID: alpine.BSO.2.00.1005190257480.27053@leary.csoft.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

On Wed, 19 May 2010, Thomas Kellerer wrote:

> System.out.println("DST active: " + TimeZone.getDefault().useDaylightTime());
> System.out.println("DST delta: " + TimeZone.getDefault().getDSTSavings());
>
> it correctly shows me that the JDK knows that DST is active and that it
> should add one hour
> (without setting a timezone when starting the JVM)

I think the problem is that the Java specification for java.sql.Time
requires that the date portion be filled in with 1970-01-01. So when
trying to determine the zone shift to apply when printing it out, it is
checking with that date instead of today's date as you are expecting.

When reading a timetz value in, we don't need to determine what the zone
shift is, it's explicit, so in this case we shift by the explicit DST
amount. When printing it back out, the original zone offset has been
discarded and we shift by the non-DST amount because the date 1970-01-01
doesn't use DST. I think we'd like to be able to override the
getTimezoneOffset value for the Time object, but there's no easy way to do
that without creating our own PgTime object.

Kris Jurka


From: Thomas Kellerer <spam_eater(at)gmx(dot)net>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: JDBC Driver and timezones
Date: 2010-05-19 08:19:15
Message-ID: ht06tl$ueh$1@dough.gmane.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-jdbc

Kris Jurka, 19.05.2010 09:27:
>> System.out.println("DST active: " +
>> TimeZone.getDefault().useDaylightTime());
>> System.out.println("DST delta: " +
>> TimeZone.getDefault().getDSTSavings());
>>
>> it correctly shows me that the JDK knows that DST is active and that
>> it should add one hour
>> (without setting a timezone when starting the JVM)
>
> I think the problem is that the Java specification for java.sql.Time
> requires that the date portion be filled in with 1970-01-01. So when
> trying to determine the zone shift to apply when printing it out, it is
> checking with that date instead of today's date as you are expecting.
>
> When reading a timetz value in, we don't need to determine what the zone
> shift is, it's explicit, so in this case we shift by the explicit DST
> amount. When printing it back out, the original zone offset has been
> discarded and we shift by the non-DST amount because the date 1970-01-01
> doesn't use DST. I think we'd like to be able to override the
> getTimezoneOffset value for the Time object, but there's no easy way to
> do that without creating our own PgTime object.
>

Thanks for the detailed answer.
For the time being I can workaround this by explicitely setting the timezone.

It might be worth mentioning in the driver's documentation though.

Regards
Thomas