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() 验证日期的有效性