PHP date_sub() 函数

date_sub() 函数是 DateTime::sub() 的过程化别名,用于从 DateTime 对象中减去指定的时间间隔。

注意:此函数在 PHP 5.3 及以上版本可用。建议使用面向对象风格的 DateTime::sub() 方法。

语法

date_sub(DateTime $object, DateInterval $interval): DateTime

参数

参数 类型 描述
$object DateTime 必需。DateTime对象,时间减法将应用于此对象
$interval DateInterval 必需。要减去的时间间隔,由 DateInterval 对象表示

返回值

返回修改后的 DateTime 对象。函数会修改原始对象并返回它,因此返回值和原始对象是同一个实例。

示例

示例 1:基本用法 - 减去天数

<?php
// 创建一个DateTime对象
$date = date_create('2023-12-25');
echo "原始日期: " . date_format($date, 'Y-m-d') . "\n";

// 创建一个时间间隔:10天
$interval = new DateInterval('P10D');

// 减去10天
date_sub($date, $interval);
echo "减去10天后: " . date_format($date, 'Y-m-d') . "\n";

// 再次减去5天
date_sub($date, DateInterval::createFromDateString('5 days'));
echo "再减去5天后: " . date_format($date, 'Y-m-d') . "\n";
?>
                            

输出:


原始日期: 2023-12-25
减去10天后: 2023-12-15
再减去5天后: 2023-12-10
                            
示例 2:减去复杂的日期时间间隔

<?php
// 创建一个DateTime对象
$date = date_create('2023-12-25 14:30:45');
echo "原始日期时间: " . date_format($date, 'Y-m-d H:i:s') . "\n";

// 创建一个复杂的时间间隔:1年2个月3天4小时5分钟6秒
$interval = new DateInterval('P1Y2M3DT4H5M6S');

// 减去这个时间间隔
date_sub($date, $interval);
echo "减去1年2个月3天4小时5分钟6秒后: " . date_format($date, 'Y-m-d H:i:s') . "\n";

// 使用面向对象风格(推荐)
$date2 = new DateTime('2024-06-15 10:00:00');
$interval2 = DateInterval::createFromDateString('2 weeks 3 days');
$date2->sub($interval2);
echo "面向对象风格 - 减去2周3天后: " . $date2->format('Y-m-d H:i:s') . "\n";
?>
                            

输出:


原始日期时间: 2023-12-25 14:30:45
减去1年2个月3天4小时5分钟6秒后: 2022-10-22 10:25:39
面向对象风格 - 减去2周3天后: 2024-05-29 10:00:00
                            
示例 3:实际应用 - 计算截止日期

<?php
/**
 * 计算任务截止日期
 * @param DateTime $startDate 开始日期
 * @param int $workDays 工作日数(假设每周工作5天)
 * @return DateTime 截止日期
 */
function calculateDeadline(DateTime $startDate, int $workDays): DateTime {
    $deadline = clone $startDate; // 克隆对象以避免修改原始对象
    $weeks = floor($workDays / 5);
    $remainingDays = $workDays % 5;

    // 减去整周数(每周末2天)
    if ($weeks > 0) {
        $interval = new DateInterval('P' . ($weeks * 7) . 'D');
        date_sub($deadline, $interval);
    }

    // 减去剩余工作日
    if ($remainingDays > 0) {
        $interval = new DateInterval('P' . $remainingDays . 'D');
        date_sub($deadline, $interval);
    }

    return $deadline;
}

// 使用示例
$startDate = date_create('2023-12-29');
$workDays = 10; // 需要10个工作日完成
$deadline = calculateDeadline($startDate, $workDays);

echo "开始日期: " . date_format($startDate, 'Y-m-d (l)') . "\n";
echo "需要工作日: $workDays 天\n";
echo "截止日期: " . date_format($deadline, 'Y-m-d (l)') . "\n";
?>
                            

输出:


开始日期: 2023-12-29 (Friday)
需要工作日: 10 天
截止日期: 2023-12-15 (Friday)
                            
DateInterval格式说明

DateInterval 构造函数使用ISO 8601持续时间格式:

  • P:时间间隔标识符(必须)
  • Y:年数
  • M:月数
  • D:天数
  • T:时间部分的开始标识符(如果有时间部分)
  • H:小时数
  • M:分钟数
  • S:秒数

示例:


P1Y2M3DT4H5M6S  // 1年2个月3天4小时5分钟6秒
P10D            // 10天
PT30M           // 30分钟
P1MT1H          // 1个月零1小时
                            

注意事项

  • 修改原对象:date_sub() 会直接修改传入的 DateTime 对象。如果需要保留原始对象,请先使用 clone 关键字克隆对象。
  • PHP版本:此函数在 PHP 5.3.0 中引入,确保您的PHP版本符合要求。
  • 面向对象风格:建议使用面向对象风格的 DateTime::sub() 方法,代码更清晰易读。
  • 月份天数差异:减去月份时需注意,如果目标月份的天数少于原始天数,日期会自动调整到目标月份的最后一天。
  • 时区处理:DateTime 对象包含时区信息,时间计算会考虑时区。

相关函数

date_add()

向DateTime对象添加时间间隔

date_diff()

计算两个DateTime对象之间的差异

DateTime::modify()

使用字符串修改DateTime对象