PHP中日期排序需先转时间戳或DateTime对象:strtotime()快捷但格式敏感,DateTime严格可控;原地排序用usort,大数组需缓存时间戳;ISO格式仅当等长补零时才可字典序排。

PHP中用 strtotime() 转换再排序最直接
PHP本身不识别日期字符串的大小关系,必须先转成可比较的数值(如时间戳),否则 sort() 或 usort() 会按字典序排,"2023-10-01" 会被当成比 "2023-9-30" 小——因为 "10" 的字符串比较小于 "9"。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 对每个日期字符串调用
strtotime($date),得到整型时间戳; - 用
usort()配合匿名函数比较时间戳; - 注意
strtotime()对格式敏感:它能可靠解析"Y-m-d"、"Y/m/d"、"m/d/Y"(取决于系统 locale),但对"d-m-Y"可能误判为m-d-Y; - 若数组里混有非法日期(如
"2023-02-30"),strtotime()返回false,需提前过滤或用DateTime::createFromFormat()做严格校验。
用 DateTime 类做严格解析和比较
当日期格式不统一,或必须拒绝模糊输入(比如用户提交的 "01-13-2023" 明显无效)时,DateTime 比 strtotime() 更可控。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 用
DateTime::createFromFormat('Y-m-d', $date)显式指定格式,失败返回false; - 在
usort()中先创建两个DateTime实例,再用比较它们的getTimestamp(); - 避免直接用
new DateTime($date)—— 它依赖自动推断,遇到"13/01/2023"在不同 PHP 版本或 locale 下行为可能不一致; - 如果数组很大(上万项),
DateTime实例化开销略高于strtotime(),但差异通常可忽略。
原地排序 vs. 生成新数组,选哪个?
多数场景直接改原数组即可,但要注意引用语义和性能边界。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 用
usort($dates, $callback)是原地排序,不改变原数组变量指向,但内容已重排; - 若需保留原始顺序副本,别用
$sorted = $dates; usort($sorted, ...)—— PHP 7+ 对数组是写时复制,安全; - 如果排序逻辑复杂(比如还要按优先级分组),考虑先用
array_map()预处理出[['date' => ..., 'ts' => ...], ...]结构,再排序,避免重复解析; - 切勿在回调里反复调用
strtotime():1000 个日期会调用 2000+ 次(比较是两两进行的),应提前映射好时间戳缓存。
ISO 8601 格式字符串可直接字典序排,但有陷阱
如果所有日期都是严格 Y-m-d(如 "2023-09-05")、Y-m-d H:i:s 或带时区的 ISO 格式(如 "2023-09-05T14:30:00+08:00"),理论上可以跳过转换,直接 sort($dates, SORT_STRING)。
但要注意:
- 必须确保所有字符串等长且补零:
"2023-9-5"会排在"2023-10-10"前面,因为"9""10" 字符串比较; - 时区信息不能省略:若混有
"2023-09-05T14:30:00Z"和"2023-09-05T14:30:00+08:00",字典序无法反映真实时间先后; - 这种做法省了转换开销,但牺牲了健壮性——一旦某条数据格式松动(比如多了一个空格或用了中文破折号),排序就错乱且难以排查。
DateTime 解析,也别赌输入格式永远整齐。时间相关的逻辑,错一点,排查成本远高于预防成本。



















