一个软件中的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的更多相关文章

  1. EXCEL日期间隔函数

    =DATEDIF(D3,TODAY(),"M") 日期一列有逗点,有横线,excel建议日期用横杠. 首先将日期列选择日期格式. 其次通过查找替换,将.换为- 之后用=DATEDI ...

  2. php读取excel日期类型数据的例子

    提供一个读取的函数:  代码如下 复制代码 //excel日期转换函数function excelTime($date, $time = false) { if(function_exists('Gr ...

  3. C# 读取Excel日期格式

    读取Excel日期数据,一种方式是在EXCEL中把你的日期列的格式设置一下,设成"文本"型. 如果单元格格式设置为date,则在后台读出的数值是一个数值,如2008-08-08读出 ...

  4. pandas,pd.ExcelWriter保存结果到已存在的excel文件中

    背景:pandas支持将DataFrame数据直接保存到excel中   保存的case如下: import pandas as pd with pd.ExcelWriter('a.xls') as ...

  5. 解决excel日期变成数字的问题

    在Excel中如果单元格的公式是日期格式,那么引用后的数值是错误的[不是日期格式而被转换成数字类型了],这种情况显然不是我们想要的结果 解决办法: 在公式中强制转成文本类型即可(="Date ...

  6. [Python]将Excel文件中的数据导入MySQL

    Github Link 需求 现有2000+文件夹,每个文件夹下有若干excel文件,现在要将这些excel文件中的数据导入mysql. 每个excel文件的第一行是无效数据. 除了excel文件中已 ...

  7. excel日期插件

    效果图 Private Sub DTPicker1_Click() ActiveCell.Value = DTPicker1.Value DTPicker1.Visible = False End S ...

  8. 如何将Excel日期快速转化为文本格式?

    Excel表中日期格式其实是数值,有时候需要原样转成文本,有时候也要将文本转成日期. 我发现了一个方法,估计是最快的了.不需要用那一堆year() month()之类的函数. 快速将日期格式转化为文本 ...

  9. 将Excel表中的数据导入MySQL数据库

    原文地址: http://fanjiajia.cn/2018/09/26/%E5%B0%86Excel%E8%A1%A8%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E5% ...

随机推荐

  1. fixed 和 absolute 定位的区别

    fixed:固定定位           absolute:绝对定位 在没有滚动条的情况下两者其实没有差异.但是在有滚动条后,fixed始终会在定好的位置不动,而absolute会随参照对象元素的宽高 ...

  2. [python]多线程模块thread与threading

    Python通过两个标准库(thread, threading)提供了对多线程的支持 thread模块 import time import thread def runner(arg): for i ...

  3. yum 出问题了

    今天用yum 安装ntp 的过程中用了 Ctrl+ z, 然后yum 再也不能使用了: error: rpmdb: BDB0113 Thread/process 6589/14060193936774 ...

  4. windows 搭建 IBM Hyperledger Fabric(超级账本)开发环境

    一.概述 Hyperledge fabric项目是IBM开源的区块链项目.Github地址:https://github.com/hyperledger/fabric 想对fabric有具体的认识,可 ...

  5. 【转】jquery-easyui中datagrid的单击删除此行

    最近在easyui的项目开发,easyui封装了许多方法,用起来很方便,但同时也遇到了不少的问题. 如果在datagrid中直接将index传给easyui自带的deletRow方法来删除当前点击行, ...

  6. disk.go

    package disk import "syscall" //空间使用结构体 type DiskStatus struct {     Size uint64     Used ...

  7. fileWriter.go

    package blog4go import ( "fmt" "path" "strings" ) // NewFileWriter ini ...

  8. MySQL 慢查询日志总结

    慢查询日志概念 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志 ...

  9. BZOJ_4726_[POI2017]Sabota?_树形DP

    BZOJ_4726_[POI2017]Sabota?_树形DP Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属 ...

  10. Django中用户权限模块

    Django中用户权限模块 1 auth模块 auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理. auth可以和admin模块配合使用, 快速建立网站的管理系 ...