Обсуждение: Unexpected value in Time object

Поиск
Список
Период
Сортировка

Unexpected value in Time object

От
"John Pile"
Дата:
I had a unit test fail for an ORM I'm writing.  I'm creating an object, persisting it in PostgreSQL 8.3 Windows using the postgresql-8.3-603.jdbc3.jar file retrieved from http://repo1.maven.org/maven2/postgresql/postgresql/8.3-603.jdbc3/, retrieving it back and comparing it to the original.
 
I created a java.sql.Time object with an inner "fastTime" value of 1, storing it in a "time with time zone" field using a PreparedStatement insert.  When I retrieve it, also via PreparedStatement, I notice that the "fastTime" value is not the value 1 that I expected, but 86400001 instead.  Although the toString() output looks the same for these two values, the check originalObject.equals(retrievedObject) returns false.
 
The JavaDoc for the java.sql.Time object states, 'The date components should be set to the "zero epoch" value of January 1, 1970 and should not be accessed.', which suggests that the driver's returned value is out of compliance.
 
Database ENCODING = 'WIN1252';  jdk1.6.0_06.  Feel free to contact me for any additional details.
 
John Pile
Sacramento, CA

Re: Unexpected value in Time object

От
Oliver Jowett
Дата:
John Pile wrote:

> I created a java.sql.Time object with an inner "fastTime" value of 1,
> storing it in a "time with time zone" field using a PreparedStatement
> insert.  When I retrieve it, also via PreparedStatement, I notice that
> the "fastTime" value is not the value 1 that I expected, but 86400001
> instead.  Although the toString() output looks the same for these two
> values, the check originalObject.equals(retrievedObject) returns false.

What is your JVM's default timezone?
What is the actual value stored in the DB?

-O

Re: Unexpected value in Time object

От
Kris Jurka
Дата:

On Tue, 28 Oct 2008, Oliver Jowett wrote:

> What is your JVM's default timezone?
> What is the actual value stored in the DB?
>

The attached test case shows the results of trying to store a Time object
with one millisecond in a timetz field with a America/Los_Angelese JVM
timezone.

Orig Time: 16:00:00
Orig TZ offset: 480
Orig millis: 1
Result as String: 16:00:00.001-08
Result Time: 16:00:00
Result TZ Offset: 480
Result millis: 86400001

Kris Jurka

Вложения

Re: Unexpected value in Time object

От
Oliver Jowett
Дата:
Kris Jurka wrote:
>
>
> On Tue, 28 Oct 2008, Oliver Jowett wrote:
>
>> What is your JVM's default timezone?
>> What is the actual value stored in the DB?
>>
>
> The attached test case shows the results of trying to store a Time
> object with one millisecond in a timetz field with a
> America/Los_Angelese JVM timezone.
>
> Orig Time: 16:00:00
> Orig TZ offset: 480
> Orig millis: 1
> Result as String: 16:00:00.001-08
> Result Time: 16:00:00
> Result TZ Offset: 480
> Result millis: 86400001

Ok, after looking at this some more, the driver seems to be doing the
correct thing.

"new Time(1)" is 1 Jan 1970 00:00:00.001 UTC
This is equivalent to 31 Dec 1969 16:00:00.001 -0800

So the original Time value is actually the one that is out of spec if
your default timezone is -0800, since it has a day/month/year that
doesn't match the "zero epoch" requirement of Time.

The result returned by the driver is 2 Jan 1970 00:00:00.001 which is
equivalent to 1 Jan 1970 16:00:00.001 -0800. This appears to be the
correct representation in a -0800 timezone.

The driver is actually constructing the returned Time from a Calendar
initialized like this (using an -0800 calendar)

>         cal.set(Calendar.HOUR_OF_DAY,  16);
>         cal.set(Calendar.MINUTE,       0);
>         cal.set(Calendar.SECOND,       0);
>         cal.set(Calendar.MILLISECOND,  1);
>         cal.set(Calendar.ERA,          GregorianCalendar.AD);
>         cal.set(Calendar.YEAR,         1970);
>         cal.set(Calendar.MONTH,        0);
>         cal.set(Calendar.DAY_OF_MONTH, 1);

which results in the 86400001ms value you see.

java.sql.Time is generally a horrible interface to work with, since it
depends so much on the default JVM timezone :( About all you can do with
it is work in the default timezone and use
getHours/getMinutes/getSeconds/getMilliseconds. The actual milliseconds
value used internally to represent a particular time will vary wildly
depending on the JVM's timezone.

-O