.NET平台下很多功能是根據本地化配置來的,如果沒有很好的注意這些就會出現錯誤,年少無知的時候總會寫出一些糟糕的代碼,更不幸的是那樣糟糕的時期還挺高產的,現在想挽救得付出很大的代價。
曾今看過這樣一段C/C++代碼:
#define ture true #define flase false #define viod void
當時就懵逼了,原來還能這么玩,當然這並不是什么好的技巧,不值得Get,純屬拿出來開下玩笑。
然而,就在今天我遇上了一個嚴重的問題,關於DateTime的ToString方法的問題!!!
比如下面這段測試代碼:
1 var dt = new DataTable(); 2 dt.Columns.Add("FTime", typeof(DateTime)); 3 dt.Rows.Add(DateTime.Now); 4 5 var value1 = dt.Rows[0][0]; 6 var formatTime1 = Convert.ToDateTime(value1); 7 var formatTime2 = Convert.ToDateTime(value1.ToString());
其中第7行代碼在特定情況下會失敗,報異常 該字符串未被識別為有效的 DateTime。
什么情況下呢?

修改了本地的日期格式,也就是當我本機設置日期格式為此格式時,DateTime 類型 ToString(不指定format的情況下),雖然很多情況下,我們經常會ToString("yyyy-MM-dd HH:mm:ss"),當時就如以上的測試代碼中,從DataTable讀出來的值是object,還需要強轉一下(請暫時忽略DBNull的情況),然而從我之前的代碼來看,我並沒有強轉,再指定format去ToSting(),按照以上設置ToString()后得到是 ,然而此時我再通過 Convert.ToDateTime("2016/1/5/星期二 16:43:43") 時就會報異常了,即使用Convert.ToDateTime(value1.ToString(), DateTimeFormatInfo.CurrentInfo) 依然無法解決問題。
然后就產生了這樣的想法:把ToString()的默認格式改掉!
這樣我不用改之前寫下的不合代碼啦!
這樣我就不用每次ToString都指定成 yyyy-MM-dd HH:mm:ss (其他自定義時間格式在我們目前的框架下保存到MySql中是有些問題的,慚愧)!
於是,我就研究了一下 DateTimeFormatInfo.CurrentInfo ↓↓↓

用了個非常笨的辦法,就一個個改這里面字段的值,然后在即時窗口里面用 DateTime.Now.ToString() 測試。
經測試發現,影響的關鍵在於generalLongTimePattern!!!
然而,寫代碼時才發現 generalLongTimePattern 是訪問不到的,甚至通過屬性 GeneralLongTimePattern 都無法給其設置值,我想可能是通過其他的方法來設置,但徘徊了一會MSDN和StackOverFlow都沒有找到答案。
不過這並不是問題,既然我可以在Visual Studio 中可以修改它的值:

那么我用反射依然可以做到!
於是就有了以下這段代碼:
//輸出未修改前本地化設置的ToString結果 Console.WriteLine(DateTime.Now); //還真沒測出DateTimeFormatInfo.CurrentInfo是NULL的情況,但是預防一下 if (DateTimeFormatInfo.CurrentInfo != null) { var type = DateTimeFormatInfo.CurrentInfo.GetType(); var field = type.GetField("generalLongTimePattern", BindingFlags.NonPublic | BindingFlags.Instance); //我慫!! if (field != null) field.SetValue(DateTimeFormatInfo.CurrentInfo, "yyyy-MM-dd HH:mm:ss"); }
測試運行結果:

至此,偷懶大功告成,回去玩PS4咯~~~~~
我猜其中必有槽點,您發現了但說無妨!
