在 Dynamics CRM 中,如何使用 API 协调用户在本地时区输入的日期与 UTC 中存储的日期?

In Dynamics CRM, how to reconcile dates entered by users in their local time zone with stored dates in UTC using API?

我正在编写与 Dynamics CRM 集成的代码,目前使用 OrganizationService 代理和 Xrm Tooling SDK。我们在不同的时区有许多不同的用户使用不同的 Dynamics CRM 实例,我正在寻找一个通用的解决方案。

这个问题与最终用户在 Dynamics 中指定日期有关,而我的集成代码在使用服务调用读取该日期时理解该用户的意图。请注意,我无法控制我的客户如何设置他们的 CRM 实例,我只能读取他们的数据。

我 运行 遇到的问题是,也许我的客户希望我使用他们为项目开始和结束日期指定的列。对于此示例,假设 opportunity 实体上这些自定义列的 API“逻辑名称”是 custom_projectstartdatecustom_projectenddate。在他们的 UI 上,他们可能已经为他们的用户设置了一个日期选择器,并且他们的用户正在选择一个日期。那个日期是他们的用户认为与特定时区无关的日期,但 CRM 会假设他们输入的是他们所在时区的日期和时间,并将该日期和时间作为 UTC 存储在基础数据库中。

在线下的某个时刻,我的集成代码使用 OrganizationService 读取该 opportunity 记录并将检索那些列 custom_projectstartdatecustom_projectenddate 并将这些日期作为世界标准时间。但实际上我需要这些日期作为文字,作为用户输入的实际日期(不考虑时区),但我不知道是什么用户输入了这些日期,或者他们在输入数据时所处的时区。或者(就此而言)当他们输入这些日期时夏令时是否有效。

如果输入这些日期的用户恰好在 GMT 时区(当不在夏令时时,与 UTC 的偏移量为 0),那么我根本不应该偏移这些日期。另一方面,如果输入这些日期的用户恰好在澳大利亚,我可以申请大量抵消。但是我怎么知道呢?

我怀疑我必须把这个问题反馈给我的客户,并说他们需要想办法让我得到与时区无关的字符串文字日期,但我没有对 Dynamics CRM 的管理有足够的了解,可以建议他们如何做到这一点。欢迎就如何表达提问提出建议。

但也许某些 Whosebug 评论者有一个漂亮的解决方案,我可以在不涉及我的客户的情况下解决这个问题?那样更好。

首先,如果我遗漏了您问题中的某些要点,我深表歉意,它很长而且更具哲理,但我理解您与 Dynamics 日期的斗争。

在 Dynamics 中,您可以为日期字段决定值的存储方式,如果是“用户本地”(意味着该值始终存储为 UTC,但显示时已转换为用户的本地时间)或“Time-区域独立”(意味着该值存储为 UTC 并作为 UTC 值显示给所有人)。

根据您的描述,您属于第一种情况。

示例:我的时区是 UTC+8,我创建了一个从今天上午 9 点开始的约会。 Dynamics 会将值存储为 UTC(因此存储的时间是 UTC 凌晨 1 点),并且因为该字段是“用户本地”,我将在上午 9 点看到,具有像 UTC+1 这样的时区的用户将在凌晨 2 点看到它。

当您通常通过代码创建记录时(比如没有模拟时),您 运行 在特定用户或应用程序用户的上下文中,具有在设置中定义的特定时区(因为在最后它是一个用户),但是如果你使用的是 C# SDK 并且你设置了一个日期字段,那么该值通常存储为 UTC(我通常写的是因为在 C# 中日期值可以存储为 Local,更多信息在这里https://docs.microsoft.com/en-us/dotnet/api/system.datetimekind?view=net-5.0)

如果您有兴趣可以检索此信息,您可以在此处找到更多详细信息https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/sample-retrieve-time-zone-information (the samples are stored inside this GitHub repo that is linked https://github.com/Microsoft/PowerApps-Samples/tree/master/cds/orgsvc/C%23/RetrieveTimeZone)

例如,您可以创建一个包含用户 ID 和与 UTC 的时差的字典,并使用它来计算正确的 UTC 值以在您设置该特定字段时插入。

我希望这能回答您的问题,如果您还有其他问题,请随时发表评论。