PHP常用日期时间函数

文章目录

环境

  • Windows 11 专业版
  • PHP 8.4.5

总结

如果不想看详细内容,可以只看总结:

  • 如果只是获取Unix时间戳,不涉及时区问题,可用 time() 函数
  • 其它涉及到时间比较和时区的情况下,优先使用 DateTime 类,它的功能最强大
  • PHP默认使用UTC时间,要想配置时区信息:
    • 可通过 date_default_timezone_set() 函数设置
    • 可在 php.ini 文件里设置

time()

time() 函数获取当前的Unix时间戳(单位是秒),返回值类型是 int

php 复制代码
echo time();

运行结果如下:

powershell 复制代码
1753430095

Unix时间戳不涉及时区问题。

mktime()

mktime() 函数把给定的年月日时分秒信息组合成一个Unix时间戳:

php 复制代码
$x = mktime(7, 54, 55, 7, 25, 2025);

echo $x; // 1753430095

注意:本例给定的年月日时分秒信息,是UTC的时间,因为默认没有配置时区,而Unix时间戳则不涉及时区问题。

date()

date() 函数将Unix时间戳转换为人类可读的日期时间格式,返回值类型是 string

php 复制代码
echo date("Y-m-d H:i:s", 1753430095);

运行结果如下:

powershell 复制代码
2025-07-25 07:54:55

注意:本例中输出的时间是UTC时间,因为默认没有配置时区。

第二个参数可以省略,其默认值为 time() ,也就是当前时间戳:

php 复制代码
echo date("Y-m-d H:i:s");

运行结果如下:

powershell 复制代码
2025-07-25 08:04:43

第一个参数是格式化字符串:

  • e :时区,如 UTCAsia/Shanghai
  • T :时区缩写,如 EST
  • O :与GMT的时差,如 +0800
  • P :与GMT的时差,如 +08:00
  • Z :与GMT的时差秒数,如 28800
  • Y :4位年份,如 2025
  • o :4位年份,ISO周数年份,一般不太常用
  • y :2位年份,如 25
  • M :英文缩写表示的月份,如 Jul
  • m :数字表示的月份(前面补0),如 07
  • n :数字表示的月份(前面不补0),如 7
  • t :当前月份的总天数,如 31
  • d :数字表示的日(前面补0),如 03
  • j :数字表示的日(前面不补0),如 3
  • S :序数词的缩写,比如对于3就是 rd ,所以 jS 就是 3rd
  • H :24小时制的小时(前面补0),如 19
  • h :12小时制的小时(前面补0),如 07
  • G :24小时制的小时(前面不补0),如 7
  • g :12小时制的小时(前面不补0),如 7
  • i :分(前面补0),如 08
  • s :秒(前面补0),如 05
  • A :大写的 AMPM
  • a :小写的 ampm
  • D :英文缩写表示的周几,如 Mon
  • l :英文全称表示的周几,如 Monday
  • w :数字表示的周几,如 1 (即周一)
  • DATE_RFC2822 :常量 'D, d M Y H:i:s O'
  • DATE_ATOM :常量 'Y-m-d\\TH:i:sP'

在格式字符串中,如果想输出上面的特殊字符,可用 \ 转义。但要小心,比如 \n ,本身在字符串中也会转义:

  • "\n" :在字符串中会被转义为换行符
  • '\n' :在字符串中不会被转义(注: '\\''\'')还是会被转义
  • '\n' :在 date() 函数中,作为格式字符串,会被转义

所以,如果想要在 date() 函数中打印 n ,则需要使用 \n ,且必须用单引号(否则就变成换行了)。

o 则没有这个问题,如果想要在 date() 函数中打印 o ,既可以使用 '\o' ,也可以使用 "\o" ,这是因为 \o 本身在字符串中没有转义。

时区

前面的 mktime()date() 函数例子中,默认使用的是UTC时间,因为我们没有配置时区信息。

想要配置时区信息的话:

  • 可以在代码里设置
  • 也可以通过配置文件设置

date_default_timezone_set() 和 date_default_timezone_get()

这两个函数分别是设置和获取时区信息:

php 复制代码
echo date_default_timezone_get() . PHP_EOL; // UTC

echo date("Y-m-d H:i:s", 1753430095) . PHP_EOL; // 2025-07-25 07:54:55

date_default_timezone_set('Asia/Shanghai');

echo date_default_timezone_get() . PHP_EOL; // Asia/Shanghai

echo date("Y-m-d H:i:s", 1753430095) . PHP_EOL; // 2025-07-25 15:54:55

php.ini

php.ini 文件(可通过 php --ini 查找其路径)里配置时区信息:

powershell 复制代码
......
[Date]
; Defines the default timezone used by the date functions
; https://php.net/date.timezone
;date.timezone =
......

可见,默认并没有设置时区。

将其修改为:

powershell 复制代码
......
date.timezone = Asia/Shanghai
......

保存退出,则默认时区已被改为上海。

在代码里验证:

php 复制代码
echo date_default_timezone_get() . PHP_EOL; // Asia/Shanghai

最后别忘了把配置改回去,免得影响后续测试。

其它

和JavaScript相比,后者是在浏览器运行,也就是在客户端运行,所以能够直接获取用户的时区信息,显示为本地时间,如下图所示:

而PHP是运行在服务器端的,无法获取客户端时区信息,所以最多只能显示服务器的本地时间。

那么默认情况下,为什么不使用服务器的本地时间,而是使用UTC时间呢?

这可能是因为,如果客户端与服务器不在同一个时区的话,如果在客户端看到的是服务器本地时间,反而更加困扰,还不如干脆显示为UTC时间。

如果你显式配置了时区信息,那自当别论。

DateTime

Date() 函数里无法显式设置时区参数,这可能是历史遗留问题。

如果想要"临时"设置时区,可用 DateTime 类。这样,可以只在 DateTime 对象中设置和修改时区,不影响全局时区配置。

DateTime 类相比传统的日期函数更强大、更面向对象,是处理日期时间操作的首选方式。

php 复制代码
$x = new DateTime();

var_dump($x);

运行结果为:

powershell 复制代码
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2025-08-06 01:41:50.533232"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}

默认是当前时间和PHP系统时区。

也可以指定时间和时区:

php 复制代码
$x = new DateTime('2025-08-06 11:22:33');
php 复制代码
$x = new DateTime('2025-08-06 11:22:33', new DateTimeZone('Asia/Shanghai'));

也可以指定Unix时间戳:

php 复制代码
$x = new DateTime('@' . 1753430095);

可以将DateTime对象按指定格式输出时间:

php 复制代码
echo $x->format('Y-m-d H:i:s');

注意, format() 方法无法指定时区,不过可以先设置时区,再格式化时间:

php 复制代码
echo $x->format('Y-m-d H:i:s'); // 2025-07-25 07:54:55

$x->setTimezone(new DateTimeZone('Asia/Shanghai'));

echo $x->format('Y-m-d H:i:s'); // 2025-07-25 15:54:55

获取Unix时间戳:

php 复制代码
echo $x->getTimestamp(); // 1753430095

注意:Unix时间戳与时区无关。

修改日期和时间,例如:

php 复制代码
$x->modify('+1 day'); // 增加1天

$x->add(new DateInterval('P1D')); // 增加1天

$x->sub(new DateInterval('P1M')); // 减少1个月

比较日期:

php 复制代码
if ($date1 < $date2) {
    echo 'date1 is earlier than date2';
}

计算日期和时间差异:

php 复制代码
$interval = $date1->diff($date2);

注意: diff() 方法返回的是一个 DateInterval 对象。可用 format() 方法将其格式化输出:

php 复制代码
echo $interval->format('%a days'); // 输出相差天数