TimeZoneInfo.ConvertTimeToUtc issue
我们遇到一个问题,一个开发人员创建下面的代码,它可以在他的DEV环境中工作。 但是当它被检入QA时,代码会出现以下错误消息:
1 | 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服务器相同的错误。 我应用以下更改来解决问题:
1 2 | DateTime utcStart = DateTime.SpecifyKind(myRecord.StartTime, DateTimeKind.Unspecified); myRecord.UTCStartTime = TimeZoneInfo.ConvertTimeToUtc(utcStart, myTimeZone); |
为什么第一个代码示例在DEV1的环境中起作用,但在我的DEV环境和QA服务器上中断?
这取决于
-
如果从
DateTime.Now 获得它,那么它将具有Local 类型。 -
如果从
DateTime.UtcNow 获得它,那么它将具有Utc 类型。 -
如果从
new DateTime(2013,5,1) 获得它,那么它将具有Unspecified 类型。
它还取决于你从哪里得到
-
TimeZoneInfo.Local -
TimeZoneInfo.Utc -
TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
只有当区域与您提供的区域匹配时,
您可以轻松地一致地重现异常:
1 2 | var tz = TimeZoneInfo.FindSystemTimeZoneById("Fiji Standard Time"); var utc = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now, tz); |
假设你不住在斐济,每次都会出错。你基本上说,"将我的当地时间,在其他一些区域转换为utc" - 这没有任何意义。
它可能适用于您的开发环境,因为您为
关于你的改变 - 确保你可以强制使用这种类型,并改变你正在做的事情的意义,这样才有意义。但你确定这是你想要的吗?事先约会的
如果所有这些听起来都疯狂,疯狂,令人沮丧和奇怪,那是因为
- 无论如何,DateTime有什么问题?
- 针对DateTime.Now的案例
您可以考虑使用NodaTime。它的API将阻止您犯这些类型的常见错误。
在这个例子中我已经将本地时区转换为未指定的类型,因此通过使用"DateTime.SpecifyKind()"方法它对我来说很好
DateTime.SpecifyKind(utc,DateTimeKind.Unspecified);
此方法创建一个新的DateTime对象,该对象具有与指定的DateTime相同的刻度数,但被指定为未指定的DateTimeKind类型。
public static DateTime ConvertLocalDate(DateTime utc)
{
1
2
3
4
5
6 string id = ConfigurationManager.AppSettings["Timezone"].ToString();
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById(id);
utc = DateTime.SpecifyKind(utc,DateTimeKind.Unspecified);
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(utc, cstZone);
return cstTime;
}
我发现了一个非常简单的解决方案
https://kiranpatils.wordpress.com/2011/01/09/the-conversion-could-not-be-completed-because-the-supplied-datetime-did-not-have-the-kind-property-set-正确换例如,当最类型 - 属性 - 是 - datetimekind本地最源时区,必须/
这似乎只在您使用DateTime.Now时发生。我更新我的代码如下,它再次工作:)
DateTime currentTime = new DateTime(DateTime.Now.Ticks,DateTimeKind.Unspecified);
在C#中
1 2 3 4 5 | public static DateTime IndianDateTime(DateTime currentTime) { DateTime cstTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(currentTime, TimeZoneInfo.Local.Id,"India Standard Time"); return cstTime; } |
在VB中
1 2 3 4 | Public Shared Function IndianDateTime(ByVal currentTime As DateTime) As DateTime Dim cstTime As DateTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(currentTime, TimeZoneInfo.Local.Id,"India Standard Time") Return cstTime End Function |