Почему DateTime.ParseExact не может проанализировать вывод DateTime? - PullRequest
13 голосов
/ 23 июля 2010

Борясь с проблемами форматирования DateTime.ParseExact, я решил передать ParseExact выход из DateTime.ToString (), например:

DateTime date2 = new DateTime(1962, 1, 27);
string[] expectedFormats = { "G", "g", "f", "F", "D", "d", "M/d/yyy", "MM/dd/yyy", "MM-dd-yyy", "MMM dd, yyy", "MMM dd yyy", "MMMM dd, yyy", "MMMM dd yyy" };
bool parsed = false;

foreach (string fmt in expectedFormats)
{
    try
    {
        DateTime dtDateTime = DateTime.ParseExact(date2.ToString(fmt), fmt, new CultureInfo("en-US"));
        parsed = true;
    }
    catch (Exception)
    {
        parsed = false;
    }

    Console.WriteLine("[{0}] {1}", parsed,date2.ToString(fmt));
}

Это вывод:

[True] 1/27/1962 12:00:00 AM
[True] 1/27/1962 12:00 AM
[True] Saturday, January 27, 1962 12:00 AM
[True] Saturday, January 27, 1962 12:00:00 AM
[True] Saturday, January 27, 1962
[True] 1/27/1962
[False] 1/27/1962
[False] 01/27/1962
[False] 01-27-1962
[False] Jan 27, 1962
[False] Jan 27 1962
[False] January 27, 1962
[False] January 27 1962

Что мне нужно сделать, чтобы ParseExact проанализировал строки нестандартного формата? Неправильно ли я ожидал, что DateTime сможет принимать свой собственный вывод на основе той же строки формата?

Ответы [ 4 ]

11 голосов
/ 23 июля 2010

Это наглядно демонстрирует, что DateTime.ParseExact небезопасен при Datetime.ToString. Я не уверен, что это большая часть ответа, но проблема определенно связана с трехзначным форматом года yyy. С 1962 года нельзя представить 3 цифры ToString вынужден использовать 4 цифры. Очевидно, ParseExact не достаточно умен, чтобы полностью изменить эту логику, и вместо этого ищет ровно 3 цифры. Обходной путь должен использовать yyyy вместо yyy. Я отправлю это сообщение об ошибке на веб-сайт Microsoft Connect и посмотрим, что из этого выйдет.

0 голосов
/ 06 февраля 2014

Microsoft внедрила строковый формат для обхода DateTime.Вы используете формат «o» или «O».

Вам необходимо установить параметр стиля в DateTime.ParseExact на DateTimeStyles.RoundtripKind.

Для получения полной информации см .: http://msdn.microsoft.com/en-us/library/az4se3k1%28v=vs.110%29.aspx#Roundtrip

0 голосов
/ 24 июля 2010

Я взял ваш код, и достаточно изменить «гггг» на «гггг», чтобы вернуть им значение «ИСТИНА» (сначала воспроизведя «ЛОЖЬ», прежде чем я внес какие-либо изменения).

документация в MSDN неясна, но подчеркивает необходимость указания полной ширины каждого компонента (например, гггг, а не ггг) без инвариантной культуры:

http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx

Еслиformat - это шаблон пользовательского формата, который не включает разделители даты или времени (например, «yyyyMMdd HHmm»), использует инвариантную культуру для параметра провайдера и самую широкую форму каждого спецификатора пользовательского формата.Например, если вы хотите указать часы в шаблоне формата, укажите более широкую форму "HH" вместо более узкой формы "H".

0 голосов
/ 24 июля 2010

Я удивлен, увидев это, но документация на msdn гласит:

Вы можете указать один из стандартных спецификаторов формата даты и времени или ограниченную комбинацию пользовательского спецификатора формата даты и времени

http://msdn.microsoft.com/en-us/library/2h3syy57.aspx

Обновление

Вы можете использовать обходной путь, упомянутый в предыдущем ответе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...