DateTimeConverter преобразование из строки UTC

У меня есть дата, сериализованная как строка «2012-06-20T13: 19: 59.1091122Z»

Используя DateTimeConverter, он преобразуется в объект DateTime {22: 49: 59.1091122} со свойством Kind установлен на «Местный».

например. Следующий тест не проходит:

    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.

Есть ли способ обойти это?


person David Gardiner    schedule 21.06.2012    source источник


Ответы (1)


Настоящая ошибка здесь в том, что DateTime.Parse () без каких-либо переданных DateTimeStyles все равно должен видеть "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 результата, чтобы вернуться к DateTime с типом UTC.

person Matt Johnson-Pint    schedule 17.09.2012