[英]Using DateTime.TryParseExact without knowing the year
我有一個方法(有時)采用格式為"dddd MMMM dd"
(04年1月1日星期一)的字符串,需要將其解析為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);
這一直持續到12月中旬。 你們中的一些人可能已經發現了什么問題。
這將在新年的任何日期失敗並出現錯誤:
“字符串未被識別為有效的DateTime,因為星期幾不正確。”
它正在通過"Monday January 04"
2010年"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
中的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
更好的方法名;我選擇了一個短的方法來防止滾動條出現在這里的代碼窗口中。)
作為最后一個警告(不知道您的系統的詳細信息),您可能還要考慮檢查前一年! 想象一下以下情況:
根據系統的性質,可以考慮一些事項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.