Как создать.NET DateTime из формата ISO 8601
Я нашел, как превратить DateTime в формат ISO 8601, но ничего не говорится о том, как сделать обратное в C#.
я имею 2010-08-20T15:00:00Z
и я хочу превратить его в DateTime
объект.
Я мог бы отделить части строки самостоятельно, но это похоже на большую работу для чего-то, что уже является международным стандартом.
7 ответов
Это решение использует перечисление DateTimeStyles, а также работает с Z.
DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);
Это печатает решение отлично.
Хотя 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", чтобы значительно увеличить количество изменений в покрытом формате.
using System.Globalization;
DateTime d;
DateTime.TryParseExact(
"2010-08-20T15:00:00",
"s",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out d);
Вот тот, который работает лучше для меня (версия LINQPad):
DateTime d;
DateTime.TryParseExact(
"2010-08-20T15:00:00Z",
@"yyyy-MM-dd\THH:mm:ss\Z",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal,
out d);
d.ToString()
производит
true
8/20/2010 8:00:00 AM
Это прекрасно работает в LINQPad4:
Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00Z"));
Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00"));
Console.WriteLine(DateTime.Parse("2010-08-20 15:00:00"));
Представляется важным точно соответствовать формату строки ISO для TryParseExact
работать. Я предполагаю, что Точное - это Точное, и этот ответ очевиден для большинства, но в любом случае...
В моем случае ответ Reb.Cabin не работает, так как у меня немного другой ввод в соответствии с моим "значением" ниже.
Значение: 2012-08-10T14:00:00.000Z
Там есть несколько дополнительных тысяч за миллисекунды, а может быть и больше.
Однако, если я добавлю некоторые .fff
в формате, как показано ниже, все в порядке.
Формат строки: @"yyyy-MM-dd\THH:mm:ss.fff\Z"
В VS2010 Immediate Window:
DateTime.TryParseExact(value,@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal, out d);
правда
Возможно, вам придется использовать DateTimeStyles.AssumeLocal
а также в зависимости от того, в какой зоне ваше время для...
DateTime.ParseExact(...)
позволяет вам сказать парсеру, что представляет каждый символ.