• 诡异的DateTime.TryParseExact方法


    老赵在介绍Routing扩展的WebCast中出了点“小状况”,即将DateTime.ToString(“yyyy-MM-dd”)修改为DateTime.ToString(“yyyy/MM/dd”)后,页面中仍然显示为yyyy-MM-dd样式的日期格式。相信看过WebCast的同学都还记得吧。我不解,将老赵代码中DateTimeFotmatter的Formate属性修改为yyyy/MM/dd,在页面中输入yyyy-MM-dd样式的日期,仍然没有抛出任何异常。这是怎么回事?难道日期转换失灵了吗?

    老赵在做日期转换时,使用了DateTime.TryParseExact,那么我们就来看看这个TryParseExact是否在正常工作。

    DateTime output;
    DateTime.TryParseExact("2009-06-04", "yyyy/MM/dd", null, DateTimeStyles.None, out output);
    Console.WriteLine(output.ToString());

    以上代码的输出结果果然让人大跌眼镜,日期居然能正确转换!

    image

    难道TryParseExact的第二个参数format没有作用吗?将/改成.,居然又不能转换了:

    image

    看来是/这个符号的问题。请出Reflector,将mscorlib.dll反编译,找到DateTime.TryParseExact方法,一步一步跟进去。发现如果该方法的IFormatProvider参数为null,将获取当前线程的CultureInfo的DateTimeFormat属性作为IFormatProvider,然后在DateTimeParse.ParseByFormat方法中,遇到format参数的/字符时,会比较输入日期字符串的当前字符是否为当前DateTimeFormatInfo的DateSeperator,如果是,则返回true,即允许转换,如果不是则返回false。

    CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
    Console.WriteLine(cultureInfo.DateTimeFormat.DateSeparator);

    而以上代码输出的恰恰为-,也就是说当前线程的区域信息中,日期分隔符即为-,因此,转换得以成功。

    如果您使用

    DateTimeFormatInfo dtfi = new CultureInfo("zh-CN", false).DateTimeFormat;
    DateTime output;
    DateTime.TryParseExact("2009-06-04", "yyyy/MM/dd", dtfi, DateTimeStyles.None, out output);
    Console.WriteLine(output.ToString());

    则转换失败,因为在初始化CultureInfo时,第二个参数为false意味着不使用用户选定的区域性设置,而使用默认的设置,这时的DateSeparator为/

    至此,谜底全部解开。

    // 小贴士:遇到.NET Framework内部实现的问题时,使用Reflector反编译类库并查看源代码的方式,往往可以解决您的问题:)

  • 相关阅读:
    Tomcat December 31,2019
    XML
    Java
    mysql8.0.16安装(补) September 24,2019
    乱码中的编码和解码
    idea优化
    新版web.xml
    重定向和请求转发
    web下载文件设置的头信息
    响应状态码
  • 原文地址:https://www.cnblogs.com/kirinboy/p/1496258.html
Copyright © 2020-2023  润新知