Grey Line

First, let me explain how Flex deals with Date transfer. Dates are transfered to/from Flex client as UTC date – no timezone information available. Transfer to the UTC/local time happens automatically on protocol level. As a result, if the server does not know client’s timezone, it can not derive the entered time – rather it operates on Global time only. It means that if I am on the East coast and entered 1PM, person in Denver will see 11AM.
Depending on the type of application it can be desirable behavior – however in most of the applications it is not. Sometimes I want to enter time in the client’s local time – regardless of the timezone I am in at the time of data entry. It means that application has to operate without timezone – or for that matter in one timezone. Usually it is solved either on the server side by keeping client timezone information in session and adjusting dates on each transfer or by communicating date as String. In either case it requires a lot of code and constant tracking of the issue.

However, it can be solved much easier with usage of transient tag/keyword during data transfer:

AS3:

package com.farata.datasource.dto
{
import flash.events.EventDispatcher;
[RemoteClass(alias="com.farata.datasource.dto.LineItemDTO")]
[Bindable(event="propertyChange")]
public dynamic class LineItemDTO extends EventDispatcher //implements IManaged
{

private var _myDate : Date;

public function get myDateUTC() : Date{
return _myDate ==null?null:new Date(_myDate.valueOf() – _myDate.getTimezoneOffset()*60000);
}
public function set myDateUTC( value : Date ):void{
var oldValue:Object = _myDate;
if (oldValue !== value) {
this._myDate = value == null?null:new Date(value.valueOf() + value.getTimezoneOffset()*60000);
}
}
[Transient]

public function get myDate() : Date{
return _myDate;
}
public function set myDate( value : Date ):void{
var oldValue:Object = this._myDate;
if (oldValue !== value) {
this._myDate = value;
dispatchUpdateEvent(“myDate”, oldValue, value);
}
}

Java:
package com.farata.datasource.dto;

import java.io.Serializable;
import java.util.*;

public class LineItemDTO implements Serializable
{

transient public java.util.Date myDate;
public java.util.Date getMyDateUTC()
{
return myDate;
}

public void setMyDateUTC(java.util.Date value)
{
this.myDate = value;
}
}

That is all – you have normal public variables on both sides, and serialization works transparently, keeping Date in UTC zone on both sides (you also need to set JAVA VM timezonne to UTC) – and now you are always in the servers timezone.

Enjoy,
Anatole Tartakovsky

PS Please evaluate your need for local vs global time – otherwise you would have cases like Dell’s support center in India when they were asking for feedback on service 8 hours before it was suppose to happen – I once got a call @ 2AM about delivery set up for 10AM – plan carefully.

3 Comments »

  1. Ken said,

    March 4, 2010 @ 5:09 am

    This is useful, but how do you apply it when using Farata’s DTO2FX to generate the AS DTO’s from Java? The adjusted DateUTC methods need to be manually written in the generated parent AS class, but they need to reference the data property in the generated child class. Not sure how to get round this, without using @FXIgnore on all date fields and handling them manually.

  2. Anatole Tartakovsky said,

    July 22, 2010 @ 2:21 am

    Ken,
    2 Choices – either manually on DTO level rather then _generated one ( we generate 2 classes per DTO for generation gap pattern) or by modifying XSLT – either way it is quite simple.
    Thank you
    Anatole

  3. Duchateau Olivier said,

    August 24, 2010 @ 1:09 pm

    Thank you !
    I write your code in my two general method : setFormData(model) and getFormData(model) and it’s perfect !
    No need to write it on all dto’s

    Example : model =
    [RemoteClass(alias="org.ainflux.bdd.aintranet.evenement.Evenement")]
    public class Evenement extends BaseObjectDao {
    [Bindable] //dateHeureFin
    public var dateHeureFin : Date;
    }

    public function getFormData(model) {
    …code…
    if (property.substring(0,4) == ‘date’) {
    var dt : Date = widget.value as Date;
    model[property] = new Date(dt.valueOf() – dt.getTimezoneOffset()*60000);
    }
    …code…
    }

RSS feed for comments on this post

Leave a Comment