DateTime.Parse
пытается использовать несколько форматов - некоторые из них связаны с текущей культурой, а некоторые более инвариантны. Похоже, что это включает в себя попытку разобрать с форматом ISO-8601 "yyyy-MM-dd" - который действителен для вашего первого примера, но не для вашего второго. (В декабре нет 35 дней.)
Поскольку он пытается проанализировать несколько форматов, не обязательно имеет смысл выделять, какая часть является "неправильной" - разные части могут быть недопустимыми для разных форматов.
Как вы должны решить эту проблему, зависит от того, откуда поступают ваши данные. Если они предназначены для машиночитаемых данных, лучше применять инвариантный формат (в идеале ISO-8601), а не использовать DateTime.Parse
: укажите ожидаемый формат, используя DateTime.ParseExact
или DateTime.TryParseExact
. Вы по-прежнему не получите информацию о том, какая часть неправильна, но по крайней мере легче рассуждать. (Это также поможет узнать, какая календарная система используется.)
Если данные получены от пользователя, в идеале вы должны предоставить им какой-либо вид интерфейса календаря, чтобы они вообще не вводили текст. В этот момент только пользователи, которые вводят текст напрямую, будут вводить недопустимые данные, и вы можете считать это «нормальным» для них, чтобы получить общее сообщение об ошибке «это значение недопустимо».
Я не верю, что .NET предоставляет какое-либо указание на то, где значение было впервые признано недействительным, даже для одного значения. Noda Time предоставляет больше информации при разборе через исключение, но не в машиночитаемом виде. (Сообщение об исключительной ситуации содержит диагностическую информацию, но, вероятно, это не то, что нужно показывать пользователю.)
Короче говоря: вы, вероятно, не можете делать именно то, что вы хотите сделать здесь (без написания собственного анализатора или валидатора), поэтому лучше попытаться выработать альтернативные подходы. Написание валидатора общего назначения для этого было бы очень сложно.
Если вам нужно только для обработки дат ISO-8601, это относительно просто:
- Разбить ввод по тире. Если нет трех тире, это неверно
- Разбирать каждый фрагмент ввода как целое число. Может произойти сбой (на каждом куске отдельно)
- Подтвердите, что год - это год, с которым вы счастливы
- Подтвердите, что месяц находится в диапазоне 1-12
- Подтвердите, что день действителен для месяца (используйте
DateTime.DaysInMonth
, чтобы помочь с этим)
Каждая часть этого достаточно проста, но то, что вы делаете с этой информацией, будет зависеть от вашего приложения. У нас на самом деле недостаточно контекста, чтобы помочь написать код, не делая значительных предположений.