乐于分享
好东西不私藏

Excel中日期的表示逻辑是什么?有1900年2月29日这一天吗?

Excel中日期的表示逻辑是什么?有1900年2月29日这一天吗?

‌Excel和WPS表格中的日期以1900年1月1日为起点(以下简称起点日),用数字1表示,也就是用数值1表示1900年1月1日,数值2表示1900年1月2日,以此类推,比如2026年1月1日等于数值46023,因为2026年1月1日是起点日开始后的46023天。此外,如果某个单元格的数字是0,设置单元格的格式为日期,则会转换显示为“1900年1月0日”。

可以看到,Excel表格中标准的日期本质上就是个正整数数值(0不是正常的日期,所以不算在内),只是用日期格式的外观显示为XXXX年XX月XX日,因此在表格中使用右键设置单元格格式就可以直接完成正整数和日期之间的转换。

而在表格中,负整数无法转换为日期格式;起点日以前的日期也无法转换为负整数,即起点日之前的日期只能是个文本格式。比如如果单元格中写“2026/1/1”,表格会自动将其变为日期格式(外观上仍是日期,但实质上已经转换为一个正整数),但是如果写的是“1826/1/1”,表格只能认定这是文本格式。所以起点日以后的日期是可以用表格函数做加减乘除的,因为这些日期本质就是正整数。当然这种乘法、除法一般不具备什么意义,比如A单元格是“1900年1月1日”,B单元格是“1900年1月2日”,C单元格设置函数=A×B,则C单元格结果将显示为2。

虽然乘法、除法缺乏意义,不过减法、加法是可以找到明确意义的,比如2026年1月1日-起点日=46022,也就是两者相距的天数;另比如起点日+46022=2026年1月1日,也就是某日经过指定天数之后是什么日期。

那么如果要计算起点日和目标日之间相差几天,却遇到目标日是起点日之前的日期(比如1899年1月1日)的情况,因为目标日无法转换为负整数,该怎样用函数来给日期做减法(或其它数值运算)呢?在Excel和WPS表格中,确实无法直接用函数直接给起点日以前的日期做数值运算,理由即前述提及的,起点日以前的日期只能是文本格式,无法进行数值运算,如果一定要计算只能借助其它软件工具,或者自制一张日期与数字之间的映射表做数值转换。

另外,表格中日期的正整数数值有上限,即2958465,也就是公元9999年12月31日,这之后的日期也只能是文本格式,而无法变成数值进行计算。也就是表格中数值表示的日期范围必须是1900年1月1日-9999年12月31日。

Excel表的这套日期表示逻辑还有个bug,而这个bug一直未被修正,如果我们在表格中输入1900年的最后一天即1900年12月31日,转换为数字格式后我们会发现显示的是366,实际上1900年只有365天,因为这一年并不是闰年(闰年的话有366天)。一般规定每4年设一个闰年,但同时规定能被100整除且不能被400整除的年份不设闰年,这样可以和地球绕太阳公转的时间(约365.2422天)尽可能接近,所以1900年能被100整除,但不能被400整除,并不是闰年。把1900年当作闰年这个错误是Lotus表格(8、90年代PC电子表格的行业霸主)犯的,微软做Excel的时候,Lotus表格已经是市场巨头,为了抢占市场,微软选择无缝兼容Lotus表格文件,主动继承了这个bug,没有去修复。今天这个bug已经积重难返,大概很难再修复了。

因为将1900年错判为了闰年,而闰年多的那1天是设置在2月份,也就是2月29日,所以Excel表格误加的那一天是1900年2月29日,即这一天在历史上是不存在的,但在Excel、WPS表格中是可以输入1900年2月29日并转换为正整数60的(即1900年1月的31天+2月的29天=60天),这一点读者可以在自己电脑上测试。

所以本文开头说到的2026年1月1日和起点日之间差46022天其实是不准确的,因为46022天中包括了错加的1900年2月29日这一天,实际相差天数应该是46021天

此外,1900年2月28日是星期3,3月1日是星期4,但是如果用WEEKDAY(计算目标日期为星期几)处理,前者结果为星期3,后者结果为星期5,也是因为多加了1900年2月29日这一天,而这一天被认为是星期4,所以1900年3月1日就变成星期5了。故从1900年3月1日以后用WEEKDAY计算的星期数就都出了问题,比如2026年1月1日是星期4,用WEEKDAY计算后显示是星期5。

也有看法认为这是因为WEEKDAY默认的一周的起始日是周日,该函数表达式为=WEEKDAY(日期单元格,[return_type]),[return_type]可以写1、2、3(3不太用,主要用于某些统计运算),[return_type]是1时(1是默认值,不写时默认就是1),周日作为一周的开头,也就是周日是星期1;[return_type]是2时,周1作为一周的开头,也就是周1是星期1。