我们遇到一个问题,一个开发人员创建以下代码,并且该代码可以在他的DEV环境中工作。但是,当将其检入质量检查时,代码会中断并显示以下错误消息:
myRecord.UTCStartTime = TimeZoneInfo.ConvertTimeToUtc(myRecord.StartTime, myTimeZone);
在我的DEV环境中,以上代码生成的错误与质量检查服务器相同。我应用了以下更改来解决此问题:
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("Central Standard Time")
如果
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
对象发臭了。这里是一些其他阅读:您可以考虑改为使用NodaTime。其API可以防止您犯此类常见错误。
关于c# - TimeZoneInfo.ConvertTimeToUtc问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16322896/