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.
- 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);
Nice! Thanks a lot!
ReplyDeleteNice post, quick question, does LocalTimeFromUtcTimeRequest take care of daylight savings?
ReplyDelete