PHP日期比较异常:为何5月1日被判定小于4月28日
异常产生的核心原因
代码出现判断偏差的根源和时间逻辑本身无关,核心问题有两个:
- 你当前代码里用来比较的两个值,根本不是时间类的数值,是按照
d-m-Y , H:i格式输出的纯文本字符串 - PHP中对字符串使用
<=这类比较运算符时,会按照逐字符的ASCII编码顺序做比对,这套规则和真实时间的先后逻辑没有任何关联
拿实际输出的字符串举例就一目了然:
- 接口返回的2021-04-28时间转成目标格式后,输出的字符串为
28-04-2021 , 06:30 - 5月1日当天的时间转成相同格式后,输出的字符串为
01-05-xxxx , xx:xx
逐位比对时,第一个字符位上,历史日期字符串的首字符是'2',当天日期字符串的首字符是'0','2'的ASCII编码值远大于'0',程序会直接判定历史日期的字符串“大于”当天的字符串,根本不会继续比对后面的月份、年份等和时间相关的内容,自然就走进了else分支输出false。
额外的避坑提醒:就算把输出格式换成把年份放在最前面的Y-m-d格式,手动把日期转成字符串再比较的写法本质依然不严谨——一旦出现格式不统一、本地化特殊字符、时区错位的情况,很容易再次触发判断异常,长期可维护性也很差。
正确的日期比较实现方案
以下是生产环境中通用的两种靠谱实现方式,完全不需要手动拼接格式化字符串做比对:
- 直接比对Unix时间戳
把所有需要比较的时间都通过strtotime()转成整数型的时间戳,直接比较整数大小即可,代码示例:
注:$api_date = '2021-04-28T06:30:00Z'; $previous_ts = strtotime($api_date); $today_ts = time(); if ($previous_ts <= $today_ts) { print_r('true'); } else { print_r('false'); }strtotime()会自动识别接口返回的带UTC时区标识(Z结尾)的ISO格式时间,按服务器配置的时区转成对应时间戳,不会出现时区错位问题。 - 用PHP内置
DateTime类实现比对
这类日期处理场景下,DateTime类是官方推荐的实现方式,自带时区处理、时间计算能力,类实例本身实现了比较接口,可以直接用比较运算符判断时间先后,完全规避字符串比对的问题,代码示例:$api_date = '2021-04-28T06:30:00Z'; $previous_date = new DateTime($api_date); $today_date = new DateTime(); if ($previous_date <= $today_date) { print_r('true'); } else { print_r('false'); }
内容的提问来源于stack exchange,提问作者LearnProgramming
相关产品推荐
相关产品推荐

