PHP date_create_from_format() 函数
date_create_from_format() 函数是 DateTime::createFromFormat() 的过程化别名,根据指定的格式解析日期时间字符串,返回 DateTime 对象。
提示: 这个函数非常有用,特别是当你需要解析非标准格式的日期字符串时,比如从第三方API获取的日期数据。
语法
DateTime|false date_create_from_format ( string $format , string $datetime [, DateTimeZone $timezone = null ] )
参数说明
| 参数 |
描述 |
必需 |
$format |
日期时间字符串的格式,使用格式字符指定 |
是 |
$datetime |
要解析的日期时间字符串 |
是 |
$timezone |
DateTimeZone 对象,指定时区(可选) |
否 |
返回值
- DateTime 对象 - 解析成功时返回
- false - 解析失败时返回
常用格式字符
| 字符 |
描述 |
示例 |
d |
月份中的第几天,有前导零(01-31) |
15 |
j |
月份中的第几天,没有前导零(1-31) |
5 |
m |
数字表示的月份,有前导零(01-12) |
03 |
n |
数字表示的月份,没有前导零(1-12) |
3 |
Y |
4位数字完整表示的年份 |
2024 |
y |
2位数字表示的年份 |
24 |
H |
24小时制,有前导零(00-23) |
14 |
G |
24小时制,没有前导零(0-23) |
14 |
i |
有前导零的分钟数(00-59) |
30 |
s |
有前导零的秒数(00-59) |
45 |
u |
微秒(最多6位数字) |
123456 |
U |
Unix时间戳 |
1701234567 |
示例代码
示例 1:基本用法 - 解析标准格式
<?php
// 解析美国日期格式:月/日/年
$dateStr = "03/15/2024";
$format = "m/d/Y";
$date = date_create_from_format($format, $dateStr);
if ($date !== false) {
echo "解析成功: " . $date->format('Y-m-d');
} else {
echo "解析失败";
}
// 输出:解析成功: 2024-03-15
?>
示例 2:解析欧洲日期格式
<?php
// 解析欧洲日期格式:日.月.年
$dateStr = "15.03.2024";
$format = "d.m.Y";
$date = date_create_from_format($format, $dateStr);
if ($date) {
echo "欧洲格式: " . $date->format('Y-m-d') . "<br>";
echo "ISO格式: " . $date->format('c') . "<br>";
echo "本地格式: " . $date->format('l, F j, Y');
}
/*
输出:
欧洲格式: 2024-03-15
ISO格式: 2024-03-15T00:00:00+00:00
本地格式: Friday, March 15, 2024
*/
?>
示例 3:解析带时间的日期字符串
<?php
// 解析自定义日期时间格式
$dateTimeStr = "2024年03月15日 14:30:45";
$format = "Y年m月d日 H:i:s";
$dateTime = date_create_from_format($format, $dateTimeStr);
if ($dateTime) {
echo "原始字符串: " . $dateTimeStr . "<br>";
echo "解析后对象: " . $dateTime->format('Y-m-d H:i:s') . "<br>";
echo "12小时制: " . $dateTime->format('Y-m-d h:i:s A');
}
/*
输出:
原始字符串: 2024年03月15日 14:30:45
解析后对象: 2024-03-15 14:30:45
12小时制: 2024-03-15 02:30:45 PM
*/
?>
示例 4:处理多种可能的格式
<?php
function parseDate($dateStr) {
$formats = [
'Y-m-d',
'm/d/Y',
'd/m/Y',
'Y年m月d日',
'Y.m.d',
'd-m-Y',
];
foreach ($formats as $format) {
$date = date_create_from_format($format, $dateStr);
if ($date !== false) {
return $date;
}
}
return false;
}
// 测试不同格式的日期字符串
$testDates = [
'2024-03-15',
'03/15/2024',
'15/03/2024',
'2024年03月15日',
'2024.03.15',
'15-03-2024',
];
foreach ($testDates as $dateStr) {
$date = parseDate($dateStr);
if ($date) {
echo "成功解析 '{$dateStr}': " . $date->format('Y-m-d') . "<br>";
} else {
echo "无法解析 '{$dateStr}'<br>";
}
}
?>
示例 5:带时区的日期解析
<?php
// 解析带时区的日期时间
$dateTimeStr = "2024-03-15 14:30:00";
$timezone = new DateTimeZone('America/New_York');
$dateTime = date_create_from_format('Y-m-d H:i:s', $dateTimeStr, $timezone);
if ($dateTime) {
echo "原始时间: " . $dateTimeStr . "<br>";
echo "解析时区: " . $dateTime->getTimezone()->getName() . "<br>";
echo "本地时间: " . $dateTime->format('Y-m-d H:i:s') . "<br>";
// 转换为UTC
$dateTime->setTimezone(new DateTimeZone('UTC'));
echo "UTC时间: " . $dateTime->format('Y-m-d H:i:s');
}
/*
输出:
原始时间: 2024-03-15 14:30:00
解析时区: America/New_York
本地时间: 2024-03-15 14:30:00
UTC时间: 2024-03-15 18:30:00
*/
?>
示例 6:处理特殊格式和时间戳
<?php
// 解析Unix时间戳
$timestamp = 1678892400; // 2024-03-15 00:00:00 UTC
$date = date_create_from_format('U', $timestamp);
if ($date) {
echo "时间戳: " . $timestamp . "<br>";
echo "对应日期: " . $date->format('Y-m-d H:i:s') . "<br>";
}
// 解析包含微秒的时间
$microTimeStr = "2024-03-15 14:30:45.123456";
$format = "Y-m-d H:i:s.u";
$dateTime = date_create_from_format($format, $microTimeStr);
if ($dateTime) {
echo "<br>微秒时间: " . $dateTime->format('Y-m-d H:i:s.u');
}
?>
注意事项
重要提示:
- 格式字符串中的字符必须与日期时间字符串完全匹配
- 额外的空白字符可能导致解析失败
- 年份2位表示(y)会假设70-99是1900年代,00-69是2000年代
- 如果未指定时间部分,默认使用00:00:00
- 如果解析失败,函数返回false,而不是抛出异常
- 对于严格的格式验证,可以在格式字符串前加!(如!Y-m-d)
常见错误与解决方案
<?php
// 错误示例1:格式不匹配
$dateStr1 = "2024-03-15";
$format1 = "m/d/Y";
$date1 = date_create_from_format($format1, $dateStr1);
if ($date1 === false) {
echo "错误1: 格式 '{$format1}' 不匹配字符串 '{$dateStr1}'<br>";
}
// 错误示例2:缺少前导零
$dateStr2 = "2024-3-5"; // 月份和日期缺少前导零
$format2 = "Y-m-d"; // 但格式要求有前导零
$date2 = date_create_from_format($format2, $dateStr2);
if ($date2 === false) {
echo "错误2: 字符串 '{$dateStr2}' 不符合格式 '{$format2}'<br>";
}
// 解决方案:使用更灵活的格式
$format3 = "Y-n-j"; // 允许没有前导零
$date3 = date_create_from_format($format3, $dateStr2);
if ($date3 !== false) {
echo "解决方案: 使用格式 '{$format3}' 成功解析 '{$dateStr2}' = " . $date3->format('Y-m-d');
}
?>
与 strtotime() 比较
| 特性 |
date_create_from_format() |
strtotime() |
| 返回类型 |
DateTime对象 |
Unix时间戳 |
| 格式控制 |
精确控制,指定格式 |
智能猜测,相对灵活 |
| 处理非标准格式 |
优秀,可自定义格式 |
有限,依赖内置解析器 |
| 错误处理 |
返回false |
返回false |
| 推荐使用场景 |
已知确切格式的解析 |
用户输入或相对时间字符串 |
<?php
// 比较两种方法
$dateStr = "15-03-2024";
// 使用 date_create_from_format
$date1 = date_create_from_format('d-m-Y', $dateStr);
echo "date_create_from_format: ";
echo $date1 ? $date1->format('Y-m-d') : '失败';
echo "<br>";
// 使用 strtotime
$timestamp = strtotime($dateStr);
echo "strtotime: ";
echo $timestamp !== false ? date('Y-m-d', $timestamp) : '失败';
// 注意:strtotime可能将15-03-2024解析为03-15-2024(美国格式)
?>
相关函数
| 函数 |
描述 |
DateTime::createFromFormat() |
面向对象的格式化日期解析方法 |
date_create() |
创建DateTime对象(使用strtotime解析) |
strtotime() |
将任何英文文本日期时间解析为Unix时间戳 |
date_parse_from_format() |
根据指定格式获取日期的详细信息 |
checkdate() |
验证日期的有效性 |