Подтвердить что ты не робот

С# TimeSpan.Parse недопустимый формат возвращает неверное значение вместо исключения

TimeSpan.Parse( "23:00:00" ) возвращает 23 часа.

TimeSpan.Parse( "24:00:00" ) возвращает 24 дня!

Я понимаю, что допустил ошибку в том, что допустимый диапазон часов равен 0-23. Но в течение минут и секунд, если вы попытаетесь проанализировать значение вне диапазона, вы получите исключение. В случае часов с пределами диапазона значение парсер неправильно предполагает, что вы означали дни вместо часов.

Может кто-нибудь объяснить это?

Этот пример здесь охватывает эту тему и указывает, что http://msdn.microsoft.com/en-us/magazine/ee309881.aspx

То же самое можно сказать и о TryParse. Я получаю 24 дня, несмотря на документы, в которых говорится, что синтаксический анализ не завершился.

http://msdn.microsoft.com/en-us/library/3z48198e

//            String to Parse                TimeSpan
//            ---------------   ---------------------
//                          0        00:00:00
//                         14     14.00:00:00
//                      1:2:3        01:02:03
//                  0:0:0.250        00:00:00.2500000
//             10.20:30:40.50     10.20:30:40.5000000
//        99.23:59:59.9999999     99.23:59:59.9999999
//        0023:0059:0059.0099        23:59:59.0099000
//                     23:0:0        23:00:00
//                     24:0:0   Parse operation failed.
//                     0:59:0        00:59:00
//                     0:60:0   Parse operation failed.
//                     0:0:59        00:00:59
//                     0:0:60   Parse operation failed.
//                        10:   Parse operation failed.
//                       10:0        10:00:00
//                        :10   Parse operation failed.
//                       0:10        00:10:00
//                     10:20:   Parse operation failed.
//                    10:20:0        10:20:00
//                       .123   Parse operation failed.
//                    0.12:00        12:00:00
//                        10.   Parse operation failed.
//                      10.12   Parse operation failed.
//                   10.12:00     10.12:00:00

Я нашел ошибку или я делаю что-то неправильно?

EDIT: Я тестировал это в LinqPad и использовал консольное приложение в .NET4 на 64-разрядной версии Windows 7.

            var result = TimeSpan.Parse("24:00:00");
            Console.WriteLine(result);
            result = TimeSpan.Parse("24:00:00", CultureInfo.InvariantCulture);
            Console.WriteLine(result);

Это приводит к:

24.00:00:00
24.00:00:00
4b9b3361

Ответ 1

Что происходит, так это то, что TimeSpan.Parse пытается разобрать ##:##:##, используя каждый из следующих форматов, чтобы остановить, как только получится:

  • hh:mm:ss (инвариантная культура)
  • d.hh:mm (инвариантная культура)
  • hh:mm:ss (локализованный)
  • d.hh:mm (локализованный, более подробная информация о "." ниже)

Итак:

  • 23:08:09 успешно анализируется как 0d 23h 8m 9s на шаге 1.
  • 24:08:09 успешно проанализирован как 24d 8h 9m 0s на шаге 4.

Если это не подходит вам, вы можете вместо этого использовать TimeSpan.ParseExact:

TimeSpan.ParseExact("23:00:00", "hh':'mm':'ss", null) // OK
TimeSpan.ParseExact("24:00:00", "hh':'mm':'ss", null) // OverflowException

ОБНОВЛЕНИЕ: В соответствии с документацией для TimeSpan.Parse,. между "d" и "hh" есть

Символ, чувствительный к культуре, который отделяет дни от часов. В инвариантном формате используется символ периода (..).

Тем не менее, я врывался в исходный код с Reflector, и получается, что в локализованном формате этот предполагаемый "чувствительный к культуре" символ всегда является двоеточием! Здесь выдержка из внутреннего свойства DateTimeFormatInfo.FullTimeSpanPositivePattern:

string separator = new NumberFormatInfo(cultureData).NumberDecimalSeparator;
this.m_fullTimeSpanPositivePattern = "d':'h':'mm':'ss'" + separator + "'FFFFFFF";