C# TimeZoneInfo.ConvertTimeToUtc 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16322896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:45:15  来源:igfitidea点击:

TimeZoneInfo.ConvertTimeToUtc issue

c#.netdatetime

提问by Jerry

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:

我们遇到了一个问题,一位开发人员创建了以下代码并且它在他的 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.

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

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

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

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

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

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

采纳答案by Matt Johnson-Pint

It depends on how the myRecord.StartTimewas originated.

这取决于它是如何myRecord.StartTime起源的。

  • If you got it from DateTime.Now, then it will have a Localkind.
  • If you got it from DateTime.UtcNowthen it will have an Utckind.
  • If you got it from new DateTime(2013,5,1)then it will have an Unspecifiedkind.
  • 如果你从 得到它DateTime.Now,那么它就会有Local一种。
  • 如果你DateTime.UtcNow从那时得到它,它就会有Utc一种。
  • 如果你new DateTime(2013,5,1)从那时得到它,它就会有Unspecified一种。

It also depends on where you got myTimeZonefrom. For example:

这也取决于你从哪里来myTimeZone。例如:

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

The TimeZoneInfo.ConvertTimeToUtcfunction 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.

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

You can easily reproduce the exception consistently:

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

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

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.

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

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

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

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 .Kindof 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.

关于您的更改 - 确保您可以强制未指定种类,这会改变您所做的事情的含义,使其有意义。但你确定这是你想要的吗?什么是.Kind之前的日期?如果它还没有Unspecified,那么它带有某种意图。您可能应该回到这些数据的来源并确保它是您所期望的。

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

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

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

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

回答by Pradeep Kumar Das

in this example i have converted the local timezone to unspecified type so it is working fine for me by using "DateTime.SpecifyKind()" method

在此示例中,我已将本地时区转换为未指定的类型,因此使用“DateTime.SpecifyKind()”方法对我来说工作正常

DateTime.SpecifyKind(utc,DateTimeKind.Unspecified);

DateTime.SpecifyKind(utc,DateTimeKind.Unspecified);

this method Creates a new DateTime object that has the same number of ticks as the specified DateTime, but is designated as unspecified type of DateTimeKind.

此方法创建一个新的 DateTime 对象,该对象与指定的 DateTime 具有相同的刻度数,但被指定为未指定的 DateTimeKind 类型。

public static DateTime ConvertLocalDate(DateTime utc) {

        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;
    }

公共静态日期时间 ConvertLocalDate(DateTime utc) {

        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;
    }

回答by Atta H.

I found a really simple solution here https://kiranpatils.wordpress.com/2011/01/09/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/

我在这里找到了一个非常简单的解决方案 https://kiranpatils.wordpress.com/2011/01/09/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/

Which appears only to be happening when you use DateTime.Now. I update my code like following and it is working again :)

这似乎只有在您使用 DateTime.Now 时才会发生。我更新了我的代码,如下所示,它又开始工作了:)

DateTime currentTime = new DateTime(DateTime.Now.Ticks, DateTimeKind.Unspecified);

DateTime currentTime = new DateTime(DateTime.Now.Ticks, DateTimeKind.Unspecified);

回答by iApps Creator India

in C#

在 C# 中


public static DateTime IndianDateTime(DateTime currentTime)
{
    DateTime cstTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(currentTime, TimeZoneInfo.Local.Id, "India Standard Time");
    return cstTime;
}

In VB

在VB中


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