[ Обновление: спецификаторы форматирования - это не то же самое, что и строки формата; спецификатор формата является частью строки пользовательского формата, где строка формата является "запасом" и не предоставляет настройки. Моя проблема связана с спецификаторами, а не форматами]
Я пытаюсь выполнить конверсии DateTime roundtrip с строкой формата, которая использует спецификатор формата zzz, который, как я знаю, привязан к локальному времени. Итак, если я попытаюсь обойти поездку с датой даты UTC, она выдает исключение DateTimeInvalidLocalFormat, которое должно быть с этим текстом:
A UTC DateTime преобразуется в текст в формате, который является правильным только для локальных времен. Это может произойти при вызове DateTime.ToString с использованием спецификатора формата "z", который будет включать в себя локальное смещение часового пояса на выходе. В этом случае либо используйте спецификатор формата "Z" , который обозначает время UTC, либо используйте строку формата "o", которая является рекомендуемым способом сохранения DateTime в тексте. Это также может произойти при передаче DateTime для сериализации XmlConvert или DataSet. Если вы используете XmlConvert.ToString, перейдите в XmlDateTimeSerializationMode.RoundtripKind, чтобы сериализовать правильно. Если вы используете DataSet, установите DateTimeMode в объекте DataColumn в DataSetDateTime.Utc.
Основываясь на этом предположении, все, что мне нужно сделать, чтобы заставить мой код работать, это заменить "zzz" на "ZZZ", чтобы я мог стоять в формате UTC. Проблема заключается в том, что "Z" нигде не встречается в документации, и любая комбинация формата "Z" , которую я пытаюсь, то есть "Z" , "ZZ", "ZZZ", всегда просто преобразует экземпляр DateTime с теми, которые обрабатываются Z как литералы.
Кто-то забыл реализовать "Z" , не сообщая автору сообщения об исключении, или мне не хватает, как заменить действующее местное смещение по времени на "+0000" без взлома?
Пример кода:
// This is the format with 'zzzzz' representing local time offset
const string format = "ddd MMM dd HH:mm:ss zzzzz yyyy";
// create a UTC time
const string expected = "Fri Dec 19 17:24:18 +0000 2008";
var time = new DateTime(2008, 12, 19, 17, 24, 18, 0, DateTimeKind.Utc);
// If you're using a debugger this will rightfully throw an exception
// with .NET 3.5 SP1 because 'z' is for local time only; however, the exception
// asks me to use the 'Z' specifier for UTC times, but it doesn't exist, so it
// just spits out 'Z' as a literal.
var actual = time.ToString(format, CultureInfo.InvariantCulture);
Assert.AreEqual(expected, actual);