那些和闰年相关的 Bug
2020年是一個閏年(Leap Year),閏年是會出故障的。
常見的錯誤認知
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天,可能也會導致問題。
代碼如果假設1年永遠是365天,聲明了一個固定大小為365的數組,那在一年的第366天可能會發生數組越界。
數組越界如果發生在 C/C++ 語言編寫的代碼里,可能導致內存溢出攻擊漏洞。
閏秒
除了閏年,還有一個東西叫閏秒,詳情參考:
https://en.wikipedia.org/wiki/Leap_second
不過由于在阿里巴巴經濟體大部分同學平時相處的都是應用層代碼,處理的都是日月年,最多也就精細到小時和分鐘,閏秒對我們的影響相對小很多。閏秒對于GPS等一些對時間的精密度要求比較高的系統會影響比較大。
本文作者:
鄭子穎,花名南門,現任職螞蟻金服 國際事業群 質量和技術風險部 資深總監。上海交通大學計算機系碩士畢業后加入微軟,2018年加入螞蟻金服。從事軟件開發18年,工作重心主要圍繞著測試、質量以及工程效能。
有道無術,術可成;有術無道,止于術
歡迎大家關注Java之道公眾號
好文章,我在看??
總結
以上是生活随笔為你收集整理的那些和闰年相关的 Bug的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NYOJ 864 统计
- 下一篇: 再有人问你volatile是什么,把这篇