如何解决日期时间无效本地格式错误:"A UTC DateTime is being converted to text in a format that is only correct for loc



我得到这个错误,而在调试虽然ToString()被执行:

UTC DateTime被转换为文本格式,格式只有正确的当地时间。这可能发生在打电话的时候DateTime。使用'z'格式说明符的ToString,其中将包含一个输出中的本地时区偏移量。在这种情况下,要么用"Z"格式说明符,指定UTC时间,或使用'o'格式这是在文本中持久化DateTime的推荐方法。当传递要序列化的DateTime时也会发生这种情况XmlConvert或DataSet。如果使用XmlConvert。传入ToStringXmlDateTimeSerializationMode。正确序列化的RoundtripKind。如果使用DataSet,将dataccolumn对象上的DateTimeMode设置为DataSetDateTime.Utc .

public static string ToInterfaceString(this DateTime value)
{
    return value != DateTime.MinValue ? value.ToString("yyyy-MM-ddTHH:mm:sszzz") : string.Empty;
}

在我刚刚开始工作的应用程序中,它在许多地方使用这种格式。那么我该怎么做呢?把zzz换成Z?

更新1:传递给我的扩展的DateTime被初始化为:

DateTimeCreated = DateTime.UtcNow;

奇怪的是,如果我传递给这个扩展一些其他的DateTime对象,我没有收到任何错误/警告。

只是一个绿色警告

所以-你似乎知道你在做什么-你可以只是理解消息(这是正确的),并将复选框标记为忽略此警告在未来

正如DateTimeInvalidLocalFormat错误解释的那样,使用您定义的日期格式将日期值转换为字符串不能用于将属性Kind设置为'Utc'的DateTime。即使这个错误只是一个警告,您的代码应该仍然可以工作,但是在此操作之后您将得到的结果日期字符串将是不正确的。这意味着,如果您将日期转换为字符串,并尝试再次将其解析为DateTime,则得到的DateTime值将与原始DateTime值不同。差异将与您的时区与UTC时间的偏移量一样大。这是一个严重的错误,不应该被忽略,特别是当你的本地时间与UTC时间不匹配时。

的例子:

在这个例子中,我假设当地时区比UTC时间早2小时。

DateTime yourLocalTime = DateTime.Now;    // => 2020-05-15 08:00:00 => yourLocalTime.Kind = Local
DateTime yourTimeInUTC = DateTime.UtcNow; // => 2020-05-15 06:00:00 => yourTimeInUTC.Kind = Utc,  note hours, e.g. 6 vs 8
string dateFormat = "yyyy-MM-ddTHH:mm:sszzz";
string testDateLocal = yourLocalTime.ToString( dateFormat ); // 2020-05-15T08:00:00+02:00 - This is correct date and time
string testDateUtc = yourTimeInUTC.ToString( dateFormat );   // 2020-05-15T06:00:00+02:00 - This date and time is 2 hours behind your actual date and time

要使用日期格式正确打印日期和时间字符串,必须首先将UTC日期和时间转换为本地日期和时间:

string testDateUtc2 = yourTimeInUTC.ToLocalTime().ToString( dateFormat ); // 2020-05-15T08:00:00+02:00 - This is correct date and time

要修复您的代码,您应该在您的方法中添加对本地时间的转换:

public static string ToInterfaceString(this DateTime value)
{
    return value != DateTime.MinValue ? value.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:sszzz") : string.Empty;
}

您还可以通过将日期格式说明符'zzz'替换为'Z'来打印UTC日期和时间而不是本地日期和时间。然而,在这种情况下,你会有一个类似的转换问题,如果传递给你的方法的DateTime不是UTC类型,而是例如在本地类型,因此,你必须在生成字符串之前将其转换为UTC:

public static string ToInterfaceString(this DateTime value)
{
    return value != DateTime.MinValue ? value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") : string.Empty;
}

不进行转换的日期和时间打印也可以通过使用日期格式说明符'o'来完成,但是生成的日期字符串格式将根据所提供的DateTime类型而不同,并且该日期格式还包括毫秒。

public static string ToInterfaceString(this DateTime value)
{
    return value != DateTime.MinValue ? value.ToString("o") : string.Empty;
}

此异常被抛出并在ToString()方法内部捕获,因此应用程序将继续进一步运行。这是唯一显示这个的调试器。

它可能最初看起来像一个警告,只有在调试时才可见,但实际上,这段代码只会在的情况下生成有效的结果,当你的计算机时区是UTC(似乎在这种情况下也不会有内部异常)。例如,如果您的本地时区偏移量是UTC+02,则结果为:

new DateTime(2020,7,30,11,22,33, DateTimeKind.Utc).ToString(@"yyyy-MM-ddTHH:mm:sszzz");
你电脑上的

将会是"2020-07-30T11:22:33+02:00"这是没有意义的,因为结果显然应该有UTC偏移量为00:00。

当然,这样的内部异常对于控制流来说是一件坏事,如果这种情况经常发生,可能会影响应用程序的性能。

为了避免无效的。tostring()结果和内部异常,您可以从给定的DateTime创建DateTimeOffset并为其调用。tostring()。所以代码是:

new DateTimeOffset(new DateTime(2020,7,30,11,22,33, DateTimeKind.Utc)).ToString(@"yyyy-MM-ddTHH:mm:sszzz");

将给出预期结果"2020-07-30T11:22:33+00:00"

另一个建议是使用"为DateTime和DateTimerOffset提供正确结果的自定义格式说明符

相关内容

最新更新