ExtJs + Ext Direct + DJN: working with dates

Passing dates between ExtJs and Java code using Ext Direct is a bit convoluted, because there is no standard for passing dates in json: in fact, there is not such a thing as a date type in json.

All in all, I have found that the easiest way to pass dates back and and forth is to pass them as a numeric value, the number of milliseconds elapsed since January 1, 1970 00:00:00.000 GMT.

The java.lang.Date type represents just this, take a look here. And a javascript Date stores the same value, look here. Therefore, recreating dates is trivial once you have the milliseconds.

Besides, by passing milliseconds we are guaranteed that we will not lose data, as both types do not have more accuracy: there are no microseconds or nanoseconds in a java.lang.Date or a javascript date.

Because we are passing a number, we need to tell both ExtJs and DJN how to handle dates. Doing this in ExtJs is trivial, just redefine Ext.JSON.encodeDate as follows:

Ext.JSON.encodeDate = function(d) {
   return d.getTime();
};

Next, we need to tell DJN how to handle dates. DJN uses Gson for json handling, and it will ask us to define classes to perform date serialization and deserialization. Here’s the date serializer:

   public class DateSerializer implements JsonSerializer<Date> {
      public JsonElement serialize( Date src, Type typeOfSrc,
            JsonSerializationContext context) {
         assert src != null;
         assert context != null;
         assert typeOfSrc != null;

         JsonElement result = new JsonPrimitive( src.getTime() );
         return result;
      }
   }

And here is the deserializer:

   public class DateDeserializer implements JsonDeserializer<Date> {
      public Date deserialize( JsonElement json, Type typeOfT,
            JsonDeserializationContext context)
                  throws JsonParseException
                  {
         assert json != null;
         assert context != null;
         assert typeOfT != null;

         if( !json.isJsonPrimitive() ) {
            throw new JsonParseException( "The value must be a valid number");
         }
         JsonPrimitive primitivejson = (JsonPrimitive)json;
         if( !primitivejson.isNumber()) {
            throw new JsonParseException( "The value must be a valid number");
         }
         return new Date( primitivejson.getAsLong() );
   }

Once we have defined these classes, we need to register them with gson. To do this, we need to define a GsonBuilderConfigurator, as follows:

public class CustomGsonBuilderConfigurator extends DefaultGsonBuilderConfigurator
{
   @Override
   public void configure(GsonBuilder builder,
         GlobalConfiguration configuration)
   {
      super.configure(builder, configuration);
      builder.registerTypeAdapter( Date.class, new DateDeserializer());
      builder.registerTypeAdapter( Date.class, new DateSerializer());
   }
}

Finally, you need to tell DJN to use this configurator, by adding the following lines to web.xml:

   <init-param>
      <param-name>gsonBuilderConfiguratorClass</param-name>
      <param-value>
      com.softwarementors.extjs.djn.customizations.CustomGsonBuilderConfigurator
      </param-value>
   </init-param>    

Back to ExtJs, we still need to tell it how to convert milliseconds to dates.

In many scenarios, you will tell ExtJs that a value is a 'date', and that its format is 'time‘. For example, for a Model object you can define an startDate field as follows:

fields: [
   { name: 'startDate',<strong> type: 'date', dateFormat: 'time'</strong>}
   // ...
]

At other times, you will have to handle the milliseconds yourself, creating a new date as follows:

date = new Date(theValueYouReceivedViaJson);

Built in support for dates in future DJN versions

While all of this is boilerplate and therefore easy to set up, I will probably add this support to DJN in some version beyond 2.1, so that all you will have to do is to override Ext.JSON.encodeDate and take care of the javascript side.

Of course, you will always be able to redefine how to handle dates if this approach does not work for you.

2 responses to “ExtJs + Ext Direct + DJN: working with dates

  1. Pingback: DJN 2.2 beta 1 is out! | Software Development "Built to Last"

  2. Pingback: DirectJNgine 2.2 final is out | Software Development "Built to Last"

Leave a comment