2024年PHP开发者大会日本站

日期/时间运算

以下示例展示了关于夏令时转换和月份天数不同的日期/时间运算中的一些陷阱。

示例 #1 DateTimeImmutable::add/sub 添加涵盖已用时间的区间

在夏令时转换期间添加PT24H将显示添加了23/25小时(对于大多数时区)。

<?php
$dt
= new DateTimeImmutable("2015-11-01 00:00:00", new DateTimeZone("America/New_York"));
echo
"开始: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
$dt = $dt->add(new DateInterval("PT3H"));
echo
"结束: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
?>

以上示例将输出

Start: 2015-11-01 00:00:00 -04:00
End:   2015-11-01 02:00:00 -05:00

示例 #2 DateTimeImmutable::modify 和 strtotime 增加或减少单个组件值

在夏令时转换期间添加+24小时将精确添加24小时,如日期/时间字符串所示(除非开始或结束时间处于转换点)。

<?php
$dt
= new DateTimeImmutable("2015-11-01 00:00:00", new DateTimeZone("America/New_York"));
echo
"开始: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
$dt = $dt->modify("+24 hours");
echo
"结束: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
?>

以上示例将输出

Start: 2015-11-01 00:00:00 -04:00
End:   2015-11-02 00:00:00 -05:00

示例 #3 添加或减去时间可能会导致日期溢出或下溢

例如,1月31日 + 1个月将导致3月2日(闰年)或3月3日(平年)。

<?php
echo "平年:\n"; // 二月有28天
$dt = new DateTimeImmutable("2015-01-31 00:00:00", new DateTimeZone("America/New_York"));
echo
"开始: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
$dt = $dt->modify("+1 month");
echo
"结束: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;

echo
"闰年:\n"; // 二月有29天
$dt = new DateTimeImmutable("2016-01-31 00:00:00", new DateTimeZone("America/New_York"));
echo
"开始: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
$dt = $dt->modify("+1 month");
echo
"结束: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
?>

以上示例将输出

Normal year:
Start: 2015-01-31 00:00:00 -05:00
End:   2015-03-03 00:00:00 -05:00
Leap year:
Start: 2016-01-31 00:00:00 -05:00
End:   2016-03-02 00:00:00 -05:00

为了获取下个月的最后一天(即防止溢出),可以使用下个月的最后一天格式。

<?php
echo "平年:\n"; // 二月有28天
$dt = new DateTimeImmutable("2015-01-31 00:00:00", new DateTimeZone("America/New_York"));
echo
"开始: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
$dt = $dt->modify("下个月的最后一天");
echo
"结束: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;

echo
"闰年:\n"; // 二月有29天
$dt = new DateTimeImmutable("2016-01-31 00:00:00", new DateTimeZone("America/New_York"));
echo
"开始: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
$dt = $dt->modify("下个月的最后一天");
echo
"结束: ", $dt->format("Y-m-d H:i:s P"), PHP_EOL;
?>

以上示例将输出

Normal year:
Start: 2015-01-31 00:00:00 -05:00
End:   2015-02-28 00:00:00 -05:00
Leap year:
Start: 2016-01-31 00:00:00 -05:00
End:   2016-02-29 00:00:00 -05:00

添加注释

用户贡献注释

此页面没有用户贡献的注释。
To Top