簡體   English   中英

在不知道年份的情況下使用DateTime.TryParseExact

[英]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.InvariantCultureDateTimeStyles.None )使測試和維護更容易一些。 (你可能想要一個比Parse更好的方法名;我選擇了一個短的方法來防止滾動條出現在這里的代碼窗口中。)

作為最后一個警告(不知道您的系統的詳細信息),您可能還要考慮檢查前一年! 想象一下以下情況:

  1. 輸入是“12月31日星期四”(2009年有效)。
  2. 系統將1月1日的邊界滾動到2010年。
  3. 執行代碼並檢查2010年和2011年兩者都失敗。

根據系統的性質,可以考慮一些事項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM