You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@isis.apache.org by Kevin Meyer - KMZ <ke...@kmz.co.za> on 2011/03/27 17:39:01 UTC

Best place for application default timezone?

I'm looking at defining an "application" timezone, but I'm not sure 
where the best place is to define it.

org.apache.isis.runtimes.dflt.runtime.context.IsisContext seems like a 
good start. The IsisSession has a getUserProfile, which has a 
Localisation interface (which exposes a getTimeZone() method), but 
this would possibly be the place to keep a per-user timezone, not an 
application-level timezone [is this an artificial distinction?].

My goal is replace all occurrences of:
	"cal.setTimeZone(UTC_TIME_ZONE);"
with a configurable
	"cal.setTimeZone(IsisContext.getTimeZone());"

Likewise, the datastore implementations could provide their own 
getTimeZone() method, which defines the datastore's internal 
timezone.

Comments? Suggestions?

This has an impact on all tests (for example), as it introduces a new 
dependency into those classes that currently just create a UTC 
timezone.

Currently affected ( a quick search for etc/UTC):
./applib/src/main/java/org/apache/isis/applib/fixtures/FixtureClock.java
./applib/src/main/java/org/apache/isis/applib/value/Date.java
./applib/src/main/java/org/apache/isis/applib/value/Time.java
./applib/src/test/java/org/apache/isis/applib/value/TestClock.java
./core/progmodel/src/main/java/org/apache/isis/core/progmodel/facets/value/ValueSemanticsProviderAbstractTemporal.java
./core/progmodel/src/test/java/org/apache/isis/core/progmodel/facets/value/JavaSqlDateValueSemanticsProviderTest.java
./core/progmodel/src/test/java/org/apache/isis/core/progmodel/facets/value/JavaUtilDateValueSemanticsProviderTest.java
./core/progmodel/src/test/java/org/apache/isis/core/progmodel/facets/value/TestClock.java
./runtimes/dflt/objectstores/sql/tests-common/src/main/java/org/apache/isis/runtimes/dflt/objectstores/sql/common/SqlIntegrationTestCommon.java
./viewer/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/parsers/DateParser.java



Re: Best place for application default timezone?

Posted by Mark Struberg <st...@yahoo.de>.
+1 for internally using UTC only + converting to the respective user timezone.

LieGrue,
strub

--- On Sun, 3/27/11, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:

> From: Kevin Meyer - KMZ <ke...@kmz.co.za>
> Subject: Re: Best place for application default timezone?
> To: Isis-dev@incubator.apache.org
> Date: Sunday, March 27, 2011, 7:41 PM
> Hi Dan, 
> 
> within...
> 
> > > I'm looking at defining an "application"
> timezone, but I'm not sure
> > > where the best place is to define it.
> > >
> > That does seem like a useful concept.
> > 
> > > ... The IsisSession has a getUserProfile, which
> has a
> > > Localisation interface (which exposes a
> getTimeZone() method), but
> > > this would possibly be the place to keep a
> per-user timezone, not an
> > > application-level timezone [is this an artificial
> distinction?].
> > >
> > I think we *should* distinguish the two.
> > 
> > As per the previous thread, I think that there are
> three clocks:
> > 
> > - user timezone
> > - app timezone (where the appserver runs)
> > - db timezone.
> > 
> > However, as your other thread said, java.sql.Date is
> meant to be a UTC 
> > date.  So that simplifies things somewhat.
> > 
> > - user timezone
> > - app timezone (where the appserver runs)
> > - db timezone = UTC
> 
> This is where I have found problems. The current issue
> *seems* to be 
> that when cal.getTime() is used to create a java.util.Date,
> it 
> automatically converts from cal's timezone to the system
> default.
> 
> > Moreover, some of these "cal" occur in the applib,
> which MUST 
> > NOT reference the runtime (IsisContext).
> > ~~~
> > As - again - you did note in your other thread, what's
> required is some 
> > sort of translation layer between the user timezone
> and UTC, and - again 
> > as you point out -
> org.apache.isis.adapters.Localization interface has 
> > this.  This was something that Rob introduced
> about a month or go.
> > 
> > I've just taken a look at how this interface is used
> it, it would seem 
> > to be used by ValueSemanticsProvider's
> Parser#displayTitleOf.    In 
> > other words, this *is* the translation layer that you
> speak of (a Parser 
> > is used to render every value of every property of
> every object).
> 
> Is this layer used bi-di, i.e. all user text goes through
> it before getting to 
> the app layer, and vice versa? 
> 
> > ~~~
> > Putting all the above together:
> > 
> > - let's agree that app server time = DB server time =
> UTC
> 
> I don't like this, because it means that in most of the
> simple 
> applications (where the app, users and DB are all in the
> same (non-
> UTC) timezone), every date/time will be shunted back and
> forth 
> through timezone translations.
> 
> Also, are you suggesting that when Isis fires up, it
> automatically sets 
> the system default timezone to UTC? My gut feeling is that
> this would 
> be necessary for cal.getTime() to operate properly when
> used to 
> create a date.
> 
> Viz: I have a database field (of type DATE) which returns
> "2011-04-
> 08", or, in full, "2011-04-08T00:00:00.000+0200".
> 
> First question, what does +0200 mean, for a date, anyway?
> 
> Second question, since java.sql.Date is assumed to be UTC,
> why 
> does "rs.getDate(columnName);" return the "+0200" timezone?
> 
> Because the system default timezone is GMT+0200 on my
> machine!
> 
> Continuing: This java.util.Date date is used (in
> applib.value.Date) to 
> create a new internal java.util.date with the following:
> (note the 
> comment!)
> 
>     public Date(final java.util.Date date) {
>         final Calendar cal =
> Calendar.getInstance();
>        
> cal.setTimeZone(UTC_TIME_ZONE);
> 
>         // TODO when input date is BST
> then then date value ends up as 
> the previous day
>         cal.setTime(date);
>         cal.set(Calendar.HOUR, 0);
>         cal.set(Calendar.MINUTE, 0);
>         cal.set(Calendar.SECOND, 0);
>         cal.set(Calendar.MILLISECOND,
> 0);
>         this.date = cal.getTime();
>     }
> 
> The "this.date" shows up in my system as:
> "Thu Apr 07 14:00:00 SAST 2011" with a cdate of 
> "2011-04-07T14:00:00.000+0200"
> 
> It has moved back a day. And what is with the 14h00 time?
> It's a 
> *date* the time is supposed to be empty!
> 
> If I set the system default timezone to GMT-0200, then the
> end resut 
> reads "2011-04-06T22:00:00.000-0200"
> 
> I think java has messed up - java.util.Date has no explicit
> timezone (it 
> is managed via Calendar), but it has an implicit timezone
> based on the 
> system default?
> 
> I would like to look into Joda Time and see if they've
> fixed this issue.
> 
> > - the user timezone is as defined by Localization
> > - the UI layer - by way of Parser interface - always
> (or should always) 
> > render the time with respect to the user's
> localization
> > - we therefore shouldn't need any changes to the
> codebase.
> > 
> > Where we currently have failing tests, it's probably
> because they are 
> > evaluating the date/time with respect to the timezone
> in which they are 
> > running, rather than UTC.  In other words, the
> tests are at fault.
> 
> This is still possible (almost certain, in fact). I'm
> looking into it...
> 
> > ~~~
> > Now, the above analysis may well be wrong, I haven't
> thought about this 
> > as much as you, but that's my initial stab on the
> matter.
> > 
> > Let's keep this thread open until we get to a design
> that we are all 
> > happy with and understand.
> 
> One argument that I have against setting the system default
> (or the 
> app & datastore default) to UTC is that when looking at
> the raw data, 
> in a simple 1-timezone config, I want to see the values
> that I specified 
> (e.g. new applib.value.Date(2011, 4, 8), when written to
> the database, 
> appears as 2011-04-08 in my database browser).
> 
> 
> 


      

Re: Best place for application default timezone?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Hi Dan, 

within...

> > I'm looking at defining an "application" timezone, but I'm not sure
> > where the best place is to define it.
> >
> That does seem like a useful concept.
> 
> > ... The IsisSession has a getUserProfile, which has a
> > Localisation interface (which exposes a getTimeZone() method), but
> > this would possibly be the place to keep a per-user timezone, not an
> > application-level timezone [is this an artificial distinction?].
> >
> I think we *should* distinguish the two.
> 
> As per the previous thread, I think that there are three clocks:
> 
> - user timezone
> - app timezone (where the appserver runs)
> - db timezone.
> 
> However, as your other thread said, java.sql.Date is meant to be a UTC 
> date.  So that simplifies things somewhat.
> 
> - user timezone
> - app timezone (where the appserver runs)
> - db timezone = UTC

This is where I have found problems. The current issue *seems* to be 
that when cal.getTime() is used to create a java.util.Date, it 
automatically converts from cal's timezone to the system default.

> Moreover, some of these "cal" occur in the applib, which MUST 
> NOT reference the runtime (IsisContext).
> ~~~
> As - again - you did note in your other thread, what's required is some 
> sort of translation layer between the user timezone and UTC, and - again 
> as you point out - org.apache.isis.adapters.Localization interface has 
> this.  This was something that Rob introduced about a month or go.
> 
> I've just taken a look at how this interface is used it, it would seem 
> to be used by ValueSemanticsProvider's Parser#displayTitleOf.    In 
> other words, this *is* the translation layer that you speak of (a Parser 
> is used to render every value of every property of every object).

Is this layer used bi-di, i.e. all user text goes through it before getting to 
the app layer, and vice versa? 

> ~~~
> Putting all the above together:
> 
> - let's agree that app server time = DB server time = UTC

I don't like this, because it means that in most of the simple 
applications (where the app, users and DB are all in the same (non-
UTC) timezone), every date/time will be shunted back and forth 
through timezone translations.

Also, are you suggesting that when Isis fires up, it automatically sets 
the system default timezone to UTC? My gut feeling is that this would 
be necessary for cal.getTime() to operate properly when used to 
create a date.

Viz: I have a database field (of type DATE) which returns "2011-04-
08", or, in full, "2011-04-08T00:00:00.000+0200".

First question, what does +0200 mean, for a date, anyway?

Second question, since java.sql.Date is assumed to be UTC, why 
does "rs.getDate(columnName);" return the "+0200" timezone? 
Because the system default timezone is GMT+0200 on my machine!

Continuing: This java.util.Date date is used (in applib.value.Date) to 
create a new internal java.util.date with the following: (note the 
comment!)

    public Date(final java.util.Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTimeZone(UTC_TIME_ZONE);

        // TODO when input date is BST then then date value ends up as 
the previous day
        cal.setTime(date);
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        this.date = cal.getTime();
    }

The "this.date" shows up in my system as:
"Thu Apr 07 14:00:00 SAST 2011" with a cdate of 
"2011-04-07T14:00:00.000+0200"

It has moved back a day. And what is with the 14h00 time? It's a 
*date* the time is supposed to be empty!

If I set the system default timezone to GMT-0200, then the end resut 
reads "2011-04-06T22:00:00.000-0200"

I think java has messed up - java.util.Date has no explicit timezone (it 
is managed via Calendar), but it has an implicit timezone based on the 
system default?

I would like to look into Joda Time and see if they've fixed this issue.

> - the user timezone is as defined by Localization
> - the UI layer - by way of Parser interface - always (or should always) 
> render the time with respect to the user's localization
> - we therefore shouldn't need any changes to the codebase.
> 
> Where we currently have failing tests, it's probably because they are 
> evaluating the date/time with respect to the timezone in which they are 
> running, rather than UTC.  In other words, the tests are at fault.

This is still possible (almost certain, in fact). I'm looking into it...

> ~~~
> Now, the above analysis may well be wrong, I haven't thought about this 
> as much as you, but that's my initial stab on the matter.
> 
> Let's keep this thread open until we get to a design that we are all 
> happy with and understand.

One argument that I have against setting the system default (or the 
app & datastore default) to UTC is that when looking at the raw data, 
in a simple 1-timezone config, I want to see the values that I specified 
(e.g. new applib.value.Date(2011, 4, 8), when written to the database, 
appears as 2011-04-08 in my database browser).



Re: Best place for application default timezone?

Posted by Dan Haywood <dk...@gmail.com>.
Hi Kevin,
Appreciate you taking the time to work on this; my thoughts within...


On 27/03/2011 16:39, Kevin Meyer - KMZ wrote:
> I'm looking at defining an "application" timezone, but I'm not sure
> where the best place is to define it.
>
That does seem like a useful concept.

> org.apache.isis.runtimes.dflt.runtime.context.IsisContext seems like a
> good start. The IsisSession has a getUserProfile, which has a
> Localisation interface (which exposes a getTimeZone() method), but
> this would possibly be the place to keep a per-user timezone, not an
> application-level timezone [is this an artificial distinction?].
>
I think we *should* distinguish the two.

As per the previous thread, I think that there are three clocks:

- user timezone
- app timezone (where the appserver runs)
- db timezone.

However, as your other thread said, java.sql.Date is meant to be a UTC 
date.  So that simplifies things somewhat.

- user timezone
- app timezone (where the appserver runs)
- db timezone = UTC

In addition, though, I think we could reasonably say (define) that the 
app timezone = UTC always also.  This is, effectively, what Isis 
currently does.  That would reduce matters down to:

- user timezone
- app/db timezone = UTC



> My goal is replace all occurrences of:
> 	"cal.setTimeZone(UTC_TIME_ZONE);"
> with a configurable
> 	"cal.setTimeZone(IsisContext.getTimeZone());"
>
> Likewise, the datastore implementations could provide their own
> getTimeZone() method, which defines the datastore's internal
> timezone.
> Comments? Suggestions?
>
I'm not in favour of this, because "cal" could occur in many cases, some 
of which may be in the app layer, some of which may logically be in the 
UI layer.  Moreover, some of these "cal" occur in the applib, which MUST 
NOT reference the runtime (IsisContext).



> This has an impact on all tests (for example), as it introduces a new
> dependency into those classes that currently just create a UTC
> timezone.
>
> Currently affected ( a quick search for etc/UTC):
> ./applib/src/main/java/org/apache/isis/applib/fixtures/FixtureClock.java
> ./applib/src/main/java/org/apache/isis/applib/value/Date.java
> ./applib/src/main/java/org/apache/isis/applib/value/Time.java
> ./applib/src/test/java/org/apache/isis/applib/value/TestClock.java
[snip]

As noted above, these applib classes MUST NOT depend on IsisContext.

~~~
As - again - you did note in your other thread, what's required is some 
sort of translation layer between the user timezone and UTC, and - again 
as you point out - org.apache.isis.adapters.Localization interface has 
this.  This was something that Rob introduced about a month or go.

I've just taken a look at how this interface is used it, it would seem 
to be used by ValueSemanticsProvider's Parser#displayTitleOf.    In 
other words, this *is* the translation layer that you speak of (a Parser 
is used to render every value of every property of every object).

~~~
Putting all the above together:

- let's agree that app server time = DB server time = UTC
- the user timezone is as defined by Localization
- the UI layer - by way of Parser interface - always (or should always) 
render the time with respect to the user's localization
- we therefore shouldn't need any changes to the codebase.

Where we currently have failing tests, it's probably because they are 
evaluating the date/time with respect to the timezone in which they are 
running, rather than UTC.  In other words, the tests are at fault.

~~~
Now, the above analysis may well be wrong, I haven't thought about this 
as much as you, but that's my initial stab on the matter.

Let's keep this thread open until we get to a design that we are all 
happy with and understand.

Cheers
Dan