PHP strptime()函数

注意: 从 PHP 8.1.0 开始,strptime() 函数已被弃用。建议使用 date_parse_from_format() 函数或 DateTime::createFromFormat() 方法替代。此外,此函数在 Windows 平台上不可用。

strptime() 函数解析由 strftime() 生成的日期/时间字符串。它将日期/时间字符串解析为数组,数组包含日期和时间的各个组成部分。

语法

strptime(string $date, string $format) : array|false

参数说明

参数 描述
date

必需。 要解析的日期/时间字符串,通常是由 strftime() 生成的。

format

必需。 指定 $date 参数的格式。格式字符与 strftime() 函数相同。

注意:与 C 语言的 strptime() 函数不同,PHP 的实现不支持所有格式说明符。

返回值

返回一个数组,包含解析后的日期/时间信息,如果解析失败则返回 false

返回数组的结构

键名 描述 范围
tm_sec 秒数 0-59
tm_min 分钟数 0-59
tm_hour 小时数 0-23
tm_mday 月份中的第几天 1-31
tm_mon 月份(从0开始,0=一月) 0-11
tm_year 从1900年开始的年数 例如 123 表示 2023 年
tm_wday 星期几(从0开始,0=星期日) 0-6
tm_yday 一年中的第几天 0-365
unparsed 未能解析的剩余字符串部分 字符串,如果没有剩余则为空字符串

支持的格式字符

格式字符 描述 示例
%a, %A 星期几的名称,缩写或全称 Mon, Monday
%b, %B, %h 月份的名称,缩写或全称 Jan, January
%C 世纪(年份/100) 20(对于2023年)
%d, %e 月份中的第几天,带前导零或空格 01-31, 1-31
%D 与 %m/%d/%y 相同 08/15/23
%H 24小时制的小时数(00-23) 00, 10, 23
%I 12小时制的小时数(01-12) 01, 10, 12
%j 一年中的第几天(001-366) 001, 227, 366
%m 月份数(01-12) 01, 08, 12
%M 分钟数(00-59) 00, 30, 59
%p 上午或下午(根据本地设置) AM, PM
%r 12小时制的时间(包括上午/下午) 10:30:45 AM
%R 24小时制的时间,不包含秒 10:30
%S 秒数(00-59) 00, 30, 59
%T 24小时制的时间(包含秒) 10:30:45
%U, %W 一年中的第几周 00-53
%w 星期几,0表示星期日 0-6
%x 默认的日期格式(根据本地设置) 08/15/23
%X 默认的时间格式(根据本地设置) 10:30:45
%y, %Y 2位或4位数的年份 23, 2023
%z, %Z 时区偏移或名称 +0800, CST
%% 百分号 %

示例

示例 1:基本用法

<?php
// 解析日期字符串
$date_str = "2023-08-15 10:30:45";
$format = "%Y-%m-%d %H:%M:%S";

$parsed = strptime($date_str, $format);

echo "<pre>";
print_r($parsed);
echo "</pre>";

if ($parsed) {
    // 注意:tm_year 是从1900年开始的年数,tm_mon 从0开始
    $year = $parsed['tm_year'] + 1900;
    $month = $parsed['tm_mon'] + 1;
    $day = $parsed['tm_mday'];

    echo "解析结果:{$year}年{$month}月{$day}日 {$parsed['tm_hour']}:{$parsed['tm_min']}:{$parsed['tm_sec']}";
}

// 输出类似:
// Array
// (
//     [tm_sec] => 45
//     [tm_min] => 30
//     [tm_hour] => 10
//     [tm_mday] => 15
//     [tm_mon] => 7
//     [tm_year] => 123
//     [tm_wday] => 2
//     [tm_yday] => 226
//     [unparsed] =>
// )
// 解析结果:2023年8月15日 10:30:45
?>

示例 2:解析包含星期和月份名称的字符串

<?php
// 设置区域为英语,以便解析英文月份和星期名称
setlocale(LC_TIME, 'en_US.UTF-8');

$date_str = "Tuesday, August 15, 2023 10:30:45 AM";
$format = "%A, %B %d, %Y %I:%M:%S %p";

$parsed = strptime($date_str, $format);

if ($parsed) {
    echo "解析成功!<br>";
    echo "年份:" . ($parsed['tm_year'] + 1900) . "<br>";
    echo "月份:" . ($parsed['tm_mon'] + 1) . "<br>";
    echo "日:" . $parsed['tm_mday'] . "<br>";
    echo "时间:" . $parsed['tm_hour'] . ":" . $parsed['tm_min'] . ":" . $parsed['tm_sec'];
} else {
    echo "解析失败";
}

// 输出:
// 解析成功!
// 年份:2023
// 月份:8
// 日:15
// 时间:10:30:45
?>

示例 3:解析不同格式的日期

<?php
// 测试不同日期格式的解析
$formats = [
    "%m/%d/%Y" => "08/15/2023",
    "%d-%m-%Y" => "15-08-2023",
    "%Y%m%d" => "20230815",
    "%d %b %Y" => "15 Aug 2023",
    "%c" => "Tue Aug 15 10:30:45 2023"
];

foreach ($formats as $format => $date_str) {
    $parsed = strptime($date_str, $format);
    echo "格式:{$format}<br>";
    echo "字符串:{$date_str}<br>";

    if ($parsed) {
        $year = $parsed['tm_year'] + 1900;
        $month = $parsed['tm_mon'] + 1;
        $day = $parsed['tm_mday'];
        echo "解析结果:{$year}-{$month}-{$day}<br><br>";
    } else {
        echo "解析失败<br><br>";
    }
}
?>

示例 4:处理解析失败的情况

<?php
// 无效的日期
$date_str = "2023-02-30"; // 2月没有30日
$format = "%Y-%m-%d";

$parsed = strptime($date_str, $format);

if ($parsed === false) {
    echo "日期 '{$date_str}' 解析失败,可能是无效日期";
} else {
    echo "解析成功";
}

// 输出:
// 日期 '2023-02-30' 解析失败,可能是无效日期
?>

示例 5:替代方案 - 使用 date_parse_from_format()

<?php
// 使用 date_parse_from_format() 替代 strptime()
$date_str = "2023-08-15 10:30:45";
$format = "Y-m-d H:i:s";

$parsed = date_parse_from_format($format, $date_str);

echo "<pre>";
print_r($parsed);
echo "</pre>";

if ($parsed['error_count'] == 0) {
    echo "解析成功:{$parsed['year']}-{$parsed['month']}-{$parsed['day']} {$parsed['hour']}:{$parsed['minute']}:{$parsed['second']}";
} else {
    echo "解析失败,错误数:" . $parsed['error_count'];
}

// 输出类似:
// Array
// (
//     [year] => 2023
//     [month] => 8
//     [day] => 15
//     [hour] => 10
//     [minute] => 30
//     [second] => 45
//     [fraction] => 0
//     [warning_count] => 0
//     [warnings] => Array()
//     [error_count] => 0
//     [errors] => Array()
//     [is_localtime] =>
// )
// 解析成功:2023-8-15 10:30:45
?>

示例 6:替代方案 - 使用 DateTime::createFromFormat()

<?php
// 使用 DateTime::createFromFormat() 替代 strptime()
$date_str = "15-Aug-2023 10:30:45";
$format = "d-M-Y H:i:s";

$date = DateTime::createFromFormat($format, $date_str);

if ($date) {
    echo "解析成功!<br>";
    echo "格式化输出:" . $date->format('Y-m-d H:i:s') . "<br>";
    echo "时间戳:" . $date->getTimestamp() . "<br>";

    // 获取详细信息
    echo "<pre>";
    print_r([
        'year' => $date->format('Y'),
        'month' => $date->format('m'),
        'day' => $date->format('d'),
        'hour' => $date->format('H'),
        'minute' => $date->format('i'),
        'second' => $date->format('s')
    ]);
    echo "</pre>";
} else {
    echo "解析失败";
}

// 输出类似:
// 解析成功!
// 格式化输出:2023-08-15 10:30:45
// 时间戳:1692077445
// Array
// (
//     [year] => 2023
//     [month] => 08
//     [day] => 15
//     [hour] => 10
//     [minute] => 30
//     [second] => 45
// )
?>

弃用说明和替代方案

重要通知:PHP 8.1.0 开始弃用

从 PHP 8.1.0 开始,strptime() 函数已被弃用,并将在 PHP 9.0.0 中移除。主要原因包括:

  1. Windows 平台不支持此函数
  2. 存在更好的替代方案(date_parse_from_format()DateTime::createFromFormat()
  3. 与时区处理相关的问题

替代方案:

  1. date_parse_from_format($format, $date) - 返回详细的解析结果数组
  2. DateTime::createFromFormat($format, $date) - 返回 DateTime 对象,功能更强大

格式字符转换表

strptime格式 date()/DateTime格式 描述
%Y Y 4位数的年份
%y y 2位数的年份
%m m 月份,两位数(01-12)
%d d 日,两位数(01-31)
%H H 24小时制的小时数(00-23)
%I h 12小时制的小时数(01-12)
%M i 分钟数(00-59)
%S s 秒数(00-59)
%p A 上午/下午(大写)
%b, %h M 月份的简写(Jan, Feb, ...)
%B F 月份的完整名称(January, February, ...)
%a D 星期几的简写(Mon, Tue, ...)
%A l 星期几的完整名称(Monday, Tuesday, ...)

注意事项

  • strptime() 在 Windows 平台上不可用
  • 从 PHP 8.1.0 开始,此函数已被弃用,建议尽快迁移到替代方案
  • 返回数组中的 tm_year 是从1900年开始的年数,tm_mon 从0开始(0=一月)
  • 解析包含本地化月份和星期名称的字符串时,需要先设置正确的区域(使用 setlocale()
  • 函数对格式字符串的支持可能因系统和C库的不同而有所差异
  • 时区信息可能无法正确解析

相关函数