Embora o MSDN diga que os formatos "s" e "o" refletem o padrão, eles parecem capazes de analisar apenas um subconjunto limitado dele. Especialmente, é um problema se a string contiver especificação de fuso horário. (Nem nos formatos ISO8601 básicos ou nos formatos de precisão reduzida - no entanto, esse não é exatamente o seu caso.) É por isso que uso seqüências de caracteres de formato personalizado quando se trata de analisar o ISO8601. Atualmente, meu snippet preferido é:
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 );
}
Se você não se importa de analisar cadeias sem TZ (sim), você pode adicionar uma linha "s" para aumentar bastante o número de alterações de formato cobertas.