PHP date_format() 函数

date_format() 函数是 DateTime::format() 的过程化别名,用于将 DateTime 对象格式化为指定的日期时间字符串。这是PHP中最常用的日期格式化函数之一。

提示: date_format() 函数提供了丰富的格式化选项,可以将日期时间转换为各种格式,满足不同场景的需求。

语法

string date_format ( DateTimeInterface $object , string $format )

参数说明

参数 描述 必需
$object DateTime 对象,表示要格式化的日期时间
$format 格式化字符串,指定输出格式

返回值

  • 字符串 - 格式化后的日期时间字符串
  • 根据指定的格式化字符串返回相应的格式

常用格式化字符

字符 描述 示例
Y 4位数字完整表示的年份 2024
y 2位数字表示的年份 24
m 数字表示的月份,有前导零 01 到 12
n 数字表示的月份,没有前导零 1 到 12
F 月份,完整的文本格式 January 到 December
M 三个字母缩写表示的月份 Jan 到 Dec
d 月份中的第几天,有前导零 01 到 31
j 月份中的第几天,没有前导零 1 到 31
H 24小时格式,有前导零 00 到 23
h 12小时格式,有前导零 01 到 12
i 分钟数,有前导零 00 到 59
s 秒数,有前导零 00 到 59
A 大写的上午和下午值 AM 或 PM
a 小写的上午和下午值 am 或 pm
l 星期几,完整的文本格式 Sunday 到 Saturday
D 星期几,3个字母的文本格式 Sun 到 Sat
w 星期几的数字表示 0 (周日) 到 6 (周六)
N ISO-8601 星期几的数字表示 1 (周一) 到 7 (周日)

示例代码

示例 1:基本用法

<?php
// 创建DateTime对象
$date = date_create('2024-03-15 14:30:45');

// 不同格式的格式化示例
$formats = [
    'Y-m-d H:i:s' => '标准日期时间格式',
    'Y年m月d日 H时i分s秒' => '中文日期时间格式',
    'l, F j, Y' => '完整英文日期格式',
    'm/d/Y' => '美国日期格式',
    'd-m-Y' => '欧洲日期格式',
    'H:i:s' => '仅时间格式',
    'Y-m-d\TH:i:sP' => 'ISO 8601格式',
    'r' => 'RFC 2822格式',
];

echo "原始日期时间: 2024-03-15 14:30:45<br><br>";

foreach ($formats as $format => $description) {
    $result = date_format($date, $format);
    echo "{$description}: {$result}<br>";
}

/*
输出:
标准日期时间格式: 2024-03-15 14:30:45
中文日期时间格式: 2024年03月15日 14时30分45秒
完整英文日期格式: Friday, March 15, 2024
美国日期格式: 03/15/2024
欧洲日期格式: 15-03-2024
仅时间格式: 14:30:45
ISO 8601格式: 2024-03-15T14:30:45+00:00
RFC 2822格式: Fri, 15 Mar 2024 14:30:45 +0000
*/
?>

示例 2:日期格式转换工具

<?php
// 日期格式转换函数
function convertDateFormat($dateString, $fromFormat, $toFormat) {
    $date = date_create_from_format($fromFormat, $dateString);
    if ($date === false) {
        return "日期解析失败";
    }
    return date_format($date, $toFormat);
}

// 测试日期格式转换
$testCases = [
    ['date' => '15/03/2024', 'from' => 'd/m/Y', 'to' => 'Y-m-d', 'desc' => '欧洲转ISO'],
    ['date' => '2024-03-15', 'from' => 'Y-m-d', 'to' => 'F j, Y', 'desc' => 'ISO转英文'],
    ['date' => '03/15/2024 14:30', 'from' => 'm/d/Y H:i', 'to' => 'Y年m月d日 H时i分', 'desc' => '美国转中文'],
    ['date' => '20240315', 'from' => 'Ymd', 'to' => 'Y-m-d', 'desc' => '紧凑转标准'],
];

foreach ($testCases as $case) {
    $result = convertDateFormat($case['date'], $case['from'], $case['to']);
    echo "{$case['desc']}: {$case['date']} → {$result}<br>";
}

// 当前时间的不同格式
echo "<br>当前时间不同格式:<br>";
$now = date_create();

$formats = [
    'Y-m-d H:i:s' => '标准',
    'U' => 'Unix时间戳',
    'c' => 'ISO 8601',
    'r' => 'RFC 2822',
    'l jS \of F Y h:i:s A' => '完整英文',
];

foreach ($formats as $format => $desc) {
    echo "{$desc}: " . date_format($now, $format) . "<br>";
}
?>

示例 3:与 date() 函数比较

<?php
// date_format() 与 date() 的比较
$timestamp = time();
$date = date_create("@$timestamp"); // 从时间戳创建DateTime对象

echo "当前时间对比:<br><br>";

// 使用 date() 函数
echo "使用 date() 函数:<br>";
echo "标准格式: " . date('Y-m-d H:i:s', $timestamp) . "<br>";
echo "中文格式: " . date('Y年m月d日 H时i分s秒', $timestamp) . "<br>";
echo "英文格式: " . date('l, F j, Y', $timestamp) . "<br><br>";

// 使用 date_format() 函数
echo "使用 date_format() 函数:<br>";
echo "标准格式: " . date_format($date, 'Y-m-d H:i:s') . "<br>";
echo "中文格式: " . date_format($date, 'Y年m月d日 H时i分s秒') . "<br>";
echo "英文格式: " . date_format($date, 'l, F j, Y') . "<br><br>";

// 性能比较
$iterations = 10000;

// date() 性能测试
$start1 = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
    $result = date('Y-m-d H:i:s', $timestamp);
}
$time1 = microtime(true) - $start1;

// date_format() 性能测试
$start2 = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
    $result = date_format($date, 'Y-m-d H:i:s');
}
$time2 = microtime(true) - $start2;

echo "性能测试 ({$iterations}次):<br>";
echo "date(): " . number_format($time1 * 1000, 2) . " ms<br>";
echo "date_format(): " . number_format($time2 * 1000, 2) . " ms<br>";
echo "差异: " . number_format(($time2 - $time1) * 1000, 2) . " ms";
?>

示例 4:高级格式化技巧

<?php
// 高级格式化技巧
$date = date_create('2024-03-15 14:30:45');

echo "高级格式化示例:<br><br>";

// 1. 转义字符
echo "1. 转义字符使用:<br>";
echo date_format($date, 'Y-m-d \a\t H:i:s') . "<br>";
echo date_format($date, 'l \\t\h\\e jS') . "<br><br>";

// 2. 组合格式化
echo "2. 组合格式化:<br>";
echo "今天是" . date_format($date, 'Y年m月d日') . ",星期" . date_format($date, 'N') . "<br>";
echo "现在是" . date_format($date, 'H:i:s') . " (24小时制) 或 " . date_format($date, 'h:i:s A') . " (12小时制)<br><br>";

// 3. 时间计算与格式化结合
echo "3. 时间计算与格式化结合:<br>";
$tomorrow = date_create('2024-03-15');
date_add($tomorrow, date_interval_create_from_date_string('1 day'));
echo "明天是: " . date_format($tomorrow, 'Y-m-d l') . "<br>";

$nextWeek = date_create('2024-03-15');
date_add($nextWeek, date_interval_create_from_date_string('1 week'));
echo "一周后: " . date_format($nextWeek, 'Y-m-d') . "<br><br>";

// 4. 自定义格式化函数
function formatDateCustom($date, $style = 'full') {
    switch ($style) {
        case 'short':
            return date_format($date, 'Y-m-d');
        case 'medium':
            return date_format($date, 'Y年m月d日');
        case 'long':
            return date_format($date, 'Y年m月d日 H时i分');
        case 'full':
            return date_format($date, 'Y年m月d日 H时i分s秒 l');
        default:
            return date_format($date, 'Y-m-d H:i:s');
    }
}

echo "4. 自定义格式化函数:<br>";
echo "短格式: " . formatDateCustom($date, 'short') . "<br>";
echo "中格式: " . formatDateCustom($date, 'medium') . "<br>";
echo "长格式: " . formatDateCustom($date, 'long') . "<br>";
echo "完整格式: " . formatDateCustom($date, 'full') . "<br><br>";

// 5. 多语言月份和星期
echo "5. 模拟多语言格式化:<br>";
$monthNames = [
    'en' => ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    'zh' => ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
];

$monthNum = date_format($date, 'n') - 1;
echo "英文月份: " . $monthNames['en'][$monthNum] . "<br>";
echo "中文月份: " . $monthNames['zh'][$monthNum] . "<br>";
?>

示例 5:时区格式化处理

<?php
// 时区格式化处理
echo "时区格式化示例:<br><br>";

// 创建不同时区的DateTime对象
$timezones = [
    'UTC' => new DateTimeZone('UTC'),
    'Asia/Shanghai' => new DateTimeZone('Asia/Shanghai'),
    'America/New_York' => new DateTimeZone('America/New_York'),
    'Europe/London' => new DateTimeZone('Europe/London'),
];

$baseDate = date_create('2024-03-15 12:00:00', new DateTimeZone('UTC'));

foreach ($timezones as $tzName => $timezone) {
    $localDate = clone $baseDate;
    $localDate->setTimezone($timezone);

    echo "时区: {$tzName}<br>";
    echo "本地时间: " . date_format($localDate, 'Y-m-d H:i:s') . "<br>";
    echo "时区标识: " . date_format($localDate, 'e') . "<br>";
    echo "时区偏移: " . date_format($localDate, 'P') . "<br>";
    echo "时区缩写: " . date_format($localDate, 'T') . "<br>";
    echo "是否夏令时: " . (date_format($localDate, 'I') ? '是' : '否') . "<br><br>";
}

// 格式化时区相关字符
echo "时区格式化字符:<br>";
$date = date_create('2024-03-15 12:00:00', new DateTimeZone('America/New_York'));

$tzFormats = [
    'e' => '时区标识符',
    'T' => '时区缩写',
    'P' => '时区偏移(+08:00)',
    'O' => '时区偏移(+0800)',
    'Z' => '时区偏移秒数',
    'I' => '是否夏令时(1或0)',
];

foreach ($tzFormats as $char => $desc) {
    $result = date_format($date, $char);
    echo "{$desc} ({$char}): {$result}<br>";
}
?>

特殊格式化字符

字符 描述 示例
U Unix时间戳(自1970-01-01的秒数) 1678892400
c ISO 8601日期(如:2004-02-12T15:19:21+00:00) 2024-03-15T14:30:45+00:00
r RFC 2822格式化日期 Fri, 15 Mar 2024 14:30:45 +0000
e 时区标识符 UTC, Asia/Shanghai
T 时区缩写 UTC, CST, EST
P 与格林威治时间(GMT)的时区偏移 +08:00, -05:00
O 与格林威治时间(GMT)的时区偏移(无冒号) +0800, -0500
Z 时区偏移秒数 28800, -18000
I 是否夏令时(1=是,0=否) 1, 0
B Swatch Internet时间 000 到 999
u 微秒(PHP 5.2.2+) 123456
v 毫秒(PHP 7.0.0+) 123

注意事项

重要提示:
  • date_format() 的第一个参数必须是 DateTimeInterface 对象
  • 格式化字符串区分大小写,不同字符有不同的含义
  • 在格式化字符串中,非格式化字符需要使用反斜杠转义
  • DateTime 对象包含时区信息,格式化时会考虑时区
  • date_format() 与 date() 功能类似,但 date_format() 需要 DateTime 对象
  • 对于简单的日期格式化,date() 函数更直接;对于复杂的日期操作,DateTime 对象更强大

常见问题

使用 date() 的场景:

  • 简单的当前时间格式化
  • 不需要时区转换的情况
  • 不需要日期计算的情况
  • 性能要求较高的场景(date() 稍快)

使用 date_format() 的场景:

  • 已经拥有 DateTime 对象
  • 需要进行时区转换
  • 需要进行日期计算(加减日、月、年等)
  • 代码风格偏好面向对象或过程化别名
// date() 示例
echo date('Y-m-d H:i:s');

// date_format() 示例
$date = date_create('2024-03-15 14:30:45');
echo date_format($date, 'Y-m-d H:i:s');

PHP默认不支持中文星期几,但可以通过映射实现:

<?php
function getChineseWeekday($date) {
    $weekdays = ['日', '一', '二', '三', '四', '五', '六'];
    $englishWeekday = date_format($date, 'w'); // 0-6 (0=周日)
    return $weekdays[$englishWeekday];
}

$date = date_create('2024-03-15');
echo "星期" . getChineseWeekday($date); // 输出:星期五

// 或者使用更完整的方法
function formatChineseDate($date) {
    $weekdays = ['日', '一', '二', '三', '四', '五', '六'];
    $months = ['一月', '二月', '三月', '四月', '五月', '六月',
               '七月', '八月', '九月', '十月', '十一月', '十二月'];

    $year = date_format($date, 'Y');
    $month = date_format($date, 'n') - 1;
    $day = date_format($date, 'j');
    $weekday = date_format($date, 'w');

    return "{$year}年{$months[$month]}{$day}日 星期{$weekdays[$weekday]}";
}

echo formatChineseDate($date); // 输出:2024年三月15日 星期五
?>

性能优化建议

日期格式化性能考虑
  1. 重用 DateTime 对象:如果需要多次格式化同一时间,重用DateTime对象而不是每次都创建
  2. 预定义格式字符串:将常用格式字符串定义为常量或变量
  3. 避免循环内创建对象:在循环外创建DateTime对象,循环内只进行格式化
  4. 使用合适的函数:简单格式化使用date(),复杂操作使用DateTime对象
  5. 缓存格式化结果:对于不常变化的时间,可以缓存格式化结果

相关函数

函数 描述
DateTime::format() 面向对象的日期格式化方法
date() 格式化本地时间/日期
strftime() 根据区域设置格式化本地时间/日期(PHP 8.1.0+已弃用)
gmdate() 格式化GMT/UTC日期/时间
date_create() 创建DateTime对象
date_create_from_format() 根据指定格式创建DateTime对象
date_timezone_set() 设置DateTime对象的时区