Использование DateTime. TryParseExact, не зная год

У меня есть метод, который (иногда) берет в строке в формате "dddd MMMM dd" (Понедельник 04 января) это должно быть проанализировано в DateTime. Я иногда говорю, потому что это может также быть передано в "Today" или "Tomorrow" как значение.

Код для обработки этого был достаточно прост:

if (string.Compare(date, "Today", true) == 0)
    _selectedDate = DateTime.Today;
else if (string.Compare(date, "Tomorrow", true) == 0)
    _selectedDate = DateTime.Today.AddDays(1);
else
    _selectedDate = DateTime.Parse(date);

Это работало до на полпути в течение декабря. Некоторые из Вас, вероятно, уже определили то, что пошло не так, как надо.

Это перестало бы работать в любую дату в Новый год с ошибкой:

"Строка не была распознана как допустимый DateTime, потому что день недели был неправильным".

Это становилось переданным "Monday January 04" который является допустимой датой на 2010, но не в 2009.

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

if (!DateTime.TryParseExact(date, "dddd MMMM dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out _selectedDate))
    if (!DateTime.TryParseExact(date + " " + (DateTime.Now.Year + 1), "dddd MMMM dd yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out _selectedDate))
        throw new FormatException("That date is not valid.");

Таким образом, это попытается проанализировать его с помощью текущего года, и если это будет неудачно, то это попробует еще раз использовать следующий год. Если это перестанет работать после этого, то это просто предположит, что это - недопустимая дата, потому что я только должен взволновать приблизительно 1 год заранее, но если бы у кого-либо есть более гибкое решение, я ценил бы его. (Отметьте, я не должен волноваться о проверке даты, которая передается в, это будет допустимо или для тока или для в следующем году).

6
задан Brandon 4 January 2010 в 23:30
поделиться

1 ответ

Сначала, ваше тестирование устройства должно было поймать это. Возможно, вы захотите вернуться к тестам, которые вы написали для этого метода, чтобы узнать из этого опыта, как более полно охватить вашу функциональность.

Во-вторых, есть ли какая-то конкретная причина, по которой вы используете String.Compare вместо String.Equals? Я считаю более читабельным следующее:

date.Equals("Today", StringComparison.InvariantCultureIgnoreCase);

Я думаю, что он более четко читает, что происходит (тем более, что нам не нужно запоминать, что означает последний параметр bool в String.Compare).

Теперь, чтобы понять суть вашего вопроса. Ваш метод идеально подходит и очень четко выражает логику. Однако я бы сделал один небольшой рефакторинг:

public DateTime ParseInThisYearOrNextYear(string s, out DateTime dt)
{
    if (!Parse(s, "dddd MM dd", out dt))
    {
        if (!Parse(s + " " + DateTime.Now.Year + 1, "dddd MM dd yyyy", out dt))
        {
            throw new FormatException();
        }
    }

    return dt;
}

bool Parse(string s, string format, out DateTime dt)
{
    return DateTime.TryParseExact(
        s,
        format,
        CultureInfo.InvariantCulture,
        DateTimeStyles.None,
        out dt
    );
}

Это разделяет ваш метод на две отдельные части функциональности и предотвращает повторение (CultureInfo.InvariantCulture и DateTimeStyles.None), делая тестирование и сопровождение немного проще. (Вероятно, вам нужно лучшее название метода, чем Parse; я выбрал короткое, чтобы полоса прокрутки не появлялась в окне кода здесь)

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

  1. Ввод - "четверг 31 декабря" (действителен для 2009 г.)
  2. Система переходит границу 1 января в 2010 г.
  3. Код выполняется и проверяет 2010 и 2011 гг. и то и другое не выполняется.

Просто нужно кое-что учитывать в зависимости от характера вашей системы.

8
ответ дан 16 December 2019 в 21:40
поделиться
Другие вопросы по тегам:

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