C# · 12月 30, 2021

c# – 仅当不是Utc时才将DateTime转换为Utc

我正在使用Jon Skeet发布在 Creating a DateTime in a specific Time Zone in c# fx 3.5的DateTimeWithZone结构

这不符合我的情况,因为它假定在构造函数中传递的DateTime是本地时间,因此使用指定的TimeZone将其转换为Utc.

在我的情况下,我们将大部分传入已经在Utc中的DateTime对象(因为这是我们正在存储的),所以我们只需要执行转换,如果源DateTime.Kind不是Utc.

因此,我将构造函数更改为:

public DateTimeWithZone(DateTime dateTime,TimeZoneInfo timeZone,DateTimeKind kind = DateTimeKind.Utc) { dateTime = DateTime.SpecifyKind(dateTime,kind); utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime,timeZone); this.timeZone = timeZone; }

这里我们有一个可选的Kind参数,默认为Utc.

但是,运行此代码并传递Utc DateTime会生成以下异常:

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.

根据文件(http://msdn.microsoft.com/en-us/library/bb495915.aspx):

If the Kind property of the dateTime parameter equals DateTimeKind.Utc and the sourceTimeZone parameter equals TimeZoneInfo.Utc,this method returns dateTime without performing any conversion.

由于输入时间和时区都具有Utc的Kind属性,因此我不会期望获得此异常.

我误解了吗

解决方法 像MSDN文档一样,如果你传递一个DateTime,其类型设置为除DateTimeKind.Utc以外的任何东西,并指定除Utc之外的TimeZone,转换函数将抛出异常.这必须是这里发生的事情.在你的代码中,你应该检查DateTime是否已经在Utc中,如果是,则跳过转换.

此外,由于您传入的dateTime将附带一个DateTime,您可能不需要传入一个单独的Kind参数.

从docs

Converts the time in a specified time
zone to Coordinated Universal Time
(UTC).

意味着它从提供给Utc的时区转换

该函数抛出一个参数异常:

dateTime .Kind is DateTimeKind.Utc and
sourceTimeZone does not equal
TimeZoneInfo.Utc.

-or-

dateTime .Kind is DateTimeKind.Local
and sourceTimeZone does not equal
TimeZoneInfo.Local.

-or-

sourceTimeZone .IsInvalidDateTime( dateTime ) returns true.