如何在PHP中实现类似MySQL提供的0起始周数计算功能?
PHP实现MySQL WEEK函数mode=1规则方案
可以实现与MySQL WEEK(date,1) 完全等价的周数计算逻辑,你现有逻辑已覆盖大部分1月日期判为第0周的场景,只需补全边界判断即可。
核心对齐规则
MySQL WEEK 函数模式1的计算规则:
- 周起始为周一
- 当年第1周要求至少包含4天属于当年
- 若1月首周不满4天,统一判定为第0周
- 若12月最后一周有至少4天属于下一年,判定为当前年的52/53周,而非下一年第1周
完整实现代码
推荐使用DateTime类实现,兼容性和准确性更高:
function mysql_week_mode1(string $date): int { $dt = new DateTime($date); $currentYear = (int)$dt->format('Y'); $currentMonth = (int)$dt->format('m'); $isoWeek = (int)$dt->format('W'); $isoWeekYear = (int)$dt->format('o'); // ISO周对应的所属年份 // 1月的ISO周属于上一年 → 判定为第0周 if ($isoWeekYear < $currentYear && $currentMonth === 1) { return 0; } // 12月的ISO周属于下一年 → 返回当前年总周数 if ($isoWeekYear > $currentYear && $currentMonth === 12) { $lastDayOfYear = new DateTime("{$currentYear}-12-31"); return (int)$lastDayOfYear->format('W') === 53 ? 53 : 52; } // 其余场景直接返回ISO周数 return $isoWeek; }
如果偏好strtotime写法,对应实现如下:
$date = strtotime('2021-01-01'); $currentYear = (int)date('Y', $date); $currentMonth = (int)date('m', $date); $isoWeek = (int)date('W', $date); $isoWeekYear = (int)date('o', $date); if ($isoWeekYear < $currentYear && $currentMonth === 1) { $week = 0; } elseif ($isoWeekYear > $currentYear && $currentMonth === 12) { $lastDayOfYear = strtotime("{$currentYear}-12-31"); $week = (int)date('W', $lastDayOfYear) === 53 ? 53 : 52; } else { $week = $isoWeek; }
测试验证结果
和MySQL返回结果完全一致:
mysql_week_mode1('2021-01-01')→ 0mysql_week_mode1('2019-01-01')→ 1mysql_week_mode1('2017-01-01')→ 0mysql_week_mode1('2024-12-30')→ 53(对应边界场景:12月日期归属下一年ISO周)
内容的提问来源于stack exchange,提问作者Rafał G.
相关产品推荐
相关产品推荐

