诡异的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反编译类库并查看源代码的方式,往往可以解决您的问题:)

posted @   麒麟.NET  阅读(12328)  评论(2编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示