0

0

解决 PHP strtotime() 处理混合时间格式导致的日期转换问题

聖光之護

聖光之護

发布时间:2025-11-26 10:34:15

|

457人浏览过

|

来源于php中文网

原创

解决 PHP strtotime() 处理混合时间格式导致的日期转换问题

php中,使用`strtotime()`结合`date()`进行时间转换时,若输入字符串混合了24小时制的小时数(如`13`)与12小时制的时间修饰符(如`pm`),会导致`strtotime()`解析失败,通常返回`false`或`0`,进而使`date()`输出unix纪元时间(`1969-12-31`)。本文将深入分析此问题,并提供多种解决方案,包括修正时间格式、使用纯24小时制以及利用`datetime`类进行更健壮的解析。

PHP提供了强大的日期和时间处理功能,其中strtotime()函数因其能够将人类可读的日期时间字符串解析为Unix时间戳而广受欢迎。然而,不当的输入格式常常导致解析错误,尤其是在处理12小时制和24小时制时间时。本文将探讨一个常见的strtotime()解析错误:当时间字符串同时包含24小时制的小时数和12小时制的AM/PM指示符时,strtotime()的非预期行为及其解决方案。

问题现象

开发者在使用date()和strtotime()组合将日期时间字符串转换为特定格式时,可能会遇到以下异常输出:

假设我们尝试将字符串 "2021-12-16 13:42:46 PM" 转换为Y-m-d H:i:s格式:

$over = date("Y-m-d H:i:s", strtotime("2021-12-16 13:42:46 PM"));
echo $over;

预期输出可能是2021-12-16 13:42:46,但实际输出却是:

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

1969-12-31 16:00:00

这个结果明显不是我们期望的日期,并且指向了Unix纪元时间的一个偏移量。

根本原因分析

问题的核心在于strtotime()函数对输入字符串"2021-12-16 13:42:46 PM"的解析失败。

strtotime()在解析日期时间字符串时,会尝试识别多种格式。对于12小时制时间,它期望小时数在1到12之间,并配合AM或PM指示符。例如,"01:42:46 PM"是有效的12小时制表示。而对于24小时制时间,它期望小时数在0到23之间,且通常不带AM或PM指示符。例如,"13:42:46"是有效的24小时制表示。

当字符串中出现"13:42:46 PM"时,strtotime()会发现矛盾:13是一个24小时制的小时数,而PM是12小时制特有的修饰符。这种混合格式导致strtotime()无法正确解析,通常会返回false。

当strtotime()返回false时,date()函数会将其隐式转换为整数0。整数0代表Unix纪元时间(January 1, 1970 00:00:00 UTC)。由于时区设置(例如,如果服务器时区是UTC-8,则1970-01-01 00:00:00 UTC会显示为1969-12-31 16:00:00 PST),最终输出便显示为1969-12-31 16:00:00。

Artbreeder
Artbreeder

创建令人惊叹的插画和艺术

下载

解决方案

要解决此问题,关键在于向strtotime()提供一个符合规范的日期时间字符串。

1. 使用正确的12小时制格式

如果意图是表示下午1点42分,那么小时数应为01而不是13。

$correct12h = date("Y-m-d H:i:s", strtotime("2021-12-16 01:42:46 PM"));
echo $correct12h;
// 预期输出: 2021-12-16 13:42:46

在此示例中,strtotime()正确解析了01:42:46 PM为下午1点42分,并将其转换为对应的Unix时间戳。date("Y-m-d H:i:s", ...)则将此时间戳格式化为24小时制。

2. 使用纯24小时制格式

如果原始输入13:42:46已经是24小时制,那么PM指示符是多余且错误的,应该将其移除。

$pure24h = date("Y-m-d H:i:s", strtotime("2021-12-16 13:42:46"));
echo $pure24h;
// 预期输出: 2021-12-16 13:42:46

这是最直接的解决方案,如果确定输入时间已经是24小时制,只需确保其不包含12小时制特有的修饰符。

3. 结合 DateTime 类进行更健壮的解析

对于更复杂的日期时间解析需求,或者当输入格式不确定时,推荐使用PHP的DateTime类及其createFromFormat()方法。createFromFormat()允许你明确指定输入字符串的预期格式,从而避免strtotime()可能出现的歧义。

// 假设原始输入字符串是 "2021-12-16 13:42:46 PM"
$inputString = "2021-12-16 13:42:46 PM";

// 尝试使用 'H' (24小时制) 和 'A' (AM/PM) 解析。
// 由于 '13' 与 'PM' 冲突,此尝试会失败,因为格式字符串与输入不匹配。
$dateTimeObj1 = DateTime::createFromFormat("Y-m-d H:i:s A", $inputString);
if ($dateTimeObj1) {
    echo "Parsed (H:i:s A): " . $dateTimeObj1->format("Y-m-d H:i:s") . "\n";
} else {
    echo "Failed to parse (H:i:s A) for: '$inputString' (格式不匹配)\n";
}

// 如果确定输入是标准的12小时制,且小时数是 1-12,则使用 'h'
$inputString12h = "2021-12-16 01:42:46 PM";
$dateTimeObj2 = DateTime::createFromFormat("Y-m-d h:i:s A", $inputString12h);
if ($dateTimeObj2) {
    echo "Parsed (h:i:s A): " . $dateTimeObj2->format("Y-m-d H:i:s") . "\n";
    // 预期输出: Parsed (h:i:s A): 2021-12-16 13:42:46
} else {
    echo "Failed to parse (h:i:s A) for: '$inputString12h'\n";
}

// 如果确定输入是纯24小时制,则使用 'H' 且不带 A/PM
$inputString24h = "2021-12-16 13:42:46";
$dateTimeObj3 = DateTime::createFromFormat("Y-m-d H:i:s", $inputString24h);
if ($dateTimeObj3) {
    echo "Parsed (H:i:s): " . $dateTimeObj3->format("Y-m-d H:i:s") . "\n";
    // 预期输出: Parsed (H:i:s): 2021-12-16 13:42:46
} else {
    echo "Failed to parse (H:i:s) for: '$inputString24h'\n";
}

createFromFormat()的优势在于,如果输入字符串与指定格式不匹配,它会返回false,这使得错误处理更加明确,而不是像strtotime()那样可能返回一个意想不到的Unix纪元时间。

注意事项

  • 输入验证: 在处理用户或外部系统提供的日期时间字符串时,务必进行严格的输入验证。检查字符串是否符合预期的格式,以避免解析错误。
  • strtotime()的局限性: 尽管strtotime()功能强大,但其对模糊或混合格式的解析能力有限。在面对不确定或多种可能的输入格式时,应优先考虑使用DateTime::createFromFormat()。
  • 时区管理: 日期时间处理中时区是一个重要因素。确保PHP环境的时区设置(date_default_timezone_set()或php.ini中的date.timezone)与你的应用程序需求一致。DateTime对象默认使用当前时区,但也可以在创建时指定。
  • 错误处理: 无论使用strtotime()还是createFromFormat(),都应检查它们的返回值。strtotime()返回false表示失败,createFromFormat()也返回false。及时捕获并处理这些错误,可以防止程序产生非预期的结果。

总结

PHP日期时间转换中,strtotime()遇到混合12小时制和24小时制的时间格式(如13:42:46 PM)时,会因解析失败而导致输出1969-12-31这样的错误日期。解决此问题的关键在于确保输入字符串遵循单一且正确的日期时间格式。无论是修正为标准的12小时制(01:42:46 PM),还是采用纯粹的24小时制(13:42:46),都能有效解决问题。对于需要更精细控制和错误处理的场景,DateTime::createFromFormat()提供了更健壮的解决方案。在任何日期时间处理中,理解函数行为、验证输入以及妥善处理错误都是至关重要的。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2524

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1600

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1493

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

952

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1416

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1234

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1445

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1306

2023.11.13

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

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

精品课程

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

共137课时 | 8.6万人学习

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

共6课时 | 7万人学习

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

共13课时 | 0.9万人学习

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

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