0

0

PHP如何处理时间和日期_时间日期操作详细教程

蓮花仙者

蓮花仙者

发布时间:2025-09-20 20:15:01

|

836人浏览过

|

来源于php中文网

原创

PHP处理时间和日期的核心是time()、date()、strtotime()等函数及DateTime类;获取时间戳用time()或getTimestamp(),格式化日期用date()或format()方法,推荐使用DateTime::createFromFormat()解析字符串以避免strtotime()的模糊性,加减操作建议用add/sub配合DateInterval,时区处理应统一存储UTC时间并使用setTimezone()转换,为避免副作用推荐优先使用不可变的DateTimeImmutable对象。

php如何处理时间和日期_时间日期操作详细教程

PHP在处理时间和日期方面提供了非常强大和灵活的机制,主要通过一系列内置函数和面向对象的

DateTime
及其相关类来实现。无论是简单的获取当前时间,还是复杂的时区转换、日期加减计算,PHP都能提供可靠的解决方案,让你能够精准地管理和操作时间数据。

PHP处理时间和日期,核心在于理解两种主要方式:一是基于Unix时间戳的传统函数,二是更现代、功能更全面的

DateTime
对象家族。

传统的函数如

time()
date()
strtotime()
mktime()
,它们直接操作或返回Unix时间戳(自1970年1月1日00:00:00 UTC以来的秒数)。

  • time()
    :获取当前的Unix时间戳。
  • date(format, timestamp)
    :将Unix时间戳格式化为可读的日期时间字符串。
  • strtotime(string)
    :将英文日期时间描述字符串解析为Unix时间戳,非常灵活但有时也因此带来不确定性。
  • mktime(hour, minute, second, month, day, year)
    :根据给定的日期时间组件创建Unix时间戳。

DateTime
类(及其变体
DateTimeImmutable
)则提供了一种更面向对象、更健壮、更易于维护的方式来处理日期和时间。它封装了日期时间的所有属性和操作,包括时区、格式化、加减、比较等。

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

  • new DateTime()
    :创建表示当前日期时间的
    DateTime
    对象。
  • new DateTime('YYYY-MM-DD HH:MM:SS', new DateTimeZone('Asia/Shanghai'))
    :创建指定日期时间并在指定时区的
    DateTime
    对象。
  • $datetime->format(format)
    :格式化
    DateTime
    对象。
  • $datetime->modify(modifier)
    :修改日期时间,例如
    '+1 day'
  • $datetime->add(new DateInterval('P1D'))
    $datetime->sub(new DateInterval('PT1H'))
    :通过
    DateInterval
    对象进行精确的日期时间加减。
  • $datetime->diff(otherDateTime)
    :计算两个
    DateTime
    对象之间的差值,返回
    DateInterval
    对象。
  • $datetime->setTimezone(new DateTimeZone('America/New_York'))
    :设置
    DateTime
    对象的时区。

在我看来,对于简单的场景,传统函数确实方便快捷。但一旦涉及到复杂的逻辑、时区处理或者需要更清晰、更少副作用的代码,

DateTime
对象几乎是唯一的选择。它提供的丰富方法和对时区的良好支持,能极大减少潜在的错误。

PHP中获取当前时间戳和格式化日期有哪些常用方法?

要获取当前的Unix时间戳,最直接的方法就是使用

time()
函数。它会返回一个整数,代表自Unix纪元(1970年1月1日00:00:00 UTC)以来经过的秒数。这在很多场景下都非常有用,比如记录日志的时间、缓存的过期时间等等。

$currentTimestamp = time();
echo "当前Unix时间戳: " . $currentTimestamp; // 输出类似:当前Unix时间戳: 1678886400

如果你已经在使用

DateTime
对象,也可以通过
getTimestamp()
方法来获取。我个人更倾向于在面向对象的上下文中使用这个,保持代码风格一致。

$now = new DateTime();
$currentTimestampFromObject = $now->getTimestamp();
echo "通过DateTime对象获取的时间戳: " . $currentTimestampFromObject;

至于格式化日期,

date()
函数是老牌的、也是最常用的工具。它接受一个格式字符串和一个可选的时间戳参数,将时间戳转换成我们人类可读的字符串。格式字符串中的每个字符都有特定的含义,比如
Y
代表四位年份,
m
代表两位月份,
d
代表两位日期,
H
代表24小时制小时等等。

$formattedDate = date('Y-m-d H:i:s'); // 不指定时间戳,默认为当前时间
echo "当前格式化日期时间: " . $formattedDate; // 输出类似:当前格式化日期时间: 2023-03-15 10:30:00

$specificTimestamp = 1672531200; // 2023-01-01 00:00:00 UTC
$formattedSpecificDate = date('F j, Y, g:i a', $specificTimestamp);
echo "指定时间戳的格式化日期: " . $formattedSpecificDate; // 输出类似:指定时间戳的格式化日期: January 1, 2023, 12:00 am

而使用

DateTime
对象,格式化操作则通过其
format()
方法完成,参数与
date()
函数几乎一致。我发现这种方式在链式调用或处理复杂的日期对象时,代码可读性会更好。

$now = new DateTime();
$formattedDateObject = $now->format('Y/m/d H:i:s');
echo "通过DateTime对象格式化日期: " . $formattedDateObject; // 输出类似:通过DateTime对象格式化日期: 2023/03/15 10:30:00

选择哪种方法,很大程度上取决于你的项目习惯和具体需求。如果只是简单地显示当前时间,

date('Y-m-d H:i:s')
无疑是最快的。但如果你的应用需要进行大量的日期时间操作,或者需要精确控制时区,那么拥抱
DateTime
对象会让你省去很多麻烦。

如何在PHP中将字符串日期转换为时间戳或DateTime对象?

将字符串日期转换为可操作的时间戳或

DateTime
对象,是日常开发中非常普遍的需求。PHP为此提供了两个主要工具:
strtotime()
函数和
DateTime::createFromFormat()
方法。

strtotime()
是一个非常强大的函数,它能够解析各种英文日期时间描述字符串,并返回对应的Unix时间戳。它的灵活性简直令人惊叹,你可以传入像
"now"
"+1 day"
"next Monday"
"last day of February"
"2023-03-15 10:30:00"
这样的字符串。

$timestampFromText = strtotime("next Monday");
echo "下周一的时间戳: " . $timestampFromText . " -> " . date('Y-m-d', $timestampFromText);

$timestampFromSpecificString = strtotime("2023-03-15 10:30:00");
echo "指定日期字符串的时间戳: " . $timestampFromSpecificString . " -> " . date('Y-m-d H:i:s', $timestampFromSpecificString);

$timestampFromRelativeString = strtotime("+2 hours 30 minutes");
echo "两小时三十分钟后的时间戳: " . $timestampFromRelativeString . " -> " . date('Y-m-d H:i:s', $timestampFromRelativeString);

然而,

strtotime()
的强大也带来了它的缺点:模糊性。它在解析时会尝试“猜测”你的意图,这在某些情况下可能导致不预期的结果,尤其是在处理不同地区或格式的日期字符串时。例如,
"03/04/2023"
在某些地区可能是3月4日,而在另一些地区可能是4月3日。所以,在生产环境中,如果日期字符串的格式是已知且固定的,我通常会推荐使用更严格的方法。

这就是

DateTime::createFromFormat()
发挥作用的地方。这个静态方法允许你精确指定日期字符串的格式,从而避免了
strtotime()
的模糊性。它需要三个参数:格式字符串、日期时间字符串和可选的时区对象。如果解析成功,它会返回一个
DateTime
对象;如果失败,则返回
false

// 假设我们知道日期字符串总是 'YYYY-MM-DD HH:MM:SS' 格式
$dateString = "2023-03-15 10:30:00";
$dateTimeObject = DateTime::createFromFormat('Y-m-d H:i:s', $dateString);

if ($dateTimeObject) {
    echo "通过createFromFormat创建的DateTime对象: " . $dateTimeObject->format('Y/m/d H:i:s');
} else {
    echo "日期字符串格式不匹配或无效。";
}

// 处理不同地区格式,例如 'MM/DD/YYYY'
$usDateString = "03/15/2023";
$usDateTimeObject = DateTime::createFromFormat('m/d/Y', $usDateString);
if ($usDateTimeObject) {
    echo "美国格式日期字符串转换: " . $usDateTimeObject->format('Y-m-d');
}

// 甚至可以处理带有文本月份的日期
$textDateString = "March 15, 2023";
$textDateTimeObject = DateTime::createFromFormat('F d, Y', $textDateString);
if ($textDateTimeObject) {
    echo "文本月份日期字符串转换: " . $textDateTimeObject->format('Y-m-d');
}

在我看来,

strtotime()
是快速原型开发和处理已知清晰的相对日期(如
"+1 day"
)的利器,但对于用户输入或外部系统提供的日期字符串,
DateTime::createFromFormat()
是更安全、更专业的选择。它强制你思考并明确日期格式,从而减少了因格式不匹配而导致的潜在错误。

PHP如何进行日期时间的加减操作和时区处理?

日期时间的加减操作和时区处理是PHP日期时间功能中非常实用且重要的部分。它们允许你计算未来的事件、过去的记录,并确保在多地域应用中时间的一致性。

日期时间的加减操作

传统上,你可以通过

strtotime()
结合相对格式来做简单的加减。

$futureTimestamp = strtotime('+1 week'); // 一周后的时间戳
echo "一周后的日期: " . date('Y-m-d', $futureTimestamp);

$pastTimestamp = strtotime('-3 months'); // 三个月前的时间戳
echo "三个月前的日期: " . date('Y-m-d', $pastTimestamp);

但这种方式,正如之前所说,有时不够精确,且不如

DateTime
对象家族灵活。
DateTime
对象提供了
modify()
add()
sub()
方法来执行这些操作。

10分钟内自己学会PHP
10分钟内自己学会PHP

10分钟内自己学会PHP其中,第1篇为入门篇,主要包括了解PHP、PHP开发环境搭建、PHP开发基础、PHP流程控制语句、函数、字符串操作、正则表达式、PHP数组、PHP与Web页面交互、日期和时间等内容;第2篇为提高篇,主要包括MySQL数据库设计、PHP操作MySQL数据库、Cookie和Session、图形图像处理技术、文件和目录处理技术、面向对象、PDO数据库抽象层、程序调试与错误处理、A

下载

modify()
方法接受一个字符串参数,与
strtotime()
的相对格式类似,但它是直接作用于
DateTime
对象本身。

$now = new DateTime();
echo "当前时间: " . $now->format('Y-m-d H:i:s') . "\n";

$now->modify('+1 day'); // 直接修改对象
echo "一天后: " . $now->format('Y-m-d H:i:s') . "\n";

$now->modify('-2 hours');
echo "再减两小时: " . $now->format('Y-m-d H:i:s') . "\n";

对于更精确、更类型安全的加减操作,

add()
sub()
方法结合
DateInterval
对象是最佳实践。
DateInterval
对象表示一个时间段,可以精确到年、月、日、小时、分钟、秒。创建
DateInterval
时,你需要提供一个符合ISO 8601标准的持续时间格式字符串(例如
P1D
表示一天,
PT1H
表示一小时)。

$start = new DateTime('2023-01-15 10:00:00');
echo "起始时间: " . $start->format('Y-m-d H:i:s') . "\n";

// 增加5天3小时20分钟
$interval = new DateInterval('P5DT3H20M'); // P表示Period,T表示Time
$end = $start->add($interval);
echo "增加后: " . $end->format('Y-m-d H:i:s') . "\n";

// 减去2个月
$intervalSub = new DateInterval('P2M');
$final = $end->sub($intervalSub);
echo "减去后: " . $final->format('Y-m-d H:i:s') . "\n";

时区处理

时区是日期时间处理中的一个“老大难”问题,尤其是在全球化应用中。PHP提供了强大的时区支持。

首先,你可以通过

date_default_timezone_set()
函数设置脚本的默认时区。这会影响所有不指定时区的日期时间函数和
DateTime
对象的行为。

date_default_timezone_set('Asia/Shanghai');
$now = new DateTime(); // 这个DateTime对象将使用上海时区
echo "默认时区下的当前时间: " . $now->format('Y-m-d H:i:s') . "\n";

但更灵活的方式是为每个

DateTime
对象指定或更改时区。这通过
DateTimeZone
对象和
DateTime::setTimezone()
方法实现。

// 创建一个上海时区的DateTime对象
$shanghaiTime = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
echo "上海时间: " . $shanghaiTime->format('Y-m-d H:i:s') . "\n";

// 将其转换为纽约时区
$newYorkTime = $shanghaiTime->setTimezone(new DateTimeZone('America/New_York'));
echo "纽约时间: " . $newYorkTime->format('Y-m-d H:i:s') . "\n";

// 或者直接在创建时指定时区
$londonTime = new DateTime('2023-03-15 10:00:00', new DateTimeZone('Europe/London'));
echo "伦敦时间: " . $londonTime->format('Y-m-d H:i:s') . "\n";

我个人的经验是,在存储日期时间到数据库时,最好统一使用UTC(协调世界时)。这样可以避免夏令时(DST)带来的混乱,并且在不同时区之间进行转换时,以UTC为基准总是最稳妥的。当需要向用户显示时,再根据用户的时区偏好进行转换。理解UTC和本地时间之间的关系,是处理时区问题的关键。

处理日期时间时,PHP的DateTimeImmutable类有何优势?

在PHP 5.5引入

DateTimeImmutable
类时,我最初觉得它和
DateTime
没什么区别,甚至有点多余。但随着项目复杂度的增加,我逐渐认识到其“不变性”的巨大价值。
DateTimeImmutable
DateTime
的一个变体,但它的核心特性是不可变。这意味着一旦一个
DateTimeImmutable
对象被创建,它的内部状态(日期、时间、时区)就不能再被改变。所有修改操作,比如
modify()
add()
sub()
setTimezone()
,都不会修改原对象,而是返回一个新的
DateTimeImmutable
对象。

不变性的优势

  1. 可预测性与安全性: 当你将一个

    DateTimeImmutable
    对象传递给函数或方法时,你可以确信这个对象在函数内部不会被意外修改。这避免了所谓的“副作用”,让代码的行为更加可预测和安全。在大型应用或团队协作中,这能显著减少调试时间。

    function processDate(DateTimeImmutable $date) {
        // 即使这里调用了modify,也不会影响传入的 $originalDate 对象
        $newDate = $date->modify('+1 day');
        echo "函数内部处理后的日期: " . $newDate->format('Y-m-d') . "\n";
        return $newDate;
    }
    
    $originalDate = new DateTimeImmutable('2023-03-15');
    echo "原始日期: " . $originalDate->format('Y-m-d') . "\n";
    
    $processedDate = processDate($originalDate);
    echo "函数调用后的原始日期 (未改变): " . $originalDate->format('Y-m-d') . "\n";
    echo "函数返回的新日期: " . $processedDate->format('Y-m-d') . "\n";

    如果使用

    DateTime
    processDate
    函数内部的
    $date->modify('+1 day')
    会直接修改传入的
    $originalDate
    对象,这可能会导致意料之外的问题。

  2. 更容易推理: 当你看到一个

    DateTimeImmutable
    对象时,你立即知道它的值是固定的,不需要担心它在代码的某个地方被悄悄修改。这使得代码逻辑更容易理解和推理。

  3. 并发安全(理论上): 在多线程或并发环境中,不可变对象天然是线程安全的,因为它们的状态不会改变,不需要额外的锁机制来保护。虽然PHP本身是单线程的,但在一些异步或多进程的PHP应用中,这种特性依然有其价值。

  4. 函数式编程风格: 不变性是函数式编程的核心原则之一。使用

    DateTimeImmutable
    可以让你编写出更具函数式风格的代码,即函数只接受输入并产生输出,而不改变任何外部状态。

如何使用DateTimeImmutable

它的用法与

DateTime
非常相似,只是所有修改操作都会返回新对象。

$immutableDate = new DateTimeImmutable('2023-03-15 10:00:00');
echo "初始日期: " . $immutableDate->format('Y-m-d H:i:s') . "\n";

// modify 返回新对象
$modifiedDate = $immutableDate->modify('+1 month');
echo "修改后的日期 (新对象): " . $modifiedDate->format('Y-m-d H:i:s') . "\n";
echo "初始日期 (未变): " . $immutableDate->format('Y-m-d H:i:s') . "\n";

// add 也返回新对象
$addedDate = $immutableDate->add(new DateInterval('P2D'));
echo "增加后的日期 (新对象): " . $addedDate->format('Y-m-d H:i:s') . "\n";

总而言之,虽然

DateTime
在很多情况下已经足够,但如果你希望代码更加健壮、可预测,尤其是在处理复杂业务逻辑、API接口或构建事件流时,
DateTimeImmutable
无疑是更好的选择。它强迫你以一种更严谨的方式思考日期时间操作,从而减少了潜在的bug。

在PHP日期时间操作中,有哪些常见的陷阱和最佳实践?

在处理日期时间时,我踩过不少坑,也总结了一些经验。理解这些陷阱并遵循最佳实践,能让你的代码更加健壮可靠。

常见陷阱

  1. strtotime()
    的模糊性:
    这是最常见的陷阱之一。
    strtotime()
    在解析日期字符串时非常“智能”,但也正因如此,它可能对同一字符串在不同环境下(例如,不同的PHP版本、不同的操作系统默认时区、不同的语言环境)产生不同的解析结果。比如
    "03/04/2023"
    在美式英语中是3月4日,在英式英语中可能是4月3日。

相关专题

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

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

2709

2023.09.01

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

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

1669

2023.10.11

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

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

1529

2023.10.11

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

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

974

2023.10.23

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

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

1444

2023.10.23

html怎么上传
html怎么上传

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

1235

2023.11.03

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

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

1529

2023.11.09

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

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

1307

2023.11.13

excel表格操作技巧大全 表格制作excel教程
excel表格操作技巧大全 表格制作excel教程

Excel表格操作的核心技巧在于 熟练使用快捷键、数据处理函数及视图工具,如Ctrl+C/V(复制粘贴)、Alt+=(自动求和)、条件格式、数据验证及数据透视表。掌握这些可大幅提升数据分析与办公效率,实现快速录入、查找、筛选和汇总。

0

2026.01.21

热门下载

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

精品课程

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

共10课时 | 1.2万人学习

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

共13课时 | 0.9万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

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

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