.NET: Почему TryParseExact перестал работать на Hmm и Hmmss?

Я испытываю DateTime.TryParseExact метод, и я приехал через случай, который я просто не получаю. У меня есть некоторые форматы и некоторые предметы для парсинга этого, каждый должен соответствовать одному из форматов отлично:

var formats = new[]
     {
         "%H",
         "HH",
         "Hmm",
         "HHmm",
         "Hmmss",
         "HHmmss",
     };

var subjects = new[]
     {
         "1",
         "12",
         "123",
         "1234",
         "12345",
         "123456",
     };

Я тогда пытаюсь проанализировать их всех и распечатать результаты:

foreach(var subject in subjects)
{
    DateTime result;
    DateTime.TryParseExact(subject, formats, 
        CultureInfo.InvariantCulture, 
        DateTimeStyles.NoCurrentDateDefault,
        out result);

    Console.WriteLine("{0,-6} : {1}", 
        subject,
        result.ToString("T", CultureInfo.InvariantCulture));
}

Я получаю следующее:

1      : 01:00:00
12     : 12:00:00
123    : 00:00:00
1234   : 12:34:00
12345  : 00:00:00
123456 : 12:34:56

И к моему вопросу..., почему это перестало работать на 123 и 12345? Разве они не должны были становиться 1:23:00 и 1:23:45? Что я пропускаю здесь? И как я могу заставить это работать, поскольку я ожидал бы это к?


Обновление: Так, кажется, что мы, возможно, выяснили, почему это приводит вид к сбою. Походит H на самом деле захватывает две цифры и затем уезжает всего один в mm, который тогда перестал бы работать. Но, у кого-либо есть хорошая идея о том, как я могу изменить этот код так, чтобы я получил бы результат, который я ищу?

Другое обновление: Думайте, что я нашел разумное решение теперь. Добавленный это как ответ. Примет его через 2 дня, если кто-то еще не придумывает еще лучший. Спасибо за справку!

11
задан Svish 6 January 2010 в 21:39
поделиться

6 ответов

Хорошо, я думаю, что я понял все это теперь благодаря большему количеству чтения, экспериментов и других полезных ответов здесь. Происходит то, что H, m и s на самом деле захватывают две цифры, когда могут, даже если их не хватает на остальную часть формата. Так, например, при использовании формата Hmm и цифр 123, H хватало бы 12, а оставалось бы только 3. А мм требует две цифры, поэтому не получится. Tadaa.

Итак, моим решением на данный момент является использование вместо этого следующих трех форматов:

var formats = new[]
    {
        "%H",
        "Hm",
        "Hms",
    };

Поскольку остальной код из моего вопроса останется прежним, я получу в результате:

1      : 01:00:00
12     : 12:00:00
123    : 12:03:00
1234   : 12:34:00
12345  : 12:34:05
123456 : 12:34:56

Который, на мой взгляд, должен быть и разумным, и приемлемым :)

.
13
ответ дан 3 December 2019 в 05:58
поделиться

0123 012345

Я полагаю, что он ищет длину 2/4/6, когда находит такую строку чисел. 123 должно быть AM или PM? 0123 не так уж и двусмысленно.

3
ответ дан 3 December 2019 в 05:58
поделиться

Если вы не используете дату или время. разделители в пользовательском шаблоне формата, использовать инвариантную культуру для параметр провайдера и самая широкая форма каждого спецификатора пользовательского формата. Для например, если вы хотите указать часы в шаблоне, укажите более широкий "HH", а не более узкий. в форме "H"

цитаты: http://msdn.microsoft.com/en-us/library/ms131044.aspx

Как отмечали другие, Н является двусмысленным, поскольку подразумевает 10-часовой день, где НН равен 12

.
2
ответ дан 3 December 2019 в 05:58
поделиться

Для цитирования из MSDN с использованием спецификаторов единичного пользовательского формата :

Строка пользовательского формата даты и времени состоит из двух или более символов. Например, если строка формата состоит только из спецификатора h, то строка формата интерпретируется как стандартный спецификатор формата даты и времени. Однако в данном конкретном случае выбрасывается исключение из-за отсутствия спецификатора h стандартного формата даты и времени.

Для использования одного пользовательского спецификатора формата даты и времени необходимо включить пробел до или после спецификатора даты и времени или включить спецификатор формата в процентах (%) перед единственным пользовательским спецификатором даты и времени. Например, строки формата "h" и "%h" интерпретируются как пользовательские строки формата даты и времени, отображающие час, представленный текущим значением даты и времени. Обратите внимание, что при использовании пробела он отображается в строке результата в виде буквенного символа.

Итак, должно ли это быть % H в первом элементе массива форматов ?

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

1
ответ дан 3 December 2019 в 05:58
поделиться

Я могу ошибаться, но подозреваю, что это связано с неоднозначностью, присущей "H" части строки вашего формата - т.е., учитывая строку "123", вы можете иметь дело с часом "1" (01:00) или часом "12" (12:00); а так как TryParseExact не знает, что правильно, то возвращает ложь.

Что касается того, почему метод не дает "лучшей догадки": боюсь, что документация не на вашей стороне. Из документации MSDN по DateTime.TryParse (выделено мной):

Когда этот метод возвращает, содержит в себе Дата Время значение, эквивалентное дате. и время, содержащееся в s , если преобразование прошло успешно, или DateTime.MinValue if the конверсия не удалась. Преобразование не удается, если либо формат , либо . параметр null, является пустой строкой или не является содержать дату и время, которые соответствовать шаблону, указанному в format. Этот параметр передается неинициализированный.

1
ответ дан 3 December 2019 в 05:58
поделиться

"123" и "12345" представляются неоднозначными в отношении метода TryParseExact. "12345" может быть, например, 12:34:50 или 01:23:45. Только догадка.

0
ответ дан 3 December 2019 в 05:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: