Universal time

Posts   
 
    
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 29-Jun-2007 11:34:20   

Any ideas how you would implement following requirement using llblgen;

All date times should be stored in database in universal time, but clients should be working with their local times. It's a n-tier application with smart client.

What I would like to see is that the time handling is totally transparent in GUI application. Or to any other clients using entity classes.

What I had first had in mind was that I change the templates to override getvalue() function to return the local time. Internally the entities would always contain the data fetched from database, i.e. universal time. As llblgen does not use property setters/getters when fetching/saving entities it's would be okay to modify both getvalue() and setvalue() methods of entitybase template.

But that would not work in 2.5 anymore, you can't change getvalue() methods return value (or am I missing something?)

Another possibility is to somehow know the clients locale at server. I am not sure if it is available in the httpcontext but I doubt it (using remoting that is). You could save it to the callcontext, but then again, that would most likely break if I had to move to WCF for example (not sure though).

What I don't want to do is to let the clients work with universal times.

Any other ideas?

simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 29-Jun-2007 12:13:05   

I've been thinking on the same lines but have not implemented anything yet.

I think I am heading towards having two properties for DateTime values - one for UTC and one for local - either by modifying templates or adding virtual properties (for databinding) via TypedDescriptor.

Will be interested to see how you go with this.

Cheers Simon

sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 29-Jun-2007 12:30:06   

Hmm... I think I could live with adding fields for local time as well (not in the DB of course). Can you elaborate a bit what do you mean with virtual properties via typedescriptor?

Edit: added the template modification I tried with previous version (entityAdapter.template)

What I do like about this approach is that it's really nice to use, databinding and all works really nice, no need to add new fields or anything like that. I did not test it that much though, but did not encounter any problems with it either.



<[Foreach EntityField CrLf]>
        /// <summary> The <[EntityFieldName]> property of the Entity <[CurrentEntityName]><br/><br/>
        /// <[Foreach CustomProperty EntityField]>
        /// <[CustomPropertyName]>: <[CustomPropertyValue]><br/><[NextForeach]></summary>
        /// <remarks>Mapped on  <[ CaseCamel TargetType ]> field: "<[SourceObjectName]>"."<[SourceColumnName]>"<br/>
        /// <[ TargetType ]> field type characteristics (type, precision, scale, length): <[SourceColumnDbType]>, <[SourceColumnPrecision]>, <[SourceColumnScale]>, <[SourceColumnMaxLength]><br/>
        /// <[ TargetType ]> field behavior characteristics (is nullable, is PK, is identity): <[SourceColumnIsNullable]>, <[IsPrimaryKey]>, <[IsIdentity]></remarks>
        public <[If EntityFieldOverrides]>override<[Else]>virtual<[EndIf]> <[TypeOfField]> <[EntityFieldName]>
        {
            get
            {
                object valueToReturn = base.GetCurrentFieldValue((int)<[CurrentEntityName]>FieldIndex.<[EntityFieldName]>);
                if(valueToReturn == null)
                {
                    valueToReturn = TypeDefaultValue.GetDefaultValue(typeof(<[TypeOfField]>));
                }
                
                if (typeof(<[TypeOfField]>) == typeof(System.DateTime))
                {   
                    //When reading values, always return datetimes as LocalTime
                    //DataAdapter reads the values from underlying data structure, so this code is not used when
                    //enties are being saved.
                    System.DateTime datetime = (System.DateTime)valueToReturn;
                    valueToReturn = datetime.ToLocalTime();                 
                }
                
                return (<[TypeOfField]>)valueToReturn;
            }
            set 
            { 
                if (value is System.DateTime)
                {                   
                    //When any client is updating datetime values, convert them to UTC
                    SetNewFieldValue((int)<[CurrentEntityName]>FieldIndex.<[EntityFieldName]>, Convert.ToDateTime(value).ToUniversalTime());                    
                }
                else
                {           
                    SetNewFieldValue((int)<[CurrentEntityName]>FieldIndex.<[EntityFieldName]>, value); 
                }
                
            }
        }<[NextForeach]>


Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Jun-2007 12:44:42   

Do you want me to add a PostProcessValueToReturn method of some sort to the entitybase(2) classes (which is virtual) and which you can override to alter the value right before it's returned from Getvalue ?

Frans Bouma | Lead developer LLBLGen Pro
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 29-Jun-2007 12:52:01   

Otis wrote:

Do you want me to add a PostProcessValueToReturn method of some sort to the entitybase(2) classes (which is virtual) and which you can override to alter the value right before it's returned from Getvalue ?

So I could override that in CommonEntityBase. That should work indeed. Now that I got you here Otis, do you see any problems in this approach, regarding the original problem?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Jun-2007 13:07:04   

sami wrote:

Otis wrote:

Do you want me to add a PostProcessValueToReturn method of some sort to the entitybase(2) classes (which is virtual) and which you can override to alter the value right before it's returned from Getvalue ?

So I could override that in CommonEntityBase. That should work indeed. Now that I got you here Otis, do you see any problems in this approach, regarding the original problem?

Altering that particular part of the template doesn't really version well, as you have to take into account template changes so it's extra maintenance costs.

I'll add the method so it gives you more flexibility if you want to post-process values to return from properties.

Frans Bouma | Lead developer LLBLGen Pro
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 29-Jun-2007 13:11:29   

Otis wrote:

I'll add the method so it gives you more flexibility if you want to post-process values to return from properties.

Cool, thanks smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Jun-2007 13:59:43   

The new method is called

/// <summary>
/// Post-processes the value to return from GetValue. Override this method to be able to post-process any value to return from an entity field's property.
/// </summary>
/// <param name="fieldToGet">the field to get the value for</param>
/// <param name="valueToReturn">The value to return.</param>
/// <remarks>It's recommended that you don't change the type of the value passed in. If you want to change the type, use a type-converter.</remarks>
protected virtual void PostProcessValueToGet(IEntityField2 fieldToGet, ref object valueToReturn)

(edit) I decided to pass in the entity field instead, so it's similar to PreProcessValueToSet simple_smile

Frans Bouma | Lead developer LLBLGen Pro