Subject Re: AW: AW: AW: AW: [Firebird-Java] Timezones
Author Roman Rokytskyy
> Propably you fixed some things after copy'n'paste?

right, sorry.

> This seems incorrect:
> java.util.Date timeDstLocal = localCalendar.getTime();
> This fixed the second line:
> java.util.Date timeDstLocal = localDstCalendar.getTime();

Correct.

> Resulting in:
> Date Sun Oct 25 02:30:00 CET 2009 : 1256434200741 == 1256434200741
> Date Sun Oct 25 03:30:00 CET 2009 : 1256437800773 == 1256437800773
> Date Sun Oct 25 02:30:00 CET 2009 : 1256434200741 == 1256437800741

Which means "true" for 1 and 2, "false" for 3, right?

> Also for future testing, I changed the first line to:
> Calendar localCalendar = new GregorianCalendar(
> TimeZone.getTimeZone( "CET" ) );
> (Which makes no difference "right now" and "right here".)

Ok.

> So the first line shows there in "usual" cases, jaybird works.

Yes.

> The second line shows my problem: There are cases, where the encoding is not
> bijective.

But which ones?

> I am unsure about the third line. I never used those "translation"
> functions. Are those required any more? (As the datetime class now has a
> Calenar in it's own...)

Yes, they are still required.

> Additionally I tried to understand the function of "isInvertTimeZone", which
> was used earlier in some places, but is not used any more except in
> FBStringField. Maybe this needs changes, too? But I don't even really
> understand it's usage.

Ups, I did not see it was also used in FBStringField, will correct it
there too. The isInvertTimeZone is no longer used at the moment. It was
introduced as result of long discussion about how to interpret the
calendar that is passed as parameter - as a source or as a destination
timezone.

The change I committed might break some applications, since only one
interpretation is used - the parameter is the destination calendar.
However, I did not hear about this parameter here for a long time, so if
there is somebody using it, he will definitely cry during beta/RC cycle.

> However this pushes me even more into forcing the interpretation of
> timestamps as UTC (or if really required any other timezone WITHOUT DST).
> If I think about it, with different timezones (or even in one timezone
> with/without DST) days don't start at the same point in time.
>
> But that's what I've timestamps always seen as - a notion of a fixed point
> in time. No matter what notation is used for printing...
> I guess a lot of other users do the same.

Current state of affairs with timestamps in Firebird is very similar to
the situation when people have their databases with NONE charset - as
long as your client and server have same settings and you do not change
anything, things work like a charm. If the timestamp in Firebird would
store timezone information as well, it would be like an UTF8 charset.

> As a failsafe solution, I am planning on placing the following to the
> startup class of my web application:
> System.setProperty( "user.timezone", "UTC" );
> if ( !TimeZone.getDefault().getID().equals( "UTC" ) )
> System.exit( 1 );
>
> A rather hard solution, but it ensures the correctness of database access.
> (Yes, I do NOT like this way either.)

Well, if that solves your issue, why not?

> Reading more in XSQLVAR I would like to suggest, not to call the following
> "every time":
> Calendar.getInstance().getTimeZone().getRawOffset()
> Instead have a static member calling this once using a static initializer.
> Calender.getInstance() is a rather expensive function.

At the moment it is obsolete. However there is another quite expensice
place:

Calendar c = (Calendar)cOrig.clone();

I need this for translation, but I do not know if I am allowed to modify
the specified calendar...

> I thought about implementing my own getTimestamp function but I cannot get a
> timestamp using ResultSet.getBytes().

That can be fixed - that is not a big issue here. I could extend the
FirebirdResultSet and FirebirdPreparedStatement interfaces with
getRawData(int) and setRawData methods.

> For my former idea to have a switch to always use UTC for persistence I have
> prepared some very simple converting functions [see attachment], which are
> by the way much faster than working with calendars. Internally Timestamp is
> a thin wrapper around Date and Date is a thin wrapper around long...

looks ok for the UTC case... but for the others...

> I just have no idea where to place such a switch and where to place the
> condition selection between the default implementations and the UTC
> implementation.

What about adding "parallel" methods starting from the
FirebirdPreparedStatement and FirebirdResultSet, additional setters and
getters for FBDateField, FBTimeField and FBTimestampField, which then
call your extensions of XSQLVAR code? That could be added to Jaybird.

Then two possibilities exist - one is to add some connection parameter
that would make the "normal" setTimestamp methods to delegate to
setTimestampUTC, or create a thin proxy layer that would do this
delegation transparently. I prefer latter.

Roman