Существует ли более быстрый способ проверить, является ли это допустимой датой?

Существует ли более быстрый путь затем для простой ловли исключения как ниже?

try
{
    date = new DateTime(model_.Date.Year, model_.Date.Month, (7 * multiplier) + (7 - dow) + 2);
}
catch (Exception)
{
    // This is an invalid date
}
11
задан Jon Seigel 17 May 2010 в 13:39
поделиться

8 ответов

String DateString = String.Format("{0}/{1}/{2}", model_.Date.Month, (7 * multiplier) + (7 - dow) + 2),model_.Date.Year);

DateTime dateTime;
if(DateTime.TryParse(DateString, out dateTime))
{
    // valid
}

Как указано в комментарии GenericTypeTea, этот код не будет работать быстрее, чем у вас сейчас. Тем не менее, я считаю, что вы улучшаете читаемость.

15
ответ дан 3 December 2019 в 02:19
поделиться

Если ваша цель - избежать использования исключений, вы можете написать собственный метод проверки:

public bool IsValidDate(int year, int month, int multiplier, int dow)
{
    if (year < 1 | year > 9999) { return false; }

    if (month < 1 | month > 12) { return false; }

    int day = 7 * multiplier + 7 - dow;
    if (day < 1 | day > DateTime.DaysInMonth(year, month)) { return false; }

    return true;
}

Он выполняет большую часть того же проверки в качестве конструктора DateTime, который вы используете - он только пропускает проверку, чтобы увидеть, будет ли полученное DateTime меньше DateTime.MinValue или больше DateTime.MaxValue.

Если вы в основном получаете хорошие значения, это, вероятно, будет медленнее в целом: DateTime.DaysInMonth должен делать много того же, что и конструктор DateTime, поэтому он добавлял бы накладные расходы ко всем хорошим датам.

9
ответ дан 3 December 2019 в 02:19
поделиться

Хм... подумайте об этом так: класс model_ имеет свойство DateTime

model_.Date

, поэтому нет необходимости проверять год и месяц. Единственная сложная часть - это день месяца:

(7 * multiplier) + (7 - dow) + 2

Поэтому очень быстрый и эффективный способ проверить это (что лучше, чем бросать и ловить) - использовать метод DateTime.DaysInMonth:

if ((multiplier <= 4) && 
    (DateTime.DaysInMonth(model_.Date.Year, model_.Date.Month) < 
        (7 * multiplier) + (7 - dow) + 2))
{
    // error: invalid days for the month/year combo...
}

Еще одно преимущество - вам не нужно создавать новый DateTime только для проверки этой информации.

P.S. Обновил код, чтобы убедиться, что множитель <= 4. Это имеет смысл, поскольку любое значение >= 5 не пройдет тест DaysInMonth...

5
ответ дан 3 December 2019 в 02:19
поделиться

EDIT: Упс! DateTime.TryParse не выбрасывает исключение внутри. Я говорил из своих ягодиц! В любом случае...

DateTime.TryParse() вызовет внутреннее исключение и приведет к результату, идентичному коду в вашем вопросе. Если скорость важна, вам придется написать свой собственный метод.

Это может показаться большим количеством кода, но я думаю, что это будет быстрее, если вы ожидаете большой объем ошибок:

public bool GetDate(int year, int month, int day, out DateTime dateTime)
{
    if (month > 0 && month <= 12)
    {
        int daysInMonth = DateTime.DaysInMonth(year, month);
        if (day <= daysInMonth)
        {
            dateTime = new DateTime(year, month, day);
            return true;
        }
    }
    dateTime = new DateTime();
    return false;
}

Мой пример выше не будет обрабатывать все случаи (т.е. я не обрабатываю годы), но он укажет вам правильное направление.

2
ответ дан 3 December 2019 в 02:19
поделиться

Не знаю, как насчет быстрее, но

DateTime.TryParse()

должно делать то же самое.

Мне было бы интересно, если бы кто-нибудь мог сказать мне, быстрее ли это (с точки зрения процессорного времени), чем способ, описанный в вопросе.

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

Одно но: исключения бывают в исключительных случаях. Богоформатированные строки не являются исключительными, но ожидаемыми, поэтому TryParse более уместен.

Использование try / catch для проверки валидности является неправильным использованием и неправильным представлением об исключениях, особенно с универсальным уловом (последнее уже заставило меня часами искать, почему что-то не работает, и это много раз).

0
ответ дан 3 December 2019 в 02:19
поделиться

Если механизм синтаксического анализа не работает быстрее, то вы можете использовать немного более подробный метод проверки свойств объекта модели напрямую на наличие допустимых значений.

-1
ответ дан 3 December 2019 в 02:19
поделиться

Посмотрите на метод DateTime.TryParse

2
ответ дан 3 December 2019 в 02:19
поделиться
Другие вопросы по тегам:

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