The code for this is below and it should be deployed pre validation for the entities you wish to use it with, create or update.
/// <summary>
/// Fix for getting round the timezone issues with date only fields
/// </summary>
public class TimeZoneFix : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
//Get an instance of the helper class.
PluginHelper helper = new PluginHelper(serviceProvider);
helper.tracer.Trace("Loaded Helper");
if (helper.targetEntity.Attributes.Any(a => a.Value != null && a.Value.GetType() == typeof(DateTime)))
{
IOrganizationService service = helper.service;
helper.tracer.Trace("Building Request");
RetrieveEntityRequest request = new RetrieveEntityRequest();
request.LogicalName = helper.context.PrimaryEntityName;
request.EntityFilters = EntityFilters.Attributes;
RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request);
if (response != null && response.EntityMetadata != null)
{
List<KeyValuePair<string, object>> attribs = helper.targetEntity.Attributes.Where(a => a.Value != null && a.Value.GetType() == typeof(DateTime)).ToList();
foreach (var att in attribs)
{
DateTime date = (DateTime)helper.targetEntity[att.Key];
DateTime localDate = date.ToLocalTime();
TimeSpan dateDiff = localDate - date;
//Get the attribute metadata
AttributeMetadata meta = response.EntityMetadata.Attributes.FirstOrDefault(am => am.LogicalName.ToLower().Equals(att.Key));
//Check in the attribute metadata if the attribute is a date only.
if (meta != null && meta.AttributeType != null &&
meta.AttributeType == AttributeTypeCode.DateTime &&
((DateTimeAttributeMetadata)meta).Format == DateTimeFormat.DateOnly)
{
helper.targetEntity[att.Key] = localDate.AddHours(dateDiff.Hours + 10);
}
}
}
}
}
}