专栏名称: 朱小厮的博客
著有畅销书:《深入理解Kafka》和《RabbitMQ实战指南》。公众号主要用来分享Java技术栈、Golang技术栈、消息中间件(如Kafka、RabbitMQ)、存储、大数据以及通用型技术架构等相关的技术。
目录
相关文章推荐
北京经信局  ·  2025全球数字经济大会首设欧洲分会场!3月 ... ·  19 小时前  
北京经信局  ·  2025全球数字经济大会首设欧洲分会场!3月 ... ·  19 小时前  
易简财经  ·  DeepSeek带飞阿里股价,阿里人连夜看豪宅 ·  昨天  
构力科技PKPM BIMBase  ·  央企担当 | ... ·  3 天前  
构力科技PKPM BIMBase  ·  央企担当 | ... ·  3 天前  
51好读  ›  专栏  ›  朱小厮的博客

那些和闰年相关的 Bug

朱小厮的博客  · 公众号  ·  · 2020-01-11 17:33

正文

点击上方“朱小厮的博客”,选择“ 设为星标”

后台回复” 1024 “获取公众号专属1024GB资料


来源:阿里巴巴中间件


2020年是一个闰年(Leap Year),闰年是会出故障的。 八年前,2012年2月29日,我在Azure的时候我们就出了一个大故障:
https://azure.microsoft.com/en-us/blog/summary-of-windows-azure-service-disruption-on-feb-29th-2012/

常见的错误认知


1、 一年总是365天
2、2月总是28天
3、闰年是每四年一次

其实,闰年并不是每四年一次。 2000是闰年,但1900年和2100都不是闰年。

哪里容易出闰年相关的Bug


1、在一个日期值上加或减时间的代码。尤其是加减1年或1个月的代码


2、各种根据数据库查询结果生成的报表和图标,月度和年度统计可能会少算1天
3、证书/密码/密钥/缓存 等的过期时间,可能会比预期的早了一天,或者可能设定了一个非法的过期时间
4、固定长度的数组。 例如,一个长度为365的数组遇到闰年可能就不够了,可能会数组越界。
5、UI组件,例如日历、日期选择组件,以及客户端输入校验相关的代码。

闰年的哪些日子要特别注意


2019年12月31日 这是闰年前一年的最后一天。 2019年的最后一天加365天,并不是2020年的最后一天,而会是2020年的倒数第二天(即2020年12月30日)。

2020年1月1日 闰年的第一天。 闰年的第一天加365天,并不是下一年的1月1日,而是今年的12月31日。

2020年1月31日: 这一天加28天,并不是下个月(2月)的最后一天。
2020年2月1日 这一天加28天,并不是下个月(3月)的第一天。
2020年2月28日 这是2月29日的前一天。 有问题的代码可能会错误的把这天当成2月的最后一天,试图加1天得到3月1日。 但实际上这一天加1天是2月29日。
2020年2月29日 这是闰年多出来的一天。 如果代码以为2月总是只有28天,那代码可能出现各种问题,例如:

入参校验会认为一个合法输入(2020/2/29)是非法的,用```{ year+1 , month , day }```的方式来加减1年的话会产生一个非法日期。

2020年3月1日 2月29日后面的那天。 代码如果在3月1日上减28天,会得到2月2日(而不是预期中的2月1日); 减365天的话会得到2019年3月2日(而不是预期中的3月1日)。

2020年12月31日 一年的第366天。

代码如果不能正确处理一年的第366天,可能也会导致问题。 例如,2008年12月31日,第三方软件中的问题导致了所有Microsoft Zune设备无法使用,详情参考:
http://www.theguardian.com/technology/blog/2009/jan/01/zune-firmware-mistake

代码如果假设1年永远是365天,声明了一个固定大小为365的数组,那在一年的第366天可能会发生数组越界。

数组越界如果发生在 C/C++ 语言编写的代码里,可能导致内存溢出攻击漏洞。


闰秒


除了闰年,还有一个东西叫闰秒,详情参考:
https://en.wikipedia.org/wiki/Leap_second







请到「今天看啥」查看全文


推荐文章