PHP中Y-m格式日期验证对2月失效的问题排查与修复求助
解决DateTime::createFromFormat验证Y-m格式日期时的溢出问题
嗨,这个坑我之前踩过!咱们先搞清楚为啥会出现这个问题,再给你修复方案。
问题根源
你用DateTime::createFromFormat('Y-m', '2011-02')的时候,PHP会自动补全缺失的「日」部分——它用的是当前服务器系统的日期。比如如果你的服务器当天是31号,那解析出来的日期其实是2011-02-31,但2011年2月只有28天啊!PHP的DateTime有个「自动溢出调整」的机制,会把不存在的日期自动往后推:2011-02-28再过3天就是2011-03-03,当你用Y-m格式输出时,就变成了2011-03,自然和原输入2011-02对不上,验证失败。
修复方案:用!前缀重置缺失字段
解决方法很简单,给你的格式字符串加上!前缀,它会强制把所有未被格式定义的字段(比如日、时、分这些)重置为Unix纪元的初始值(也就是日设为1,时间设为00:00:00),这样就不会依赖当前系统日期补全,也就不会出现溢出了。
修改后的验证函数如下:
function so_validate_date( $date, $format ) { // 加上!前缀,重置未指定的日期字段为初始值 $d = DateTime::createFromFormat('!' . $format, $date); return $d && $d->format( $format ) == $date; }
测试验证
再跑你原来的测试函数试试:
function test_validate_date( $date = '2011-02', $format = 'Y-m' ) { $d = DateTime::createFromFormat('!' . $format, $date); echo $d->format( $format ); // 现在输出2011-02,完全符合预期! }
额外说明
这个方法是通用的,不管你验证的是Y-m、m-Y还是其他不完整的日期格式,只要加上!前缀,就能避免因为系统当前日期导致的溢出问题。比如验证02-2011(格式m-Y),也不会再出现类似的月份跳转问题。
内容的提问来源于stack exchange,提问作者its_me
相关产品推荐
相关产品推荐

