0

Suppose you have a pretty complex system with a heavy usage of DateTime(more than 1k places with some of helpers and extension relying on the exact type). Suppose you decide that you need to store UTC dates from now on.

My initial idea was substituting all DateTime types with DateTimeOffset but this is not a trivial task since of its heavy usage in different contexts.

The question is could I change just NHiberante mapping without having to change the type used in the rest of the system. Or is that large refactoring the only way?

2
  • How would NHibernate know what offset to apply? How would it deal with loading of historic dates? If you're going to embrace UTC, it pretty well has to be throughout the codebase. Commented Mar 20, 2012 at 19:03
  • From this description: • A 62-bit number, indicating the number of ticks since 1/1/0001 • A 2-bit enum, indicating the DateTimeKind (Unspecified, Local, or Utc) , it is like you can always make the conversion Commented Mar 20, 2012 at 19:06

2 Answers 2

1

If you use NHibernate Fluent Automapping, this's my convention for:

    public class UtcDateTimeConvention : IPropertyConvention, IPropertyConventionAcceptance
    {
        public void Apply(IPropertyInstance instance)
        {
            instance.CustomType<UtcDateTimeType>();
        }

        public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
        {
            criteria.Expect(x =>
                x.Property.PropertyType.Equals(typeof(DateTime)) ||
                x.Property.PropertyType.Equals(typeof(DateTime?)));
        }
    }

I prefer to persist UtcDateTimeType, and than convert it to local:

        public static DateTime ToUserTimeZone(this DateTime utcDateTime, TimeZoneInfo currentTimeZone)
        {
            if (utcDateTime.Kind != DateTimeKind.Utc)
            {
                throw new ArgumentException("utcDateTime.Kind != DateTimeKind.Utc", "utcDateTime");
            }

            return TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, currentTimeZone);
        }

        public static DateTime? ToUserTimeZone(this DateTime? utcDateTime, TimeZoneInfo currentTimeZone)
        {
            if (utcDateTime.HasValue)
            {
                return ToUserTimeZone(utcDateTime.Value, currentTimeZone);
            }

            return null;
        }
Sign up to request clarification or add additional context in comments.

2 Comments

UtcDateTimeType is not exactly the DateTimeOffset type it seems, may be some cast is possible here
Indeed, if you get persisted value and execute ToLocalTime() on it you would get an exception
0

You can map the DateTime fields with NHibernate UtcDateTime type instead of regular DateTime type if the database always stores UTC values. See http://codebetter.com/jameskovacs/2011/01/26/datetime-support-in-nhibernate/ for an example.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.