DateTimeConverter将UTC字符串转换为日期时间

7

我有一个日期序列化为字符串 "2012-06-20T13:19:59.1091122Z"。

使用 DateTimeConverter,它被转换为一个 DateTime 对象 {22:49:59.1091122},并将 Kind 属性设置为 "Local"。

例如:以下测试未通过:

    private static readonly DateTime UtcDate = new DateTime(634757951991091122, DateTimeKind.Utc);
    private const string UtcSerialisedDate = "2012-06-20T13:19:59.1091122Z";

    [Test]
    public void DateTimeConverter_Convert_From_Utc_String()
    {
        // Arrange
        var converter = TypeDescriptor.GetConverter(typeof(DateTime));

        // Act
        var result = converter.ConvertFrom(UtcSerialisedDate);

        // Assert
        Assert.AreEqual(UtcDate, result);
        Assert.AreEqual(DateTimeKind.Utc, ((DateTime)result).Kind);
    }

我对此有些惊讶...我本以为转换器返回的DateTime对象将是UTC时间。

文档确实说DateTimeConverter使用DateTime.Parse,但我猜它一定没有使用DateTimeStyles.RoundtripKind选项。

有什么解决办法吗?

1个回答

8
这里真正的问题在于没有传递任何DateTimeStyles的DateTime.Parse()仍然会看到“Z”,并认为应该解析为UTC。但是,想要让MS承认或修复这个问题可能会很困难。
你的代码示例所说明的特定问题是DateTimeConverter必须覆盖来自TypeConverter的方法,因此无法传递额外的参数,例如DateTimeStyles。很遗憾它没有实现这种属性的静态或线程静态版本。它确实利用了线程的Culture.CurrentCulture,但是DateTimeStyles是与文化不同的东西,所以这是另一条死路。
我假设你被锁定使用转换器而不是直接调用解析?这是一个硬性要求吗?如果不是,你可以这样做:
public static object ConvertFrom<T>(string value)
{
  if (typeof(T) == typeof(DateTime))
    return DateTime.Parse(value, null, DateTimeStyles.RoundtripKind);

  var converter = TypeDescriptor.GetConverter(typeof(T));
  return converter.ConvertFrom(value);
}

另一种方法是使用DateTimeOffsetConverter,它可以正确地理解时区Z。然后您可以使用结果的.UtcDateTime属性将其转换回具有UTC类型的DateTime。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接