Are you migrating CRM on-premises to version 9.1? Are you facing the issue and looking for a workaround? This article is for you.
What is Time-Zone Independent?
Before all, we should have a look into the DateTime fields behavior in Dynamics. It consists of User Local, Date Only, and Time-Zone Independent. With Time-Zone Independent, the field values are displayed without the time-zone conversion. That means the time value does not change based on your location.
What is the issue?
If you open the form of any entity and set the value for the field Time-Zone Independent, you will see the new value is the previous date. That means the date displayed will be less than one day compared to the filled date. That's so weird.
Of course, we don't have any code which impacts that. We opened a Microsoft ticket in order to request the correction. Eventually, they confirmed that the bug is a known bug and they haven't had the plan to fix it.
Root cause
Do a quick Internet search, but I can't find any document or any discussion about it. My team struggled to come up with a solution. We have no idea.
Finally, we found out the cause as well as the way to solve it. There is no problem with stored data. It's still correct. This bug occurs when displaying data. The displayed date is automatically converted to UTC. That means it will be subtracted several hours depending on the current time zone.
Workaround
What we need to do is correct the data before showing it on the form. You know, CRM supports many plugin messages to modify and extend the standard behavior of the CRM. One of them is the "Retrieve" message. Although it is not used as much as other messages (create, update, delete...), but it is extremely helpful in this situation. Now, I think you can guess what you need to do.
First of all, Of course, you have to create a "Retrieve" plugin
Then you can go into your code to do the following:
- Retrieve all fields Time-Zone Independent
- Get the UTC Offset of the current value
- Add corresponding hours to the value
Here's a sample code:
public static void function(Entity postEntity, EntityMetadata metaData)
{
foreach (var attr in metaData.Attributes)
{
if (!postEntity.Contains(attr.LogicalName) || attr.AttributeType != AttributeTypeCode.DateTime)
{
continue;
}
var attrDate = attr as DateTimeAttributeMetadata;
if (attrDate.DateTimeBehavior != DateTimeBehavior.TimeZoneIndependent)
{
continue;
}
var dateVal = (DateTime)postEntity[attr.LogicalName];
var offSet = TimeZoneInfo.Local.GetUtcOffset(dateVal);
var adjustedTime = dateVal.Add(offSet);
postEntity[attr.LogicalName] = adjustedTime;
}
}
Drawback
Because we add hours when retrieving, all places that retrieve data will have the wrong value (more than a few hours). Therefore, be careful if the field isn't "Date only".
For the field "Date only", no matter how many hours you add to it, the value is still correct.
Some final words
Now, your issue should be resolved. Hope that Microsoft will fix it soon and the article will become a good resource for you.
If you have any better solutions or any questions, feel free to comment below. Your opinions are appreciated.
Add new comment