Sep 14, 2017

Convert in between Local Time and UTC Time

Though this is not a new subject, thought of sharing a simplified version of Code snippet to be used in converting Local Time and UTC Time as necessary. Base for this code was taken from SDK, but I have simplified and made a Ready Made class, which I though is helpful.

Let's remind few reasons why these conversions are very important to Dynmics 365 implementations;
  • DateTime fields are always kept in DB as UTC, but shown in UI with Users Local Time.
  • DateTime Retrieve with Web Service is always UTC.
  • Plugin/WF Context returns UTC time. 
Below are some of the scenarios you may come across that need conversions in your code.
  • When you need to do a calculation based on Time
  • When you need to pass Data to another System

Here is the class I suggest;
using Microsoft.Xrm.Sdk;
using System;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;

namespace CommonLibrary
{
    internal static class CommonUtility
    {
        internal static DateTime RetrieveLocalTimeFromUTCTime(IOrganizationService service, DateTime utcTime)
        {
            return RetrieveLocalTimeFromUTCTime(utcTime, RetrieveCurrentUsersSettings(service), service);
        }

        internal static DateTime RetrieveUTCTimeFromLocalTime(IOrganizationService service, DateTime localTime)
        {
            return RetrieveUTCTimeFromLocalTime(localTime, RetrieveCurrentUsersSettings(service), service);
        }

        internal static int? RetrieveCurrentUsersSettings(IOrganizationService service)
        {
            var currentUserSettings = service.RetrieveMultiple(
                new QueryExpression("usersettings")
                {
                    ColumnSet = new ColumnSet("timezonecode"),
                    Criteria = new FilterExpression
                    {
                        Conditions =
                        {
                    new ConditionExpression("systemuserid", ConditionOperator.EqualUserId)
                        }
                    }
                }).Entities[0].ToEntity<Entity>();
            return (int?)currentUserSettings.Attributes["timezonecode"];
        }

        internal static DateTime RetrieveLocalTimeFromUTCTime(DateTime utcTime, int? timeZoneCode, IOrganizationService service)
        {
            if (!timeZoneCode.HasValue)
                return DateTime.Now;
            var request = new LocalTimeFromUtcTimeRequest
            {
                TimeZoneCode = timeZoneCode.Value,
                UtcTime = utcTime.ToUniversalTime()
            };
            var response = (LocalTimeFromUtcTimeResponse)service.Execute(request);
            return response.LocalTime;
        }

        internal static DateTime RetrieveUTCTimeFromLocalTime(DateTime localTime, int? timeZoneCode, IOrganizationService service)
        {
            if (!timeZoneCode.HasValue)
                return DateTime.Now;
            var request = new UtcTimeFromLocalTimeRequest
            {
                TimeZoneCode = timeZoneCode.Value,
                LocalTime = localTime
            };
            var response = (UtcTimeFromLocalTimeResponse)service.Execute(request);
            return response.UtcTime;
        }
    }
}

Suppose we need to Retrieve Local time from UTC time (dateTime could be a field coming from Plug-in context);

DateTime dateTimeLocal = CommonUtility.RetrieveLocalTimeFromUTCTime(service, dateTime);

2 comments:

  1. Nice post, quick question, does LocalTimeFromUtcTimeRequest take care of daylight savings?

    ReplyDelete