PHP 日期与时间
在 PHP 中处理日期和时间
Section titled “在 PHP 中处理日期和时间”在网页开发中,处理日期和时间是一项常见的任务。PHP 提供了过程式函数和强大的面向对象 API 来有效管理日期、时间和时区。
现代方法:DateTimeImmutable 和 DateTime
Section titled “现代方法:DateTimeImmutable 和 DateTime”在现代 PHP 中处理日期和时间的推荐方法是使用内置的 DateTimeImmutable(因不可变性而首选)和 DateTime 类。它们提供了健壮的面向对象接口。
为什么选择 DateTimeImmutable? DateTimeImmutable 的实例创建后不能被改变。像 modify() 或 setTimezone() 这样的方法会返回一个包含更改的 新 对象,而保持原始对象不变。这可以防止意外修改,并使代码更易于理解。
示例:获取并格式化当前日期/时间:
<?php
// 最佳实践:使用 DateTimeImmutable$now = new DateTimeImmutable(); // 创建一个表示当前日期和时间的对象
// 使用 format() 方法格式化日期和时间echo "Today is: " . $now->format('Y-m-d') . "<br>"; // 例如:2023-10-27echo "Current time: " . $now->format('H:i:s') . "<br>"; // 例如:14:35:02 (24小时制)echo "Full date and time: " . $now->format('l, F j, Y g:i a') . "<br>"; // 例如:Friday, October 27, 2023 2:35 pm
?>常用格式化字符:
Section titled “常用格式化字符:”Y- 年份的完整数字表示,4 位数(例如:2023)m- 月份的数字表示,带前导零(01 到 12)d- 月份中的日,带前导零的 2 位数(01 到 31)l(小写 ‘L’) - 星期几的完整文本表示(例如:Sunday)H- 小时数的 24 小时制格式,带前导零(00 到 23)h- 小时数的 12 小时制格式,带前导零(01 到 12)i- 分钟数,带前导零(00 到 59)s- 秒数,带前导零(00 到 59)a- 小写 AM 和 PM(am 或 pm)U- 自 Unix Epoch(1970 年 1 月 1 日 00:00:00 GMT)以来的秒数
在 PHP 文档中的 DateTimeInterface::format() 中找到完整的格式化字符列表。
服务器可能位于与用户不同的时区。PHP 的默认时区可以在 php.ini 中设置,但最佳实践是在您的应用程序中显式处理时区。
设置默认时区(脚本级别):
<?php
// 为此脚本中的所有日期/时间函数设置默认时区date_default_timezone_set('America/New_York');
$now = new DateTimeImmutable();echo "The time in New York is " . $now->format('H:i:sa') . "<br>";
// 您可以在此处找到支持的时区标识符:https://www.php.net/manual/en/timezones.php
?>使用 DateTimeZone 处理特定时区:
<?php
// 创建时区对象$londonTimezone = new DateTimeZone('Europe/London');$tokyoTimezone = new DateTimeZone('Asia/Tokyo');
// 创建一个 DateTimeImmutable 对象(默认为服务器/PHP 时区)$now = new DateTimeImmutable();
// 创建表示在不同时区的 *同一时刻* 的新的 DateTimeImmutable 对象$nowInLondon = $now->setTimezone($londonTimezone);$nowInTokyo = $now->setTimezone($tokyoTimezone);
echo "Current server time: " . $now->format('Y-m-d H:i:s P') . "<br>";echo "Current London time: " . $nowInLondon->format('Y-m-d H:i:s P') . "<br>";echo "Current Tokyo time: " . $nowInTokyo->format('Y-m-d H:i:s P') . "<br>";
?>从字符串和时间戳创建日期
Section titled “从字符串和时间戳创建日期”您经常需要从现有数据(如用户输入或数据库值)创建日期对象。
从特定格式创建(推荐):
当您知道输入字符串的确切格式时,使用 DateTimeImmutable::createFromFormat() 进行可靠的解析。
<?php
$dateString = "2024-01-15 10:30:00";$format = 'Y-m-d H:i:s';
$dateObject = DateTimeImmutable::createFromFormat($format, $dateString);
if ($dateObject) { echo "Created date: " . $dateObject->format('l, F j, Y') . "<br>"; // Outputs: Monday, January 15, 2024} else { echo "Failed to parse date string."; // 详情请参阅 DateTimeImmutable::getLastErrors() // print_r(DateTimeImmutable::getLastErrors());}
?>从灵活字符串创建(谨慎使用):
DateTimeImmutable 构造函数(以及较旧的 strtotime() 函数)可以解析许多人类可读的格式,但可能存在歧义。
<?php
try { $d1 = new DateTimeImmutable("10:30pm April 15 2024"); echo "Created date 1: " . $d1->format('Y-m-d H:i:s') . "<br>";
$d2 = new DateTimeImmutable("tomorrow"); echo "Tomorrow is: " . $d2->format('Y-m-d') . "<br>";
$d3 = new DateTimeImmutable("+3 Months"); echo "Date in 3 months: " . $d3->format('Y-m-d') . "<br>";
// 歧义格式(是 DD-MM-YYYY 还是 MM-DD-YYYY?) // $d4 = new DateTimeImmutable('10-11-12'); // 有风险!
} catch (Exception $e) { echo 'Error creating date: ' . $e->getMessage();}
?>警告: 解析诸如 ‘m/d/y’ 或 ‘d-m-y’ 这样的歧义格式在很大程度上取决于系统设置,并可能导致意料之外的结果。如果可能,始终首选 createFromFormat()。
从 Unix 时间戳创建:
Unix 时间戳是自协调世界时 1970 年 1 月 1 日 00:00:00 以来经过的秒数。
<?php
$timestamp = 1678886400; // 示例时间戳(2023 年 3 月 15 日 12:00:00 UTC)
// 从时间戳创建$dateFromTimestamp = new DateTimeImmutable("@" . $timestamp);
// 如果需要,设置时区(时间戳始终为 UTC)$dateFromTimestamp = $dateFromTimestamp->setTimezone(new DateTimeZone('Europe/Paris'));
echo "Date from timestamp: " . $dateFromTimestamp->format('Y-m-d H:i:s P') . "<br>";
?>修改日期和计算间隔
Section titled “修改日期和计算间隔”DateTimeImmutable 对象可以轻松修改,并可以计算日期差异。
<?php
$today = new DateTimeImmutable();
// modify 返回一个 *新* 对象$nextWeek = $today->modify('+1 week');$yesterday = $today->modify('-1 day');$threeMonthsLater = $today->modify('+3 months');
echo "Today: " . $today->format('Y-m-d') . "<br>";echo "Next Week: " . $nextWeek->format('Y-m-d') . "<br>";echo "Yesterday: " . $yesterday->format('Y-m-d') . "<br>";echo "Three Months Later: " . $threeMonthsLater->format('Y-m-d') . "<br>";
// 计算两个日期之间的差异$date1 = new DateTimeImmutable('2024-07-04');$date2 = new DateTimeImmutable('now');
$interval = $date2->diff($date1); // 返回一个 DateInterval 对象
// 格式化间隔echo "Difference: " . $interval->format('%R%a days') . "<br>"; // 例如:+68 days 或 -10 days
if ($date1 > $date2) { echo "There are " . $interval->days . " total days until July 4th.<br>";} else { echo "July 4th has passed by " . $interval->days . " total days.<br>";}
?>modify() 方法接受各种相对格式(类似于 strtotime() 使用的格式)。diff() 方法返回一个 DateInterval 对象,该对象具有表示年、月、日、时等的属性,以及一个 format() 方法。
传统函数:date(), strtotime(), mktime()
Section titled “传统函数:date(), strtotime(), mktime()”尽管推荐使用 DateTimeImmutable API,但您仍然会遇到较旧的过程式函数:
date(format, timestamp):格式化 Unix 时间戳(如果省略 timestamp,则格式化当前时间)。对于快速格式化很简单,但缺乏对象 API 的强大功能。strtotime(time_string):将人类可读的字符串解析为 Unix 时间戳。很方便,但对于歧义格式可能不可靠。mktime(h, i, s, m, d, y):根据提供的组成部分获取特定日期和时间的 Unix 时间戳。不如面向对象的方法直观。
使用 date() 和 strtotime() 的示例:
<?php
date_default_timezone_set('UTC'); // 最佳实践是设置时区
// 使用 date() 进行简单格式化echo "Today is " . date("Y/m/d") . "<br>";echo "The time is " . date("h:i:sa") . "<br>";
// 自动生成版权年份echo "© 2010-" . date("Y") . "<br>";
// 使用 strtotime()$timestampNextSaturday = strtotime("next Saturday");if ($timestampNextSaturday !== false) { echo "Next Saturday is: " . date("Y-m-d", $timestampNextSaturday) . "<br>";} else { echo "Could not parse 'next Saturday'.<br>";}
?>尽管这些函数对于简单任务或传统代码可能很有用,但鉴于其清晰性、健壮性和功能集,在新开发中应努力使用 DateTimeImmutable。
完整的 PHP 日期/时间参考
Section titled “完整的 PHP 日期/时间参考”有关所有日期和时间类及函数的完整参考,包括详细解释和示例,请查阅官方 PHP 文档: