Excel日期中那个著名的bug

Posted 蒋国纲的技术博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Excel日期中那个著名的bug相关的知识,希望对你有一定的参考价值。

一个软件中的bug能够持续多久?答案不一,大多数bug在软件测试阶段就已经被干掉,又有许多死在Preview阶段,抑或正式上线后不久被干掉,有些则伴随软件终生,直到下一代产品发布才寿终正寝,而Excel的日期计算上面有个非常著名的bug,从Excel诞生的时刻起,一直存在,不管Excel已经更新换代几个版本,它依旧存在,并且会一直存在下去。
 
要重现这个bug非常简单,打开Excel(任意版本),选中一个单元格,格式化单元格:

选择日期格式,确定。

然后在此单元格中输入60,bug出现了:

60变成了1900年2月29日,事实上,1900年的2月并没有29日,1900年并不是闰年,虽然它能被4整除,但由于它的个位十位都是0,必须要被400整除才能算闰年。
 
这个bug今天依然大行其道,我为什么提起它?我今天真的中招了,我们在做Excel数据导入的时候,经常要将导入内容转为程序特定类型,比如转为程序的的DateTime类型,而我们从Excel中读取的内容则不固定,一个栏位命名应该是日期,但读进来是个整数,稍微搜索一下便知道,这个整数是从1900年1月1日算起的天数,1900年1月1日是1,1900年1月2日是2,这简单了,遇到这种情况,我只需要写出这样的代码即可:
 
DateTime value = new Date(1900, 1, 1) + TimeSpan.FromDays(valueFromExcel-1);
 
我尝试了几个日期,1900年1月1日,1900年1月31日,1900年2月1日,都没问题,但如果日期是2018年某天就不对了,我发觉按照我的做法,会导致计算结果多出一天出来,比如明明应该是2018年8月1日的,却偏偏变成了2018年8月2日。
 
这种不一致的原因大家都知道了,问题就出在那个1900年的2月29日上,当日期数值是60时,Excel的理解是1900年2月29日,而我们的程序并不认为这天是存在的,因此就理解为1900年3月1日,所以从60开始,总是比Excel里展示的多出一天。
 
解决方法很简单,多加个判断就行了,代码我就不写了。
 
令人惊讶的是,这么简单而显著的bug为什么会出现,并且还持续了这么长时间,还将一直持续下去?
 
《软件随想录》中提到了这个典故,作者Joel Spolsky曾为微软工作,开发了Excel的Basic脚本语言,比尔·盖茨还专门给他开了审查会,这个逼格真是够高的了,大家一起通过这本书的摘录来了解下这个典故。

看完这个相信大家对这个bug都有充分认识了,并不怎么严重,完全是最早的程序员为了方便而留下的bug,但后继修正又面临太多遗留问题,只好一直“兼容”着这个bug,通过这个故事我们也真的了解到了——比尔·盖茨真的非常了解技术,虽然你可以找出一些例子来说明“运营一家伟大的软件公司并不需要懂技术”,但了解技术本身难道对成功的运营一家伟大的软件公司没有帮助吗?
 

以上是关于Excel日期中那个著名的bug的主要内容,如果未能解决你的问题,请参考以下文章

excel2007为日期制作下拉菜单的方法步骤

excel表格日期下拉框制作教程

JS中已经知道一个日期如何获取7天后的那个日期

JS中已经知道一个日期如何获取7天后的那个日期

java中如何读取excel表格中的日期

POI处理Excel中各种日期格式问题