Хотя MSDN говорит, что форматы «s» и «o» отражают стандарт, они, похоже, способны анализировать только его ограниченное подмножество. Особенно это проблема, если строка содержит указание часового пояса. (Ни для базовых форматов ISO8601, ни для форматов с пониженной точностью - однако это не совсем ваш случай.) Именно поэтому я использую строки произвольного формата, когда дело доходит до анализа ISO8601. В настоящее время мой предпочтительный фрагмент кода:
static readonly string[] formats = {
// Basic formats
"yyyyMMddTHHmmsszzz",
"yyyyMMddTHHmmsszz",
"yyyyMMddTHHmmssZ",
// Extended formats
"yyyy-MM-ddTHH:mm:sszzz",
"yyyy-MM-ddTHH:mm:sszz",
"yyyy-MM-ddTHH:mm:ssZ",
// All of the above with reduced accuracy
"yyyyMMddTHHmmzzz",
"yyyyMMddTHHmmzz",
"yyyyMMddTHHmmZ",
"yyyy-MM-ddTHH:mmzzz",
"yyyy-MM-ddTHH:mmzz",
"yyyy-MM-ddTHH:mmZ",
// Accuracy reduced to hours
"yyyyMMddTHHzzz",
"yyyyMMddTHHzz",
"yyyyMMddTHHZ",
"yyyy-MM-ddTHHzzz",
"yyyy-MM-ddTHHzz",
"yyyy-MM-ddTHHZ"
};
public static DateTime ParseISO8601String ( string str )
{
return DateTime.ParseExact ( str, formats,
CultureInfo.InvariantCulture, DateTimeStyles.None );
}
Если вы не возражаете против разбора строк без TZ (я так делаю), вы можете добавить строку "s", чтобы значительно увеличить количество изменений в покрытом формате.