c# - TimeZoneInfo.ConvertTimeToUtc 问题

标签 c# .net datetime

我们遇到了一个问题,一位开发人员创建了以下代码并且它可以在他的 DEV 环境中运行。但是当它被检查到 QA 时,代码中断并显示以下错误消息:

myRecord.UTCStartTime = TimeZoneInfo.ConvertTimeToUtc(myRecord.StartTime, myTimeZone);

The conversion could not be completed because the supplied DateTime did not have the Kind property set correctly. For example, when the Kind property is DateTimeKind.Local, the source time zone must be TimeZoneInfo.Local.

在我的 DEV 环境中,上述代码生成与 QA 服务器相同的错误。我应用了以下更改来解决问题:

DateTime utcStart = DateTime.SpecifyKind(myRecord.StartTime, DateTimeKind.Unspecified);
myRecord.UTCStartTime = TimeZoneInfo.ConvertTimeToUtc(utcStart, myTimeZone);

为什么第一个代码示例可以在 DEV1 的环境中运行,但在我的 DEV 环境和我们的 QA 服务器上会中断?

最佳答案

这取决于 myRecord.StartTime 的来源。

  • 如果您从 DateTime.Now 获取它,那么它将具有 Local 类型。
  • 如果您从 DateTime.UtcNow 获取它,那么它将具有 Utc 类型。
  • 如果您从 new DateTime(2013,5,1) 获得它,那么它将有一个 Unspecified 类型。

这还取决于您从何处获取 myTimeZone。例如:

  • TimeZoneInfo.Local
  • TimeZoneInfo.Utc
  • TimeZoneInfo.FindSystemTimeZoneById("中部标准时间")

TimeZoneInfo.ConvertTimeToUtc 函数只有在它可以将区域与您提供的类型相匹配时才会运行。如果两者都是本地的,或者都是 UTC,那么它将起作用。如果你给它一个特定的区域,那么类型应该是未指定的。此行为是 documented on MSDN .

您可以轻松地一致地重现异常:

var tz = TimeZoneInfo.FindSystemTimeZoneById("Fiji Standard Time");
var utc = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now, tz);

假设您不住在斐济,每次都会出错。您基本上是说,“将我在其他区域的本地时间转换为 utc”——这没有意义。

它可能适用于您的开发环境,因为您为 myTimeZone 测试的值恰好是开发人员的本地区域。

关于您的更改 - 确保您可以强制不指定类型,这会改变您正在做的事情的意义,使其变得有意义。但是你确定这是你想要的吗?之前日期的 .Kind 是什么?如果它还不是 Unspecified,那么它就带有一些意图。您可能应该返回此数据的来源并确保它符合您的预期。

如果所有这些听起来很疯狂、疯狂、令人沮丧和奇怪,那是因为 DateTime 对象很臭。这是一些额外的阅读 Material :

您可以考虑使用 NodaTime反而。它的 API 将防止您犯这些类型的常见错误。

关于c# - TimeZoneInfo.ConvertTimeToUtc 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16322896/

相关文章:

c# - 如何在游戏暂停时播放动画(时间刻度 = 0)

.net - F#中的哈希散列和.net中的弱哈希表

c# - JSON 解析问题 - 'S' 是 JSON 中无效的可转义字符

python - 如何遍历元组字典?

PHP strtotime() : date showing '1970-01-01 ' after conversion

c# - 如何更改 Windows Phone 应用程序栏的颜色?

c# - 如果它是一个单独的方法,ASP.NET Core 异步请求处理程序总是以 200 OK 和空主体响应

c# - 如何从通用列表创建 View ?

sql - 如何获取sql server 2005中两个日期之间的月份数

.net - NHibernate的轻量级替代品