Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Timezone problem

    Hi,

    I am totally confused.

    On SmartGWT Pro 2.4 I have a server-side datasource containing a field:

    Code:
    <field name="birthday" type="date" dateFormatter="toShortDate" />

    On my client I use the following code to display everything in german locale and timezone:
    Code:
    final TimeZoneConstants timeZoneConstants = GWT.create(TimeZoneConstants.class);
    	final TimeZone TIMEZONE = TimeZone.createTimeZone(TimeZoneInfo.buildTimeZoneData(timeZoneConstants.europeBerlin()));
    
    	DateUtil.setShortDateDisplayFormatter(new DateDisplayFormatter()
    	{
    		@Override
    		public String format(final Date date)
    		{
    			if (date == null)
    			{
    				return null;
    			}
    			final DateTimeFormat dateFormatter = DateTimeFormat.getFormat("dd.MM.yyyy");
    			final String format = dateFormatter.format(date, TIMEZONE);
    			return format;
    		}
    	});
    On the server-side the Date is read as a java.sql.date from the database containing April 11th 1978, 00:00:00 CET.

    This is converted to UTC when transferred to the client: April 10th 1978, 23:00:00 UTC which ist totally correct. But when debugging my date-formatter above I recognized that the date that is passed to it is April 10th 1978, 23:00:00 CET and therefore the date displayed is "10.04.1978".

    What am I doing wrong? Is there a way to stop SmartGWT from setting the CET-timezone on the UTC-date on client-side?

    I found a lot of related posts in the forum and on the web, but I am still not able to resolve this problem.

    Any help will be greatly appreciated.


    Your's

    Jens

    #2
    A field of type "date" represents a logic date without a time. Use "datetime" for date values where the time component is intended to have meaning.

    Comment


      #3
      Thank you very much for your answer. The time has no meaning on the birthday field. This is the reason why it is represented by a java.sql.Date on the server and the time is set to 00:00:00.000.

      SmartGWT nevertheless translates the java.sql.Date "April, 11th 1978, 00:00:00 CET" into the long-value 261093600000 when transferring it to the client (using DSResponse.setData(...)). 261093600000 is April, 10th 1978, 23:00:00" which is totally correct assuming the SmartGWT transfers the Date in UTC.

      But on the client-side this is translated by SmartGWT into a java.util.Date "April, 10th 1978, 23:00:00 CET" which is then passed to the format-method of the DateDisplayFormatter.

      I do not know what I am doing wrong. In my oppinion I have to change the way SmartGWT calculates the long value from the given Date, so it will not substract the one hour timezone-difference or change the way the long-value is translated into a java.util.Date on the client-side (setting it's timezone to UTC instead of CET)...

      Hope this clarifies things a little bit...


      Your's

      Jens

      Comment


        #4
        Are you using your own JDBC code directly to access the database? When using our SQLDataSource we automatically use a marker type (ISCDate) to cause special serialization - we don't send a timestamp, rather we deliver the date as month, day, year values, and we end up representing the date in local time (specifically, 0 seconds past midnight).

        You could use this marker type as well (com.isomorphic.util.ISCDate subclass of java.util.Date) or define your own serialization policy for java.sql.Date (see JSTranslater).

        Comment


          #5
          Thank you again for your prompt answer. Using ISCDate instead of java.sql.Date in my entities on the server does not work for me. Hibernate cannot deal with it...

          In the meantime I found out, that I can get the format I want by setting

          Code:
          DateUtil.setShortDateDisplayFormat(DateDisplayFormat.TOEUROPEANSHORTDATE);
          DateUtil.setDefaultDateSeparator(".");
          without any custom DateFormatters, too. Sorry, I am just a beginner...

          But my problem is still there. (Please see the post below for a more detailed description. What I wrote here first is already outdated...).


          Your's

          Jens
          Last edited by jstegemann; 2 Feb 2011, 10:03.

          Comment


            #6
            After a full day of work on this problem I still have no idea how to handle it, but a slightly better understanding, what is happening. I will try to describe the situation in more detail:

            I have a ValueManager "vm". A DynamicForm is added to the ValueManager which includes a DateItem named "dateA" (to make it easy to read ;-)). Into the TextField of this DateItem I enter "11.04.1978".
            I have another DynamicForm which includes a DateItem named "dateB". I enter the same Date into the TextField of this item. I then add the Record from this Form to a ListGrid by

            Code:
            final JavaScriptObject jsObj = form.getValuesAsRecord().getJsObj();
            JSOHelper.deleteAttribute(jsObj, SC.REF);
            listGrid.addData(new ListGridRecord(jsObj));
            The ListGrid is defined to save locally. Later I add all Records from this ListGrid to the ValueManager "vm":

            Code:
            vm.setValue("values", listGrid.getRecords());
            Finally I save the values from the ValueManager by

            Code:
            vm.saveData()
            The DSRequest sent to my server now has the correct Date for dateA ("1978-04-11"), but the wrong Date for DateB ("1978-04-10T22:00:00").

            What is interesting is the different format although both fields are declared as type "date" in their datasource.xml-files.

            Calling vm.getValues() right before saveData() shows for dateA: "Mon Apr 10 23:00:00 CET 1978" and for DateB "Mon Apr 10 23:00:00 CET 1978".


            I am really confused. I have to work this out real soon to finnish our first SmartGWT-project and have absolutely no idea what to do about it.


            Hope anybody can help.


            Your's

            Jens

            Comment


              #7
              You haven't shown any of the DataSources, what's bound to what, and what types are set, which is what drives this behavior.

              What this primarily suggests is that dateB is being edited in a context where we don't know the type is "date". Perhaps that form doesn't have a DataSource.

              Comment


                #8
                I am sorry. Here is, how the Datasources are configured:

                I have two Datasource defined:

                Code:
                <DataSource ID="DatasourceA" serverType="generic">
                
                	<fields>
                		<field name="id" type="integer" hidden="true" primaryKey="true" />
                		<field name="version" type="integer" hidden="true" primaryKey="true" canEdit="false"/>
                		
                		<field name="elements" multiple="true"
                			type="DatasourceB" javaClass="de.my.package.Element" />
                
                		<field name="dateA" type="date" dateFormatter="toShortDate" />
                	</fields>
                
                	<serverObject lookupStyle="spring" bean="myDao"/>
                    
                </DataSource>
                and

                Code:
                <DataSource ID="DatasourceB" serverType="generic">
                
                	<fields>
                		<field name="id" type="integer" hidden="true" primaryKey="true" />
                		<field name="version" type="integer" hidden="true" primaryKey="false" />
                		
                		<field name="dateB" type="date" useTextField="true" dateFormatter="toShortDate" enforceDate="true"/>
                	</fields>
                	
                </DataSource>
                DatasourceA is attached to the ValuesManager vm and to the DynamicForm that contains dateA
                This form is added to the ValuesManager. dateA is represented by a DateItem created in JavaCode and added to the form by setItem().

                The DynamicForm, that contains dateB is attached to DatasourceB as well as the ListGrid, that the record from the form is added to.

                Hope this provides the necessary information.


                Your's

                Jens
                Last edited by jstegemann; 3 Feb 2011, 02:41.

                Comment


                  #9
                  Just to complete the information:

                  Calling a datasource.xmlSerialize() just before the valuesManager,save() like

                  Code:
                  final String test = dataSource.xmlSerialize(vm.getValues(), new SerializationContext());
                  vm.saveData(new DSCallback()
                      {
                          ...
                  results in test containing:

                  Code:
                  <DatasourceA>
                      <dateA>1978-04-11</dateA>
                      <elements>
                          <DatasourceB>
                              <dateB>1978-04-11</dateB>
                  	    <id>17<id>
                              <version>1</version>
                          </DatasourceB>
                      </elements>
                      <id>17<id>
                      <version>1</version>
                  </DatasourceA>
                  The dates are all totally correct here, but the DSRequest send to the server (from the Developer Console) looks like:

                  Code:
                  {
                      "actionURL":"http://localhost:8080/.../sc/IDACall", 
                      "showPrompt":true, 
                      "transport":"xmlHttpRequest", 
                      "promptStyle":"cursor", 
                      "bypassCache":true, 
                      "data":{
                          "values":{
                              "dateA":"1978-04-11", 
                              "elements":[
                                  {
                                      "dateB":"1978-04-10T22:00:00", 
                                      "id":17, 
                                      "version":1
                                  }
                              ], 
                              "id":17, 
                              "version":1
                          }, 
                          "operationConfig":{
                              "dataSource":"DatasourceA", 
                              "repo":null, 
                              "operationType":"add"
                          }, 
                          "componentId":"isc_ValuesManager_0", 
                          "appID":"builtinApplication", 
                          "operation":"DatasourceA_add", 
                          "oldValues":{
                          }
                      }
                  }
                  Might this be a bug in the serializiation-code? I have no idea why serializing the vm-values in xml should result in something different from serializing the same content in json... But maybe I am still doing something wrong here.


                  Your's

                  Jens

                  Comment


                    #10
                    This makes more sense now. The key is that the date is in a subelement - the XML serialization system will do recursive schema-driven serialization (it needs to be this sophisticated for use with SOAP), however the JSON one will not.

                    Even given this, if the date value came from a form that was bound to DataSourceB, it should still serialize as a date only (no time). Are you able to create a test case demonstrating a scenario where this does not happen?

                    Comment


                      #11
                      Note that the reason the date value would still be expected to serialize as just a date is that the Date instance is itself marked as a logical date. So you might be defeating this by copying the value at some point (perhaps indirectly).

                      Comment


                        #12
                        This might course be the case. I listed everything I am doing to the data in my posts. Unfortunately I have absolutely no clue, how I could find out where the logical-date flag might be lost not to think about how to correct it. Could you please point me into the right direction?

                        I will work on a test case...

                        Comment


                          #13
                          Wee don't have your complete code, so all can say is look for a copy (explicit or implicit). If you don't find it by inspection, trim code off until the find the minimum code needed to show the problem, and post that.

                          Comment


                            #14
                            Building the testcase I found out, that the described behaviour has nothing to do with my copying around of Records, etc.

                            Just defining two datasources, one depending on the other and a simple DynamicForm is enough. If a date is included in the dependent datasource, a wrong value for this date gets sent to the server:

                            DatasourceA:
                            Code:
                            <DataSource ID="DatasourceA" serverType="generic">
                            	<fields>
                            		<field name="name" type="text" />
                            		<field name="elements" multiple="true"
                            			type="DatasourceB" javaClass="de.testcase.client.domain.DatasourceB" />
                            		<field name="dateA" type="date"/>
                            	</fields>
                            	<serverObject lookupStyle="spring" bean="datasourceADao"/>    
                            </DataSource>
                            DatasourceB:
                            Code:
                            <DataSource ID="DatabaseB">
                            	<fields>
                            		<field name="name" type="text" />
                            		<field name="dateB" type="date" />	
                            	</fields>
                            </DataSource>
                            GWT-Module:
                            Code:
                            public class Testcase implements EntryPoint
                            {
                            	@Override
                            	public void onModuleLoad()
                            	{
                            		SC.showConsole();
                            
                            		final VStack stack = new VStack();
                            		stack.setHeight100();
                            		stack.setWidth100();
                            
                            		final DynamicForm firmaForm = new DynamicForm();
                            		firmaForm.setDataSource(DataSource.get("DatasourceA"));
                            
                            		stack.addMember(firmaForm);
                            
                            		firmaForm.editNewRecord();
                            
                            		final ToolStripButton sb = new ToolStripButton("save");
                            		sb.addClickHandler(new ClickHandler()
                            		{
                            
                            			@Override
                            			public void onClick(final ClickEvent event)
                            			{
                            				firmaForm.saveData();
                            			}
                            		});
                            
                            		stack.addMember(sb);
                            
                            		stack.draw();
                            	}
                            }
                            Now I enter April, 11th 1978 into both DateItems (dateA and dateB) and click the send-button:

                            RPCRequest sent by saveData (copied from DevelopmentConsole):
                            Code:
                            {
                                "actionURL":"http://localhost:8080/Testcase/Testcase/sc/IDACall", 
                                "showPrompt":true, 
                                "prompt":"Saving form...", 
                                "transport":"xmlHttpRequest", 
                                "promptStyle":"cursor", 
                                "bypassCache":true, 
                                "data":{
                                    "values":{
                                        "dateA":"1978-04-11", 
                                        "name":"testA", 
                                        "elements":[
                                            {
                                                "dateB":"1978-04-10T22:00:00", 
                                                "name":"testB"
                                            }
                                        ]
                                    }, 
                                    "operationConfig":{
                                        "dataSource":"DatasourceA", 
                                        "repo":null, 
                                        "operationType":"add"
                                    }, 
                                    "componentId":"isc_DynamicForm_0", 
                                    "appID":"builtinApplication", 
                                    "operation":"DatasourceA_add", 
                                    "oldValues":{
                                    }
                                }
                            }
                            I uploaded the full source-code as a maven-project to rapidshare (http://rapidshare.com/files/446556667/Testcase.zip) and attached a screenshot.

                            I have checked the results with Firefox 3.6, Chrome 8 and IE 8. I also tried a compiled version and development mode. It's always the same...

                            Am I doing something wrong, or is this a bug? Thank you once again for your help! Unfortunately this gets quite urgent for me now (have to deliver project tomorrow and want to make it look good to my boss since it is our first SmartGWT-project ;-)).


                            Your's

                            Jens
                            Attached Files
                            Last edited by jstegemann; 6 Feb 2011, 11:54.

                            Comment


                              #15
                              Complete code is key, and without we can't answer whether you're doing something wrong.

                              Don't send a Maven project - what's easier to work with is a minimal number of files that can be dropped onto one of the sample projects.

                              Comment

                              Working...
                              X