strtotime() 函数将任何英文文本的日期时间描述解析为 Unix 时间戳。这个函数非常强大,能够理解多种自然语言格式的日期时间字符串。
它是 PHP 中最常用的日期时间处理函数之一,特别适合处理用户输入的相对日期时间。
strtotime(string $datetime [, int $baseTimestamp = time()]) : int|false
| 参数 | 描述 |
|---|---|
| datetime |
必需。 日期/时间字符串。可以是绝对时间(如 "2023-08-15")或相对时间(如 "next Monday")。 支持多种格式,详见下面的格式示例表。 |
| baseTimestamp |
可选。 用作计算相对日期的基准时间戳。默认为当前时间 time()。 如果提供此参数,相对日期(如 "+1 day")将从该时间戳开始计算。 |
成功时返回 Unix 时间戳(整数),失败时返回 false。
| 格式类型 | 示例 | 说明 |
|---|---|---|
| 绝对日期 | 2023-08-15, 15-08-2023 | 标准日期格式 |
| 绝对时间 | 10:30:45, 10:30 | 24小时制或12小时制 |
| 组合日期时间 | 2023-08-15 10:30:45 | 日期和时间组合 |
| 自然语言日期 | tomorrow, yesterday, next Monday | 相对当前时间的描述 |
| 相对时间 | +1 day, -2 weeks, +3 months | 相对某个基准时间 |
| 特殊日期 | first day of, last day of | 月份的特殊日期 |
| 时区 | next Monday 8am UTC | 包含时区信息 |
<?php
// 解析标准日期格式
echo strtotime("2023-08-15") . "<br>";
echo date("Y-m-d", strtotime("2023-08-15")) . "<br>";
echo strtotime("15 August 2023") . "<br>";
echo date("Y-m-d", strtotime("15 August 2023")) . "<br>";
echo strtotime("08/15/2023") . "<br>"; // 美国格式 (MM/DD/YYYY)
echo date("Y-m-d", strtotime("08/15/2023")) . "<br>";
echo strtotime("2023-08-15 10:30:45") . "<br>";
echo date("Y-m-d H:i:s", strtotime("2023-08-15 10:30:45")) . "<br>";
// 输出类似:
// 1692057600
// 2023-08-15
// 1692057600
// 2023-08-15
// 1692057600
// 2023-08-15
// 1692064245
// 2023-08-15 10:30:45
?>
<?php
// 相对当前时间的日期
echo "今天: " . date("Y-m-d", strtotime("today")) . "<br>";
echo "明天: " . date("Y-m-d", strtotime("tomorrow")) . "<br>";
echo "昨天: " . date("Y-m-d", strtotime("yesterday")) . "<br>";
echo "后天: " . date("Y-m-d", strtotime("+2 days")) . "<br>";
echo "大前天: " . date("Y-m-d", strtotime("-3 days")) . "<br>";
echo "下周一: " . date("Y-m-d", strtotime("next Monday")) . "<br>";
echo "上周日: " . date("Y-m-d", strtotime("last Sunday")) . "<br>";
echo "下个月: " . date("Y-m-d", strtotime("+1 month")) . "<br>";
echo "明年: " . date("Y-m-d", strtotime("+1 year")) . "<br>";
// 输出类似:
// 今天: 2023-08-15
// 明天: 2023-08-16
// 昨天: 2023-08-14
// 后天: 2023-08-17
// 大前天: 2023-08-12
// 下周一: 2023-08-21
// 上周日: 2023-08-13
// 下个月: 2023-09-15
// 明年: 2024-08-15
?>
<?php
// 各种相对时间计算
echo "1小时后: " . date("H:i:s", strtotime("+1 hour")) . "<br>";
echo "30分钟后: " . date("H:i:s", strtotime("+30 minutes")) . "<br>";
echo "2小时后: " . date("H:i:s", strtotime("+2 hours")) . "<br>";
echo "1天前: " . date("Y-m-d H:i:s", strtotime("-1 day")) . "<br>";
echo "1周后: " . date("Y-m-d", strtotime("+1 week")) . "<br>";
echo "2周3天4小时5分钟后: " . date("Y-m-d H:i:s", strtotime("+2 weeks 3 days 4 hours 5 minutes")) . "<br>";
// 复杂的相对时间
echo "下个月的第3天: " . date("Y-m-d", strtotime("first day of +1 month +2 days")) . "<br>";
echo "上个月的最后一天: " . date("Y-m-d", strtotime("last day of previous month")) . "<br>";
echo "下个季度的第一天: " . date("Y-m-d", strtotime("first day of +3 months")) . "<br>";
// 输出类似:
// 1小时后: 11:30:45
// 30分钟后: 11:00:45
// 2小时后: 12:30:45
// 1天前: 2023-08-14 10:30:45
// 1周后: 2023-08-22
// 2周3天4小时5分钟后: 2023-09-01 14:35:45
// 下个月的第3天: 2023-09-03
// 上个月的最后一天: 2023-07-31
// 下个季度的第一天: 2023-10-01
?>
<?php
// 使用特定的基准时间戳
$baseTimestamp = strtotime("2023-01-01");
echo "基准时间: " . date("Y-m-d", $baseTimestamp) . "<br>";
echo "基准时间的明天: " . date("Y-m-d", strtotime("+1 day", $baseTimestamp)) . "<br>";
echo "基准时间的下周一: " . date("Y-m-d", strtotime("next Monday", $baseTimestamp)) . "<br>";
echo "基准时间的一个月后: " . date("Y-m-d", strtotime("+1 month", $baseTimestamp)) . "<br>";
// 输出:
// 基准时间: 2023-01-01
// 基准时间的明天: 2023-01-02
// 基准时间的下周一: 2023-01-02
// 基准时间的一个月后: 2023-02-01
?>
<?php
// 处理时间相关字符串
echo "早上8点: " . date("Y-m-d H:i:s", strtotime("8am")) . "<br>";
echo "晚上8点: " . date("Y-m-d H:i:s", strtotime("8pm")) . "<br>";
echo "中午: " . date("Y-m-d H:i:s", strtotime("noon")) . "<br>";
echo "午夜: " . date("Y-m-d H:i:s", strtotime("midnight")) . "<br>";
echo "现在: " . date("Y-m-d H:i:s", strtotime("now")) . "<br>";
// 组合日期和时间
echo "明天下午3点: " . date("Y-m-d H:i:s", strtotime("tomorrow 3pm")) . "<br>";
echo "下周一上午9:30: " . date("Y-m-d H:i:s", strtotime("next Monday 9:30am")) . "<br>";
echo "上周五下午5点: " . date("Y-m-d H:i:s", strtotime("last Friday 5pm")) . "<br>";
// 输出类似:
// 早上8点: 2023-08-15 08:00:00
// 晚上8点: 2023-08-15 20:00:00
// 中午: 2023-08-15 12:00:00
// 午夜: 2023-08-15 00:00:00
// 现在: 2023-08-15 10:30:45
// 明天下午3点: 2023-08-16 15:00:00
// 下周一上午9:30: 2023-08-21 09:30:00
// 上周五下午5点: 2023-08-11 17:00:00
?>
<?php
// 节假日和特殊日期
echo "今年的圣诞节: " . date("Y-m-d", strtotime("25 December this year")) . "<br>";
echo "下一个圣诞节: " . date("Y-m-d", strtotime("25 December")) . "<br>";
echo "2024年新年: " . date("Y-m-d", strtotime("1 January 2024")) . "<br>";
echo "本月的第一个星期一: " . date("Y-m-d", strtotime("first Monday of this month")) . "<br>";
echo "本月的最后一个星期五: " . date("Y-m-d", strtotime("last Friday of this month")) . "<br>";
echo "下个月的第三个星期三: " . date("Y-m-d", strtotime("third Wednesday of next month")) . "<br>";
// 复活节(需要计算)
echo "2023年复活节: " . date("Y-m-d", strtotime("2023-04-09")) . "<br>";
echo "2024年复活节: " . date("Y-m-d", strtotime("2024-03-31")) . "<br>";
// 输出类似:
// 今年的圣诞节: 2023-12-25
// 下一个圣诞节: 2023-12-25
// 2024年新年: 2024-01-01
// 本月的第一个星期一: 2023-08-07
// 本月的最后一个星期五: 2023-08-25
// 下个月的第三个星期三: 2023-09-20
// 2023年复活节: 2023-04-09
// 2024年复活节: 2024-03-31
?>
<?php
// 处理可能失败的情况
function safeStrtotime($dateString, $baseTimestamp = null) {
if ($baseTimestamp === null) {
$timestamp = strtotime($dateString);
} else {
$timestamp = strtotime($dateString, $baseTimestamp);
}
if ($timestamp === false) {
return "无法解析日期: " . htmlspecialchars($dateString);
}
return $timestamp;
}
echo safeStrtotime("2023-08-15") . "<br>";
echo safeStrtotime("无效日期字符串") . "<br>";
echo safeStrtotime("2023-13-45") . "<br>"; // 无效日期
echo safeStrtotime("2023-02-30") . "<br>"; // 2月没有30日
// 输出类似:
// 1692057600
// 无法解析日期: 无效日期字符串
// 无法解析日期: 2023-13-45
// 无法解析日期: 2023-02-30
?>
<?php
// 设置时区
date_default_timezone_set('UTC');
echo "UTC时间: " . date("Y-m-d H:i:s", strtotime("2023-08-15 10:30:45")) . "<br>";
// 转换为其他时区
date_default_timezone_set('Asia/Shanghai');
echo "上海时间: " . date("Y-m-d H:i:s", strtotime("2023-08-15 10:30:45")) . "<br>";
// 包含时区的字符串
date_default_timezone_set('UTC');
echo "带时区的字符串: " . date("Y-m-d H:i:s T", strtotime("2023-08-15 10:30:45 America/New_York")) . "<br>";
// 时区转换
$timestamp = strtotime("2023-08-15 10:30:45 UTC");
date_default_timezone_set('America/Los_Angeles');
echo "洛杉矶时间: " . date("Y-m-d H:i:s T", $timestamp) . "<br>";
// 输出类似:
// UTC时间: 2023-08-15 10:30:45
// 上海时间: 2023-08-15 18:30:45
// 带时区的字符串: 2023-08-15 14:30:45 UTC
// 洛杉矶时间: 2023-08-15 03:30:45 PDT
?>
strtotime() 返回的是 Unix 时间戳(自 1970-01-01 00:00:00 UTC 以来的秒数)strtotime() 的结果,可以使用 date_default_timezone_set() 设置时区strtotime() 的解析strtotime() 可能返回 -1 而不是 falseDateTime 类| 场景 | 建议 |
|---|---|
| 频繁解析相同格式的日期 | 使用 DateTime::createFromFormat() 替代,性能更好 |
| 需要处理时区 | 使用 DateTime 类,时区处理更完善 |
| 处理用户输入 | 先验证日期格式,再使用 strtotime() 解析 |
| 需要高精度日期计算 | 使用 DateTime 和 DateInterval 类 |
| 批量处理日期 | 缓存解析结果,避免重复解析 |
| 特性 | strtotime() | DateTime 类 |
|---|---|---|
| 易用性 | 非常简单,单行代码 | 需要创建对象,但功能更丰富 |
| 时区支持 | 依赖于全局时区设置 | 对象级别的时区控制 |
| 错误处理 | 返回 false,需要手动检查 | 抛出异常,更容易调试 |
| 性能 | 较快,适合简单解析 | 稍慢,但功能更强大 |
| 日期计算 | 支持相对时间字符串 | 支持 DateInterval,更精确 |