0

0

PHP strtotime() 日期时间解析错误:无效格式导致的问题与解决方案

DDD

DDD

发布时间:2025-12-05 13:26:15

|

780人浏览过

|

来源于php中文网

原创

PHP strtotime() 日期时间解析错误:无效格式导致的问题与解决方案

本文深入探讨了php `strtotime()` 函数在处理日期时间字符串时,因12小时制与24小时制混用而导致解析失败的问题。当输入字符串格式不规范时,`strtotime()` 可能返回unix纪元之前的日期(如1969年),而非预期的转换结果。教程将分析问题根源,并提供使用纯24小时制、正确12小时制以及更严格的`datetime::createfromformat()`方法来解决此类问题的实践方案。

在PHP开发中,strtotime() 函数因其强大的灵活性而广泛应用于日期时间字符串的解析。然而,当输入字符串的格式存在歧义或不规范时,strtotime() 可能会返回意料之外的结果,例如将日期解析为 1969-12-31 16:00:00。这种现象通常不是PHP的bug,而是由于对日期时间格式的误解导致解析器无法正确识别。

问题根源分析

strtotime() 函数尝试解析各种英文日期时间格式。当它遇到一个无法明确识别的字符串时,通常会返回 false。在某些PHP版本或操作系统环境下,false 在进行隐式类型转换时可能被视为 0,而 0 对应的Unix时间戳是 1970-01-01 00:00:00 UTC。由于时区偏移,这在本地时间可能显示为 1969-12-31 的某个时间。

问题的核心在于混淆了12小时制(AM/PM)和24小时制。例如,给定一个字符串 "2021-12-16 13:42:46 PM",strtotime() 会感到困惑。

  • 13:42:46 明确是一个24小时制的时间,其中 13 表示下午1点。
  • PM 是12小时制中表示下午的指示符,它通常与小时数 1 到 12 结合使用。

将 13(24小时制)与 PM(12小时制)同时使用,形成了一个语法上不一致的日期时间字符串。strtotime() 在尝试解析 13:42:46 PM 时无法理解这种混合格式,因此解析失败。

立即学习PHP免费学习笔记(深入)”;

以下是导致问题的示例代码及其输出:

<?php
$over = date("Y-m-d H:i:s", strtotime("2021-12-16 13:42:46 PM"));
echo $over;
// 预期输出:2021-12-16 13:42:46
// 实际输出:1969-12-31 16:00:00 (或类似结果,取决于时区)
?>

正确处理日期时间格式

为了避免此类解析错误,我们需要确保提供给 strtotime() 或其他日期时间解析函数的字符串格式是明确且一致的。

Video Ocean
Video Ocean

人人皆导演,让视频创作变得轻松自如

下载

方法一:使用纯24小时制

如果您的时间数据已经是24小时制,则不应添加 AM 或 PM 指示符。

<?php
$correct_24h = date("Y-m-d H:i:s", strtotime("2021-12-16 13:42:46"));
echo "纯24小时制: " . $correct_24h . "\n"; // 输出: 2021-12-16 13:42:46
?>

方法二:使用正确12小时制

如果您的时间数据是12小时制,请确保小时数在 1 到 12 之间,并正确使用 AM 或 PM。

<?php
$correct_12h = date("Y-m-d H:i:s", strtotime("2021-12-16 01:42:46 PM"));
echo "正确12小时制: " . $correct_12h . "\n"; // 输出: 2021-12-16 13:42:46
?>

在这个例子中,01:42:46 PM 被 strtotime() 正确解析为下午1点42分46秒,然后 date() 将其格式化为24小时制的 13:42:46。

方法三:利用 DateTime 对象进行更严格的解析

对于需要更严格或自定义格式解析的场景,推荐使用 DateTime::createFromFormat() 方法。它允许您明确指定输入字符串的格式,如果字符串不符合该格式,则会返回 false,从而避免 strtotime() 可能产生的模糊解析问题。

<?php
// 示例1: 解析纯24小时制字符串
$dateString24h = "2021-12-16 13:42:46";
$dateTime24h = DateTime::createFromFormat('Y-m-d H:i:s', $dateString24h);

if ($dateTime24h instanceof DateTime) {
    echo "DateTime (24h): " . $dateTime24h->format('Y-m-d H:i:s') . "\n";
} else {
    echo "DateTime (24h) 解析失败!\n";
}

// 示例2: 解析正确12小时制字符串
// 注意:'A' 用于匹配 'AM' 或 'PM'
$dateString12h = "2021-12-16 01:42:46 PM";
$dateTime12h = DateTime::createFromFormat('Y-m-d h:i:s A', $dateString12h);

if ($dateTime12h instanceof DateTime) {
    echo "DateTime (12h): " . $dateTime12h->format('Y-m-d H:i:s') . "\n";
} else {
    echo "DateTime (12h) 解析失败!\n";
}

// 示例3: 尝试解析错误格式字符串 (13:42:46 PM)
$invalidDateString = "2021-12-16 13:42:46 PM";
// 尝试用24小时制格式解析,但字符串含有PM
$invalidDateTime1 = DateTime::createFromFormat('Y-m-d H:i:s', $invalidDateString);
// 尝试用12小时制格式解析,但小时数是13
$invalidDateTime2 = DateTime::createFromFormat('Y-m-d h:i:s A', $invalidDateString);

if (!$invalidDateTime1 instanceof DateTime) {
    echo "DateTime (无效格式1) 解析失败!\n"; // 会触发
}
if (!$invalidDateTime2 instanceof DateTime) {
    echo "DateTime (无效格式2) 解析失败!\n"; // 会触发
}
?>

DateTime::createFromFormat() 的优点在于它强制要求输入字符串与指定格式完全匹配。如果格式不匹配,它将返回 false,这使得错误处理更加直观和可靠。

注意事项与最佳实践

  1. 始终验证输入格式: 在处理用户输入或外部数据时,务必验证日期时间字符串的格式是否符合预期,以避免解析错误。
  2. 优先使用 DateTime 对象: DateTime 类及其相关方法(如 createFromFormat(), format(), add(), sub() 等)提供了更强大、更面向对象的日期时间处理能力,并且在错误处理方面比 strtotime() 更加健壮。
  3. 理解 strtotime() 的局限性: 尽管 strtotime() 非常方便,但其灵活的解析方式有时会导致模糊或意想不到的结果。在对格式有严格要求或需要精确控制的场景下,应避免单独使用 strtotime()。
  4. 考虑时区: PHP的日期时间函数默认使用服务器的时区设置。在进行日期时间操作时,尤其是在跨时区应用中,应通过 date_default_timezone_set() 函数或 DateTimeZone 对象明确设置和处理时区。

总结

strtotime() 函数将日期解析为 1969-12-31 的问题并非PHP的bug,而是由于提供了不规范的日期时间字符串,具体来说是混淆了12小时制和24小时制。要解决此问题,关键在于提供格式一致且明确的日期时间字符串,例如纯24小时制(YYYY-MM-DD HH:MM:SS)或正确的12小时制(YYYY-MM-DD hh:MM:SS AM/PM)。对于需要更严格控制和错误处理的场景,强烈推荐使用 DateTime::createFromFormat() 方法,它能确保日期时间字符串按照预期的格式进行解析。遵循这些实践可以显著提高日期时间处理的准确性和代码的健壮性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

63

2025.11.27

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

887

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

459

2024.06.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

649

2023.11.24

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.3万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号