修改DateTime ToString的默认格式

.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咯~~~~~

我猜其中必有槽点,您发现了但说无妨!

posted @ 2016-01-05 17:42  维思德软件  阅读(4875)  评论(5编辑  收藏  举报