ValueProviderResult.ConvertTo returns 本地和云端的不同日期
ValueProviderResult.ConvertTo returns different dates locally and in the cloud
我有下一个自定义模型活页夹:
public class WebApiModelBinderDateTime : IModelBinder
{
public bool BindModel(HttpActionContext executionContext, ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null)
{
return false;
}
DateTime date = (DateTime)value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
bindingContext.Model = date;
return true;
}
}
文化在 web.config 中设置如下:
<globalization culture="en-GB" enableClientBasedCulture="false" uiCulture="en-GB" />
并且在 global.asax 中是这样的:
CultureInfo culture = CultureInfo.CreateSpecificCulture("en-GB");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
问题是这个活页夹 returns 本地和远程日期不同。
例如2019-06-03T09:53:26.651Z
将在本地转换为 2019-06-03 10:53:26
,但在云中转换为 2019-06-03 09:53:26
(这是部署到 Azure 云服务的旧系统)。
我尝试在本地和远程进行调试,但没有发现 CultureInfo.CurrentCulture
、ModelBindingContext
、ValueProvider
或 ValueProviderResult
之间有任何差异。
还有什么会导致不同的时区?
几件事:
文化设置和时区是完全正交的概念。文化可以影响字符串的格式,或者应用哪个日历系统,但它不影响时区。他们之间没有任何关系。
您正在指定 DateTimeKind.Utc
,因此无论您在哪里使用它,结果值都将被序列化,并带有一个表示 UTC 的尾随 Z
。如果这些值确实是基于 UTC 的,那么一切都很好,没有什么可做的了。但是,如果您将这些应用于可能代表不同时区时间的任意值,则设置 UTC 类型将无济于事。相反,您可以考虑使用 DateTimeOffset
类型而不是 DateTime
.
您没有向我们展示您如何应用此模型绑定器或如何使用 API。假设您的 API 正确地传递了 UTC-based 结果(使用 Z
),那么您对时区的担忧完全基于 client-side 代码的解释。
直接回答"What else can cause different time zones?"
- 如果调用
DateTime.Now
或DateTimeOffset.Now
或TimeZoneInfo.Local
或使用DateTimeKind.Local
、.ToLocalTime()
等,还有几个APIs 将 从 本地时间转换为 .ToUniversalTime()
,然后服务器的本地时区设置(从日期和时间控制面板或设置页面)控制该时区。它是服务器上所有应用程序的 server-wide 设置。您也可以在命令行中使用 tzutil.exe
查看或控制它。
- 如果您遵循 而非 依赖于服务器时区设置的最佳实践,(通过仅使用基于 UTC 的 APIs 或 APIs使用特定时区),那么您就没有这个顾虑。
- 别忘了,世界并非都在同一个时区。因此,如果您的服务器在一个时区(例如 UTC)发出时间,而您的客户端代码显式或隐式地将其转换为另一个时区(例如本地时间),那么值不同是完全正常的。
我有下一个自定义模型活页夹:
public class WebApiModelBinderDateTime : IModelBinder
{
public bool BindModel(HttpActionContext executionContext, ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null)
{
return false;
}
DateTime date = (DateTime)value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
bindingContext.Model = date;
return true;
}
}
文化在 web.config 中设置如下:
<globalization culture="en-GB" enableClientBasedCulture="false" uiCulture="en-GB" />
并且在 global.asax 中是这样的:
CultureInfo culture = CultureInfo.CreateSpecificCulture("en-GB");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
问题是这个活页夹 returns 本地和远程日期不同。
例如2019-06-03T09:53:26.651Z
将在本地转换为 2019-06-03 10:53:26
,但在云中转换为 2019-06-03 09:53:26
(这是部署到 Azure 云服务的旧系统)。
我尝试在本地和远程进行调试,但没有发现 CultureInfo.CurrentCulture
、ModelBindingContext
、ValueProvider
或 ValueProviderResult
之间有任何差异。
还有什么会导致不同的时区?
几件事:
文化设置和时区是完全正交的概念。文化可以影响字符串的格式,或者应用哪个日历系统,但它不影响时区。他们之间没有任何关系。
您正在指定
DateTimeKind.Utc
,因此无论您在哪里使用它,结果值都将被序列化,并带有一个表示 UTC 的尾随Z
。如果这些值确实是基于 UTC 的,那么一切都很好,没有什么可做的了。但是,如果您将这些应用于可能代表不同时区时间的任意值,则设置 UTC 类型将无济于事。相反,您可以考虑使用DateTimeOffset
类型而不是DateTime
.您没有向我们展示您如何应用此模型绑定器或如何使用 API。假设您的 API 正确地传递了 UTC-based 结果(使用
Z
),那么您对时区的担忧完全基于 client-side 代码的解释。直接回答"What else can cause different time zones?"
- 如果调用
DateTime.Now
或DateTimeOffset.Now
或TimeZoneInfo.Local
或使用DateTimeKind.Local
、.ToLocalTime()
等,还有几个APIs 将 从 本地时间转换为.ToUniversalTime()
,然后服务器的本地时区设置(从日期和时间控制面板或设置页面)控制该时区。它是服务器上所有应用程序的 server-wide 设置。您也可以在命令行中使用tzutil.exe
查看或控制它。 - 如果您遵循 而非 依赖于服务器时区设置的最佳实践,(通过仅使用基于 UTC 的 APIs 或 APIs使用特定时区),那么您就没有这个顾虑。
- 别忘了,世界并非都在同一个时区。因此,如果您的服务器在一个时区(例如 UTC)发出时间,而您的客户端代码显式或隐式地将其转换为另一个时区(例如本地时间),那么值不同是完全正常的。
- 如果调用