2

I would like to create a fluent nhibernate mapping to map a DateTime field in a following way:

  1. On save - Save the UTC value
  2. On read - Adjust to local time zone value

What is the best way to achieve this mapping?

Alex
  • 9,250
  • 11
  • 70
  • 81
  • 1
    Looks like a duplicate of http://stackoverflow.com/questions/1547133/rehydrating-fluent-nhibernate-configured-datetime-as-kind-utc-rather-than-unspec/6118935#6118935 – David Peden Mar 12 '12 at 16:28
  • 1
    Regarding rehydration with local time, that really should be a presentation concern. Otherwise, you might end up storing mixed dates. – David Peden Mar 12 '12 at 16:34
  • well, actually, my question is still valid, since the link you reference just mentions that this should be done with a custom mapping, but doesn't provide the example code. I was hoping for a solution where the mapping automagically adjusted the times as needed – Alex Mar 12 '12 at 16:38
  • To do that, check out this post: http://stackoverflow.com/questions/242022/nhibernate-mapping-to-custom-types. You'll in the NullSafeGet, you should return dateTime.ToLocalTime();. – David Peden Mar 12 '12 at 16:48

1 Answers1

2

Personally, I would store the date in the object in UTC, then convert within the object when reading/writing. You can then reference the backing field your property uses in the mapping (it's not quite as "fluent" to do it this way but you can use FluentNH to map this). If the UTC value might have value to you in code then just expose it.

public class MyClass
{
   ...

   //Don't map this field in FluentNH; this is for in-code use
   public DateTime MyDate 
   {
      get{return MyDateUTC.ToLocalTime();} 
      set{MyDateUTC = value.ToUniversalTime();}
   }

   //map this one instead; can be private as well
   public DateTime MyDateUTC {get;set;} 
}

...

public class MyClassMap:ClassMap<MyClass>
{
   public MyClassMap()
   {
      Map(x=>x.MyDateUTC).Column("MyDate");

      //if you made the UTC property private, map it this way instead:
      Map(Reveal.Member<DateTime>("MyDateUTC")).Column("MyDate");
   }
}
KeithS
  • 70,210
  • 21
  • 112
  • 164
  • I like this approach. It solves the problem and it's not complicated. The only negative is that I have to define two properties for each date, but it's not too bad. – Alex Mar 12 '12 at 17:19
  • I made MyDateUTC a private variable, but the Reveal.Member mapping is not working. – Alex Mar 12 '12 at 17:28
  • You can try making MyDateUTC a field instead of a property; just remove the Get/Set declarations. Usually Reveal.Member is used to access private backing fields, so it may not be searching for a private property. – KeithS Mar 12 '12 at 17:33
  • I'm ok. Was able to use the fluent mapping anyway since I was already using nested mappings. See here: http://wiki.fluentnhibernate.org/Fluent_mapping_private_properties – Alex Mar 12 '12 at 17:34
  • That would have been the next suggestion, putting the mapping somewhere where the private visibility isn't a problem. – KeithS Mar 12 '12 at 17:35
  • if we are accessing this API (server code) from different time zone , it will convert to local time of hosted area right ? if my system is hosted at United States and I'm accessing it from Singapore , I think it is best way to convert to local time at server side , better to convert at client side , right ? – AhammadaliPK Apr 02 '20 at 11:33