TimeZoneInfo.ConvertTimeToUtc问题 [英] TimeZoneInfo.ConvertTimeToUtc issue

查看:314
本文介绍了TimeZoneInfo.ConvertTimeToUtc问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们遇到一个问题,一个开发人员创建了以下代码,并且可以在他的DEV环境上工作。但是,当将其检入质量检查时,代码会中断并显示以下错误消息:

We had an issue where one developer creates the below code and it works on his DEV environment. But when it's checked into QA, the code breaks with the below error message:

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




由于提供的DateTime
,转换无法完成没有正确设置Kind属性。例如,当
的Kind属性为DateTimeKind.Local时,源时区必须为
TimeZoneInfo.Local。

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环境中,以上代码生成的错误与质量检查服务器相同。我应用了以下更改来解决此问题:

On my DEV environment, the above code generates the same error as the QA server. I applied the below change to fix the problem:

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

为什么第一个代码示例可在DEV1的环境上工作,但在DEV环境和QA服务器上却无法正常工作?

Why does the first code example work on DEV1's environment but break on my DEV environment and on our QA server?

推荐答案

这取决于 myRecord.StartTime 的起源。


  • 如果您是从 DateTime.Now 获得的,则它将有一个 Local 种。

  • 如果您是从 DateTime.UtcNow 获得的,它将有一种 Utc 类型。

  • 如果您是从 new DateTime(2013,5,1),则它将具有未指定类型。

  • If you got it from DateTime.Now, then it will have a Local kind.
  • If you got it from DateTime.UtcNow then it will have an Utc kind.
  • If you got it from new DateTime(2013,5,1) then it will have an Unspecified kind.

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

It also depends on where you got myTimeZone from. For example:


  • TimeZoneInfo.Local

  • TimeZoneInfo.Utc

  • TimeZoneInfo.FindSystemTimeZoneById( Central Standard Time)

  • TimeZoneInfo.Local
  • TimeZoneInfo.Utc
  • TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")

TimeZoneInfo.ConvertTimeToUtc 函数仅在可以匹配时运行该区域与您提供的类型相同。如果两者都是本地的,或者两者都是UTC,那么它将起作用。如果要为其指定特定区域,则类型应为未指定。此行为记录在MSDN上

The TimeZoneInfo.ConvertTimeToUtc function will only operate if it can match the zone to the kind you give it. If both are local, or both are UTC, then it will work. If you are giving it a specific zone, then the kind should be unspecified. This behavior is documented on MSDN.

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

You can easily reproduce the exception consistently:

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

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

Assuming you don't live in Fiji, this will error every time. You basically said, "convert my local time, in some other zone, to utc" - which doesn't make sense.

它可能在您的开发环境中有效,因为您为 myTimeZone 测试的值恰好是开发人员的本地区域。

It probably works in your dev environment because the value you're testing for myTimeZone happens to be the local zone for the developer.

关于您的更改-确定您可以强制指定未指定的种类,从而改变您所做工作的含义,以使其有意义。但是您确定这就是您想要的吗?前一天的。种类是什么?如果尚未<未指定 ,则表明它具有某些意图。您可能应该回到这些数据的来源,并确保它是您所期望的。

Regarding your change - sure you can force the kind to be unspecified, and that changes the meaning of what you are doing such that it makes sense. But are you sure this is what you want? What is the .Kind of the date before hand? If it's not already Unspecified, then it is carrying some intent. You should probably go back to the source of this data and make sure it is what you expect.

如果所有这些听起来都疯狂,疯狂,令人沮丧和奇怪,那就是因为 DateTime 对象发臭。以下是一些其他阅读材料:

If all of this sounds crazy, mad, frustrating, and bizarre, it's because the DateTime object stinks. Here's some additional reading:

  • What's wrong with DateTime anyway?
  • The case against DateTime.Now

您可以考虑使用改为 NodaTime 。其API可以防止您犯此类常见错误。

You might consider using NodaTime instead. Its API will prevent you from making these types of common mistakes.

这篇关于TimeZoneInfo.ConvertTimeToUtc问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆