2009-10-16 70 views
11

我們有以下格式的應用程序解析日期/時間值:Convert.ToDateTime導致出現FormatException上下午的日期/時間值

2009-10-10 09:19:12.124 
2009-10-10 12:13:14.852 
2009-10-10 13:00:00 
2009-10-10 15:23:32.022 

一個特定的服務器所有的突然(今天)的啓動未能解析任何時間13:00:00或更晚。這個特定的客戶端有五臺服務器,只有一臺有問題。我們有數十個其他客戶端,總共數百臺服務器沒有問題。

System.FormatException: String was not recognized as a valid DateTime. 
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles) 
at System.DateTime.Parse(String s, IFormatProvider provider) 
at System.Convert.ToDateTime(String value, IFormatProvider provider) 
at System.String.System.IConvertible.ToDateTime(IFormatProvider provider) 
at System.Convert.ToDateTime(Object value) 

我跑使用DateTime.Parse(S,CultureInfo.CurrentCulture)comapred到DateTime.Parse(S,CultureInfo.InvariantCulture)和問題只示出了一個的CurrentCulture測試。但是,CurrentCulture與所有其他服務器一樣是「en-US」,並且在區域或語言設置中沒有什麼不同。

有沒有人見過這個?有關我可以研究的建議?

編輯:謝謝你到目前爲止的答案。然而,我正在尋找什麼樣的配置進行研究,這可能會導致它突然改變行爲,並在多年的工作中停止工作,並在數百臺其他服務器上運行。我已經改變了它的下一個版本,但我正在尋找一個配置更改,以在當前安裝的過渡期修復此問題。

回答

3

我們也遇到了同樣的問題。只需回收您的應用程序池。

+0

是的,但是...爲什麼?我們偶爾也有同樣的問題。我們的Web服務將C#DateTime對象轉換爲字符串,並將其傳遞給SQL Server數據庫過程,該過程需要一個smalldatetime。出於某種原因,有時這會將時間轉移12小時,因此發送今天的日期會在今天中午(中午12:00:00)而不是今天午夜(中午12:00:00)發生。 – 2012-10-10 20:46:48

0

聽起來好像文化對象不懂軍事時間表示法。我真的不知道該從哪裏出發,但它可能會給你一個起點。

7

如果您完全瞭解格式,請告訴應用程序它是什麼 - 使用DateTime.ParseExact而不是僅僅使用DateTime.Parse。 (正如其他人所說,指定不變文化爲好,帶走任何更多的變化。)這就給了你更多的控制:

using System; 
using System.Globalization; 

class Test 
{ 
    static void Main() 
    { 
     Parse("2009-10-10 09:19:12.124"); 
     Parse("2009-10-10 12:13:14.852"); 
     Parse("2009-10-10 13:00:00"); 
     Parse("2009-10-10 15:23:32.022"); 
    } 

    static readonly string ShortFormat = "yyyy-MM-dd HH:mm:ss"; 
    static readonly string LongFormat = "yyyy-MM-dd HH:mm:ss.fff"; 

    static readonly string[] Formats = { ShortFormat, LongFormat }; 

    static void Parse(string text) 
    { 
     // Adjust styles as per requirements 
     DateTime result = DateTime.ParseExact(text, Formats, 
               CultureInfo.InvariantCulture, 
               DateTimeStyles.AssumeUniversal); 
     Console.WriteLine(result); 
    } 
} 
2

的解決方案很簡單,使用CultureInfo.InvariantCulture。對於唯一明智的事情來說,樣本數據。

我知道這並不能解釋其中的差異,但是您的軟件確實不應該依賴'默認'文化(除了可能在UI中)。

+1

即使使用不變文化,我也不會依賴於默認格式 - 明確指定格式,那麼它就很清楚您的期望。 – 2009-10-16 19:17:00

0

CultureInfo.DateTimeFormat屬性的價值是什麼? According to MSDN

「的用戶可能會選擇重寫 一些通過 區域和語言選項部分控制面板的 與Windows的 當前區域性關聯的值。例如,在 用戶可以選擇。以不同的格式顯示日期 或使用 貨幣以外的默認 培養。

如果UseUserOverride爲真並且 指定培養CUR匹配租 文化的Windows,CultureInfo的 使用這些替代,包括用戶的 的DateTimeFormatInfo實例的屬性 設置返回:由DateTimeFormat屬性 ,並 由NumberFormat的 屬性返回的NumberFormatInfo 實例的屬性。如果用戶設置是 與CultureInfo相關聯的培養 不相容,用於 例如,如果選定的日曆的OptionalCalendars的 不是一個,所述方法的 結果的值和屬性的 是不確定的。

直到您的 應用程序訪問該屬性,纔會計算DateTimeFormat 屬性和NumberFormat屬性 的值。如果 的 應用程序運行時,用戶可以改變當前 培養到新的培養,然後將 應用訪問 DateTimeFormat或NumberFormat的 屬性,應用程序檢索 新培養 默認值代替的替換值原始文化的 。爲了保持 覆蓋原始當前 文化,應用程序應該改變當前 培養前訪問 的DateTimeFormat和NumberFormat的 性能。」

難道是有些用戶設置壓倒一切的呢?

0

這是胡亂猜測,但也許像這一系列事件可能造成的問題:

  1. 管理員進入續在所有服務器上滾動面板國際設置並將時間格式從「HH:mm:ss」更改爲「hh:mm:ss tt」。
  2. 管理員僅在其中一臺服務器上回收應用程序池(或IIS服務或計算機)。

回收服務器上的所有新ASP.NET工作線程現在都會看到更改的時間格式,並且它們的DateTime.Parse方法將失敗。但是,如果其他服務器仍在使用原始工作線程,則他們尚未檢測到對當前文化DateTimeFormatInfo的更改。

這是一個非常不可能的情況,但是再一次,你有一個非常不可能的情況。您可以嘗試回收所有服務器上的相關應用程序池並查看是否有任何更改。

3

我們在Windows 2003服務器上運行C#.NET 2.0 Web服務。該服務已運行兩年多。我們最近在該應用程序中遇到了錯誤。錯誤消息是「字符串未被識別爲有效的日期時間」。另一個Web役返回日期,以及函數應該返回一個值一樣

「5/10/2010 12:00:00 AM」

當錯誤發生的函數返回

「5/10/2010 12:00:00」

不正確的回報具有在最後也沒有AM空白。

此問題在接下來的幾周內出現並消失了好幾次。檢查Windows日誌後,我們注意到錯誤的開始和結束時間與(默認情況下)每29小時發生的應用程序池回收週期(一兩分鐘內)一致。此問題僅發生在生產Web服務器上,而不在開發或測試服務器上。我們嘗試更換服務器,並且一個月內沒有錯誤。現在錯誤又重新開始了。我們手動重置池並且問題立即消失。我們不會認爲這是一個可以接受的解決方案,因爲池會定期回收。我們不知道我們是否需要回收池,但我們的理解是定期回收有助於提高應用程序的性能。

Web應用程序使用ParseExact()了,但格式字符串看起來是這樣的:

「YYYY-MM-ddHH:MM:ss.0Z」

,而不是

「YYYY-MM-DD HH:MM:SS」

所建議喬恩Skeet在這個線程。我不知道這是否會產生很大的影響。

我們還檢查了培養設置。

似乎很清楚,問題始於應用程序池回收,但我不知道在回收期間發生了什麼。大多數情況下,回收沒有負面影響,並且當發生錯誤時,下一次回收始終會停止錯誤。

+0

@丹布魯頓 我們還沒有修復它。自從我寫這篇文章以來,這個問題又被踢了幾次,回收也暫時解決了這個問題。我們正在考慮改變回收的時間,以確保它在每週的同一時間發生,並且我們已經做好準備,但我們仍然不知道真正的問題是什麼。我們也與微軟合作過,他們似乎沒有比我們更好的想法。 – 2010-06-11 16:47:10

+0

對此有任何其他更新?我親眼目睹了這個同樣的問題,並在發生這種情況時記下了這個過程。我在那裏看到的是將日期時間存儲爲通用對象,然後將其作爲日期時間丟失文化信息(非常隨機,當然...看起來不可能重現),將其拉回。 – mpeterson 2011-01-20 15:26:32

1

我剛剛發現了一些有關導致此問題的信息。我們的C#客戶端將一個業務日期(僅限日期)作爲字符串值發送給Web服務。 Web服務將此字符串在SqlParameter中傳遞給SqlCommand,以存儲過程接受商務日期的datetime參數。

客戶的系統突然行爲異常。我使用SQL Server Profiler來觀察RPC調用,並注意到date參數突然有一個時間組件。這應該是僅限日期的值 - 即10/27/2012 12:00:00 AM。

我修改了存儲過程以添加一個WAITFOR DELAY '00:01:00'。然後我在調用這個存儲過程時獲得了Web服務的內存轉儲。

檢查內存轉儲,我發現客戶端在參數的DataSet中傳入了正確的日期字符串「2012-10-25 00:00:00」。當Web服務調用存儲過程時,Web服務以某種方式搞砸了這些日期的轉換。我在轉儲中找到了SqlCommand,並檢查了與存儲過程的日期參數相對應的SqlParameter。值爲「2012年10月25日12:00:00 PM」。

看着所有的CultureInfo對象,我發現「en-US」的語言環境1033有很長一段時間的字符串「h:mm:ss tt」。 AMDesignator是「AM」,但是PMDesignator是是一個空字符串!我確認這是在C#中劣棗的原因通過運行以下命令:

// clear the PM designator 
System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator = "" 
// this will yield "12/25/2012 12:00:00 " (note the extra space at the end) 
Convert.ToDateTime("10/25/2012").ToString() 

,結果是「2012年10月25日12:00:00」這相當於什麼布賴恩·貝格利在他的回答。使用不變格式會產生非常相似的結果:

// clear the PM designator 
System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator = "" 
// this will yield "10/25/2012 12:00:00" 
Convert.ToDateTime("10/25/2012").ToString(System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) 
// restore the PM designator to "PM" 
System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator = "PM" 
// this will yield "10/25/2012 00:00:00" 
Convert.ToDateTime("10/25/2012").ToString(System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) 

我還沒有確定是什麼導致CultureInfo被破壞。

請注意,Microsoft is aware of this issue。鏈接文章說,它只適用於Windows Server 2003,並有一個修補程序可用。

+0

+1有趣的信息和類似的問題。 – 2012-10-28 04:15:22

相關問題