У меня есть метод, который (иногда) берет в строке в формате "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 год заранее, но если бы у кого-либо есть более гибкое решение, я ценил бы его. (Отметьте, я не должен волноваться о проверке даты, которая передается в, это будет допустимо или для тока или для в следующем году).
Сначала, ваше тестирование устройства должно было поймать это. Возможно, вы захотите вернуться к тестам, которые вы написали для этого метода, чтобы узнать из этого опыта, как более полно охватить вашу функциональность.
Во-вторых, есть ли какая-то конкретная причина, по которой вы используете 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
; я выбрал короткое, чтобы полоса прокрутки не появлялась в окне кода здесь)
В качестве последнего предостережения (не зная подробностей вашей системы), вы, возможно, захотите рассмотреть возможность проверки и предыдущего года! Представьте себе следующую ситуацию:
Просто нужно кое-что учитывать в зависимости от характера вашей системы.