簡體   English   中英

C#中的DateTime的字符串以保存在SQL Server中

[英]String to DateTime in C# to save in SQL server

將“ 3月16日至17日”轉換為DateTime並將其保存到SQL Server時遇到問題。 看起來是“ 3月16日至17日”,讀作3月16日至3月17日,在我的情況下是無效的,但是C#DateTime.TryParse()將“ 3月16日-17日”視為2017年3月16日,這是錯誤的,並且將數據保存在SQL Server中。 SQL Server將“ 3月16日至17日”視為無效。 因此,有人可以告訴我如何在C#中使用SQL Server日期時間驗證。

感謝Ashwani

解析中

您可以使用DateTime.TryParseExact將字符串解析為DateTime,要求其格式正確。 這將消除您能夠將無效日期解析為DateTime實例的問題。

這是一個例子:

        DateTime dt;
        if (DateTime.TryParseExact("March 16", "MMMM dd", new CultureInfo("en-GB"), DateTimeStyles.None, out dt))
            Console.WriteLine(dt);

當省略年份時,TryParseExact將采用當前年份。 如果將“ 3月16日至17日”傳遞給該方法,它將失敗。 IFormatProvider參數是英語文化,因此我們可以將“ March”解析為一年中的第三個月。

您要注意,這與SQL Server的功能不同。 如何轉換日期將基於其排序規則設置。 我不建議這樣做,但是如果您確實確實需要精確地復制該功能,並從C#中使用它,則可以創建一個存儲過程,該存儲過程采用varchar,進行轉換,並返回DateTime-並從C#中調用它。

您還可以使用DateTime.TryParse方法來解析C#中的日期。 此方法還使用一個IFormatProvider,它告訴框架如何進行解析。 IFormatProvider由CultureInfo實現,因此,如果傳入與您觀察到所需行為的SQL Server排序規則相對應的CultureInfo,則解析結果很可能會相似。 最后,如果您對內置的可能性不滿意,則可以執行自己的IFormatProvider實現。

我的評論

真正的問題是您實際上兩次進行了從字符串到DateTime的驗證和轉換。 一旦使用C#,您就將該字符串發送到SQL Server,並再次對其進行轉換。 正如您指出的那樣,這勢必會給您帶來問題,因為兩個系統的解析方式相似,但在極端情況下的解析方式並不完全相同。

我認為您應該做的是在C#中進行驗證和解析,然后將生成的DateTime作為DateTime對象發送到SQL Server,因此SQL Server本身不需要進行解析。 您可以使用ADO .NET中的參數化查詢來執行此操作-如果您使用其他方式進行數據訪問,將有類似的功能。

聽起來好像該值根本不應該是DateTime。 相反,它應該是一個字符串(varchar / nvarchar)或兩個DateTime值(開始和結束)。 即,為什么要首先調用DateTime.TryParseDateTime.TryParseExact 如果要將它們存儲為日期,則需要強制用戶將它們輸入為日期(如示例中的兩個日期值),然后可以輕松地將它們存儲為日期。 如果要允許用戶輸入“ 3月16-17日”或“ 2010年春季”或“ 3月下半月”,請使用varchar或nvarchar數據類型。

編輯鑒於您在評論中所說的話,聽起來好像您正在將XML直接傳遞給SQL Server,並希望SQL Server解析日期。 不幸的是,正如您所發現的,SQL Server並不是一個很好的解析器。 IMO,在將XML傳遞給SQL Server之前,更容易用C#重建XML,驗證和解析日期和整數。 即,我將嘗試在SQL Server中盡可能少地進行這種類型的解析和驗證。 如果您仍然想走這條路,另一種解決方案是創建CLR函數(這意味着必須啟用CLR),該函數將為您提供與C#相同的日期解析功能。

編輯經過大量討論,聽起來問題在於C#的日期解析器對於您的目的而言太聰明了。 您想要的是使C#像SQL Server那樣使日期無效。 我可以想到幾種解決方法:

  • 將一長串允許的格式發送到DateTime.TryParseExact方法。 不利的一面是,就解析日期值而言,這要寬容得多。
  • 運行TryParse並驗證年份。 如果年份X超出今年的年份,則將其無效。
  • 尋找一種強制XML源強制執行日期的方法,以便僅發送有效日期。
  • 在將日期傳遞給TryParse之前,編寫一個例程來確定日期是否像16-17(雖然應該將03-16-17視為有效,因此您需要小心)這樣的日期。

除非您將數據推送到字符列中,然后在填充數據后使用SQL Server的IsDateCast函數填充DateTime列,否則嘗試實際使用SQL Server的日期解析將不會起作用。

我了解您不想限制用戶。 您聽起來好像在做這樣的事情:

mySqlCommand.CommandText = "UPDATE tbl SET date_field = @parm";
string maybeDate = "March 16-17");
DateTime dt;
if (DateTime.TryParse(maybeDate, dt)
{
    mySqlCommand.Parameters.AddWithValue("@parm", maybeDate)
}

你能代替嗎?

mySqlCommand.CommandText = "UPDATE tbl SET date_field = @parm";
string maybeDate = "March 16-17");
DateTime dt;
if (DateTime.TryParse(maybeDate, dt)
{
    mySqlCommand.Parameters.AddWithValue("@parm", dt); // <============
}

它認為17是2017年,因為可以用2位數字寫年份,嘗試將其強制為4

if (DateTime.TryParseExact("March 16-17", "MMMM dd YYYY", new CultureInfo("en-GB"), DateTimeStyles.None, out dt))

暫無
暫無

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

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