У меня есть дата, сериализованная как строка "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.
Есть ли способ обойти это?
Ответ 1 · рейтинг 8 · Matt Johnson-Pint
Настоящая ошибка здесь в том, что 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.