PHP date_date_set() 函数
date_date_set() 函数是 DateTime::setDate() 的过程化别名,用于设置 DateTime 对象的日期部分(年、月、日),同时保持时间部分不变。
提示: 这个函数特别适用于需要单独修改日期部分而不改变时间的场景,比如修改用户的出生日期但保持时间不变。
语法
DateTime date_date_set ( DateTime $object , int $year , int $month , int $day )
参数说明
| 参数 |
描述 |
必需 |
$object |
DateTime 对象,表示要修改的日期时间 |
是 |
$year |
年份(1-32767) |
是 |
$month |
月份(1-12) |
是 |
$day |
日期(1-31,根据月份和闰年自动调整) |
是 |
返回值
- 返回修改后的 DateTime 对象
- 原始 DateTime 对象也会被修改
- 支持链式调用
示例代码
示例 1:基本用法 - 修改日期
<?php
// 创建 DateTime 对象
$date = date_create('2024-03-15 14:30:45');
echo "原始日期: " . date_format($date, 'Y-m-d H:i:s') . "<br>";
// 修改日期部分(保持时间不变)
date_date_set($date, 2025, 6, 20);
echo "修改后日期: " . date_format($date, 'Y-m-d H:i:s');
// 输出:
// 原始日期: 2024-03-15 14:30:45
// 修改后日期: 2025-06-20 14:30:45
?>
示例 2:处理月末日期
<?php
// PHP会自动处理超出范围的天数
$date = date_create('2024-01-31 10:00:00');
// 尝试设置到2月30日(无效日期)
date_date_set($date, 2024, 2, 30);
// PHP会自动调整为2月的最后一天
echo "调整后日期: " . $date->format('Y-m-d H:i:s');
// 输出:2024-02-29 10:00:00(2024年是闰年)
// 另一个例子
$date2 = date_create('2024-03-31');
date_date_set($date2, 2024, 2, 31); // 2月没有31天
echo "<br>另一个例子: " . $date2->format('Y-m-d');
// 输出:2024-02-29(自动调整为2月最后一天)
?>
示例 3:链式调用
<?php
// 链式调用
$date = date_create('2024-03-15 09:30:00');
// 修改日期并格式化输出
$result = date_date_set($date, 2025, 12, 25)
->format('l, F j, Y \\a\\t g:i A');
echo "新的日期时间: " . $result;
// 输出:Thursday, December 25, 2025 at 9:30 AM
// 继续修改
echo "<br>";
date_date_set($date, 2023, 7, 4);
echo "再次修改: " . $date->format('Y-m-d H:i:s');
// 输出:2023-07-04 09:30:00
?>
示例 4:与DateTime::setDate()比较
<?php
// 使用date_date_set()函数
$date1 = date_create('2024-03-15 14:30:00');
date_date_set($date1, 2025, 6, 20);
echo "date_date_set: " . $date1->format('Y-m-d H:i:s') . "<br>";
// 使用DateTime::setDate()方法
$date2 = new DateTime('2024-03-15 14:30:00');
$date2->setDate(2025, 6, 20);
echo "DateTime::setDate: " . $date2->format('Y-m-d H:i:s') . "<br>";
// 两种方法输出相同:2025-06-20 14:30:00
// 使用date_modify()作为替代
$date3 = date_create('2024-03-15 14:30:00');
date_modify($date3, '2025-06-20');
echo "date_modify: " . $date3->format('Y-m-d H:i:s');
// 注意:date_modify会重置时间为00:00:00,除非指定时间
?>
示例 5:错误处理
<?php
// 错误处理示例
$date = date_create('2024-03-15 14:30:00');
// 无效的月份
try {
date_date_set($date, 2024, 13, 1); // 月份超出范围
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "<br>";
}
// PHP 8.0+ 会抛出异常,PHP 7.x 会尝试自动调整
// PHP 8.0+ 输出:DateTime::setDate(): Argument #2 ($month) must be between 1 and 12
// 负数值处理
$date2 = date_create('2024-03-15');
try {
date_date_set($date2, 2024, -1, 1); // 负月份
echo "处理后的日期: " . $date2->format('Y-m-d') . "<br>";
} catch (Exception $e) {
echo "负值错误: " . $e->getMessage();
}
// 在PHP 8.0+中,负值会抛出异常
?>
示例 6:实用场景
<?php
// 场景1:调整活动日期
function rescheduleEvent($originalDateTime, $newYear, $newMonth, $newDay) {
$date = date_create($originalDateTime);
date_date_set($date, $newYear, $newMonth, $newDay);
return $date;
}
$originalEvent = '2024-03-15 19:00:00';
$rescheduledEvent = rescheduleEvent($originalEvent, 2024, 5, 10);
echo "活动重新安排: " . $rescheduledEvent->format('Y-m-d H:i:s') . "<br>";
// 场景2:生日日期修正(保持出生时间)
function correctBirthDate($birthDateTime, $correctYear, $correctMonth, $correctDay) {
$birthDate = date_create($birthDateTime);
date_date_set($birthDate, $correctYear, $correctMonth, $correctDay);
return $birthDate;
}
$birthRecord = '2000-00-00 08:30:00'; // 数据库中的占位符日期
$correctedBirth = correctBirthDate($birthRecord, 1990, 6, 15);
echo "修正出生日期: " . $correctedBirth->format('Y-m-d H:i:s') . "<br>";
// 场景3:季度末日期设置
function setQuarterEndDate($date, $year, $quarter) {
$quarterEndMonths = [
1 => 3, // Q1: 3月
2 => 6, // Q2: 6月
3 => 9, // Q3: 9月
4 => 12, // Q4: 12月
];
if (!isset($quarterEndMonths[$quarter])) {
return false;
}
$month = $quarterEndMonths[$quarter];
$lastDay = date_create("$year-$month-01")
->modify('last day of this month')
->format('d');
$newDate = date_create($date);
date_date_set($newDate, $year, $month, $lastDay);
return $newDate;
}
$currentDate = '2024-03-15 14:30:00';
$q1End = setQuarterEndDate($currentDate, 2024, 1);
echo "第一季度末: " . $q1End->format('Y-m-d H:i:s');
// 输出:2024-03-31 14:30:00
?>
与其他日期修改函数比较
| 函数/方法 |
描述 |
是否改变时间部分 |
示例 |
date_date_set() |
仅修改日期部分(年、月、日) |
否 |
date_date_set($date, 2025, 6, 20) |
date_time_set() |
仅修改时间部分(时、分、秒) |
是(只改时间) |
date_time_set($date, 15, 30, 0) |
date_modify() |
使用字符串修改日期时间 |
可能改变 |
date_modify($date, '+1 day') |
DateTime::setTimestamp() |
设置Unix时间戳 |
是(完全改变) |
$date->setTimestamp(1700000000) |
注意事项
重要提示:
- date_date_set() 会修改原始 DateTime 对象(mutable)
- 对于无效日期(如2月30日),PHP会自动调整到有效日期
- 时间部分(时、分、秒、微秒)保持不变
- 在PHP 8.0+中,无效参数会抛出异常;在PHP 7.x中,会尝试自动调整
- 要创建不修改原对象的新对象,可以先克隆原对象:
clone $date
- 函数返回修改后的对象本身,支持链式调用
PHP版本差异
| PHP版本 |
行为 |
说明 |
| PHP 7.x |
自动调整无效参数 |
月份13会调整为1(下一年1月),天数32会调整为下月1日 |
| PHP 8.0+ |
抛出异常 |
无效参数(如月份13)会抛出ValueError异常 |
| 所有版本 |
时间部分保持不变 |
只修改日期部分,时间部分不受影响 |
<?php
// PHP版本兼容性示例
$date = date_create('2024-03-15 14:30:00');
try {
// 在PHP 7.x中:这会将日期调整为2025-01-01 14:30:00
// 在PHP 8.0+中:这会抛出异常
date_date_set($date, 2024, 13, 1);
echo "PHP 7.x行为: " . $date->format('Y-m-d H:i:s') . "<br>";
} catch (Exception $e) {
echo "PHP 8.0+行为: " . $e->getMessage() . "<br>";
}
// 安全的方式:先验证参数
function safeDateSet($date, $year, $month, $day) {
// 验证月份
if ($month < 1 || $month > 12) {
throw new InvalidArgumentException("月份必须在1-12之间");
}
// 验证日期
if (!checkdate($month, $day, $year)) {
throw new InvalidArgumentException("无效的日期");
}
return date_date_set($date, $year, $month, $day);
}
try {
$safeDate = date_create('2024-03-15 14:30:00');
safeDateSet($safeDate, 2024, 6, 15);
echo "安全设置: " . $safeDate->format('Y-m-d H:i:s');
} catch (Exception $e) {
echo "安全设置错误: " . $e->getMessage();
}
?>
相关函数
| 函数 |
描述 |
date_time_set() |
设置DateTime对象的时间部分 |
date_modify() |
使用相对/绝对字符串修改DateTime对象 |
DateTime::setDate() |
面向对象的日期设置方法 |
DateTime::setTimestamp() |
通过Unix时间戳设置DateTime对象 |
checkdate() |
验证日期的有效性 |