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