玩转C科技.NET

从学会做人开始认识这个世界!http://volnet.github.io

导航

在浏览器的JavaScript里new Date().toUTCString()后,传递给C# DateTime().TryParse()会发生什么?

Format 1. Sun, 09 Oct 2016 13:24:35 GMT
Format 2. Sun, 9 Oct 2016 13:36:09 UTC

Format 1 是在IE里面产生的(Windows10下的Edge和IE已经使用Format2)
Format 2 是Edge/Firefox/Safari/Chrome等产生的格式(这么说不太严谨,应该带上版本号)
那么采用DateTime.TryParse,Format 1会报错,而Format 2会成功。

我们先看一下C#下DateTime的格式,打开TryParse的文档,很长,似乎看不懂。用ILSpy查一下源代码,在代码中,我们似乎只能找到GMT字眼,却找不到UTC字眼。

通过代码,我们知道了这样的格式,C#DateTime中微软遵循了RFC1123标准(从这里扒出来的线索),我们找到RFC1123 第5.2.14节文档,5.2.14 Date and Time Specification章节,发现它引用的是RFC822 第5节的内容,在里面关于zone的内容中,只提及了GMT作为关键字,并没有使用UTC的字眼。

但是在IE中微软toUTCString方法,仅提到了UTC时间,并没有提到Format 1和Format 2之间的差异以及版本变更,在IE的版本变更信息中也没有提及具体的变化细节。

我们尝试从其它浏览器的文档里面找到蛛丝马迹,于是来到了FireFox的官方文档。在文档中,我们找到了ECMAScript 5.1ECMAScript 6的文档,其实二者没有区别,只是一个已定稿一个是在草稿状态。它们提到的格式说明在这里。文中,提到是基于ISO 8601标准进行实现的。但是我们可以发现ISO 8601所定义的标准,大多是YYYY-MM-DDTHH:mm:ss.sssZ格式的,其中的Z并不是GMT也不是UTC。

注意到在IE9和其它浏览器中都支持toISOString方法,这个方法,返回的正是以上格式的数据。
再回到toUTCString的各种定义,我们会发现一句话叫:生成人类可读易读的格式,比如C# DateTime的ToString可以传递格式o或者r,而且除了RFC1123中明确提到GMT字眼外,其它地方并未提到UTC,既然是给人阅读的,人是聪明且智能的,GMT还是UTC大家都能看懂,但是我们的命题其实是给机器读的。这个时候,我们更建议使用ISO 8601的YYYY-MM-DDTHH:mm:ss.sssZ在不同的系统间进行传递,既能表现世界时,又能保证各种程序转换的正确性。

临时解决办法:

既然IE旧版中的toUTCString方法,所产生的数据仅是UTC字眼和GMT字眼的差异,那么在进行TryParse之前,替换一下字符即可。注意一点,在IE中,如果“日”为1位数的话,比如是10月9日,那么可能显示的是9 Oct,这个在ECMA的标准中,还是明确提到要补齐为“09”,不过对于C#的DateTime.TryParse,则没有什么影响。

posted on 2016-10-10 00:38  volnet(可以叫我大V)  阅读(794)  评论(0编辑  收藏  举报

使用Live Messenger联系我
关闭