You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP 用 mktime 生成月份数组时英国夏令时调表后出现重复3月无2月异常

异常成因

这个问题和RethinkDB的eachPosTime函数完全无关,核心是代码长期存在的参数依赖bug,刚好被英国夏令时切换的时间点触发暴露:

  • PHP的mktime()函数有明确的参数缺省规则:凡是调用时未手动传入的参数,会直接取当前系统本地时间对应的年、月、日值。你写的两个版本的函数里,调用mktime(0,0,0,$i)时,只传入了时、分、秒、月份四个参数,没有手动传入“日期”和“年份”两个值,这两个参数会自动使用当前系统的数值。
  • 英国2024年的夏令时切换节点是3月31日,切换完成后系统的本地时间中,“日”的数值固定为31,“年”为2024年。当循环到$i=2(要生成2月的时间节点)时,mktime实际拿到的参数组合是:时0、分0、秒0、月2、日31、年2024。
  • 2024年是闰年,2月最多只有29天,根本不存在2月31日这个时间点。PHP内部对mktime的时间计算会自动做归一化:超出当月天数的时间会顺次向后顺延,2月29日之后剩余的2天偏移,会直接滚到3月2日。这就导致循环到2月的位置时,计算出来的月份实际是3月;等循环到$i=3时,正常取到3月的日期,最终结果就出现了两个3月、完全缺失2月的异常。
  • 为什么之前运行正常?因为在夏令时切换前,英国本地时间的系统“日”值始终小于30,无论循环到哪个月份,用当前的日值计算时间都不会超出当月的最大天数,不会触发跨月偏移。只有当系统进入3月31日这个有31号的日期、恰逢夏令时切换,才把这个潜藏的bug触发出来。你之前尝试修改的第二版函数,依然在调用mktime(0,0,0,$m)时没有手动传入日期、年份参数,还是在依赖系统当前的日值做计算,所以问题不会有任何改善。
修复方案

核心思路是彻底去掉mktime对系统当前参数的隐式依赖,手动传入明确、固定的计算基准值,从根源上避免时间越界:

  • 最直接的改法:手动固定传入每个月的参考日期(统一取每月1号即可)和参考年份,不要依赖函数的缺省参数,示例代码:
    function months($month_format="F") {
        $array = array();
        // 固定取当前年作为参考基准
        $reference_year = date("Y");
        for ($i = 1; $i <=12; $i++) {
            // 手动传全所有参数,不再依赖缺省的日、年值
            $timestamp = mktime(0,0,0,$i, 1, $reference_year);
            $array[$i]['string'] = date($month_format, $timestamp);
            $array[$i]['int'] = date('m', $timestamp);
        }
        return $array;
    }
    
  • 更稳妥的替代写法:直接用PHP原生的DateTime类构造固定日期对象,完全绕开mktime的参数归一化坑,也能兼容不同时区、夏令时的边界场景,示例代码:
    function months($month_format="F") {
        $array = array();
        $reference_year = date("Y");
        for ($i = 1; $i <=12; $i++) {
            // 直接按固定模板构造日期,不读取任何系统当前的可变时间值
            $dt = new DateTime("$reference_year-$i-01");
            $array[$i]['string'] = $dt->format($month_format);
            $array[$i]['int'] = $dt->format('m');
        }
        return $array;
    }
    

额外提示:这个bug的本质是代码对隐式参数的滥用,和夏令时时钟拨快本身没有直接因果关系,哪怕不切换夏令时,只要系统时间走到当月有31号的日期,循环到天数不足31天的月份(比如2月、4月、6月、9月、11月)时,都会触发同类的跨月偏移问题。

内容的提问来源于stack exchange,提问作者AGradePHP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 06:36:09