关于闰年bug的瓜

ragnar 10月前 ⋅ 232 阅读

昨日是2024年2月29日。今年的是闰年,二月有29天。

昨日闰年二月瓜

  • 消息称禾赛科技激光雷达存在固件bug,导致用了他家激光雷达的车,自动驾驶功能全部歇菜。
  • 哥伦比亚最大航空公司(阿维安卡航空公司 Aviance)打印的机票为3/1,而不是2/29。
  • 印度Fastrack公司发布的Fastrack FS1智能手表无法显示正确的日期。
  • 有用户无法购买 YouTube Premium 订阅。因为这些用户是闰日出生的,年龄验证逻辑认为他们未满18岁。
  • EA Sports 赛车游戏崩溃了。玩不了,根本玩不了,除非你将系统日期设置3月1日,否则这个闰年的2月29日就只能休息一下。

关于闰年的常见错误:

  • 弄错了闰年算法。
    • 闰年的计算方法是:“四年一闰,百年不闰,四百年再闰”
    • 闰年不是固定的每四年一次,对于不能被100整除的年份才是每四年一次,能被400整除的除外。1900年并不是闰年。
  • 为每个月使用天数数组,其中二月只有28天(也就是没考虑闰年有29天的情况)。
  • 针对闰年为代码创建分支,但没有测试所有代码路径。
  • 使用单独的年、月和日值,但却不对其进行验证。
    • 例如:有一单独下拉菜单控件的UI,用来选定每个组件。只测试某个日期在特定月份内是否有效是不够的,还要考虑年份。
  • 直接使用一年的平均天数,比如日期数学中的365.25天或者365.2425天。

怎么发现闰年bug?

  • 检查代码中,一切跟时间相关的内容,仔细梳理。
  • 对代码进行充分的单元测试,如何正确“模拟时钟”。
  • 全年测试,而只在闰年之前测试;
  • 验证所有输入,包括配置部分;

关于模拟时钟

模拟时钟 ===> 测试代码在不同日期下是否表现有别。
不同的编程语言有不同的实现。具体是:

  • 用于显示当前真实时间的系统时钟绝不可随意使用;
  • 把时钟视为一项服务(在DDD领域驱动设计意义上);

以java语言为例,在应用程序的逻辑处理不直接调用 LocalDateTime.now() 等直接返回日期类的方法,而是做一层封装,比如写一个日期时间的工具类。 ===> 这样单元测试就好覆盖了。。。

怎么避免出现闰年bug?

  • 编程时,涉及日期时间的计算,尽量用编程语言的API,尽量避免自己手写算法。
  • 用模拟时钟,写单元测试时全面覆盖。

参考

  • InfoQ的微信公众号文章《致敬昨晚熬夜改bug的技术团队!连OpenAI也躲不过:为什么几行代码能反复干翻大批软件》

全部评论: 0

    我有话说:

    目录