date_time_set() 函数是 DateTime::setTime() 的过程化别名,用于设置 DateTime 对象的时间部分(小时、分钟、秒、微秒)。
DateTime::setTime() 方法。
date_time_set(DateTime $object, int $hour, int $minute, int $second = 0, int $microsecond = 0): DateTime
| 参数 | 类型 | 描述 |
|---|---|---|
$object |
DateTime | 必需。DateTime对象,时间设置将应用于此对象 |
$hour |
int | 必需。小时值(0-23)。注意:24小时制,超过23会自动进位到天数 |
$minute |
int | 必需。分钟值(0-59)。超过59会自动进位到小时 |
$second |
int | 可选。秒值(0-59)。默认0。超过59会自动进位到分钟 |
$microsecond |
int | 可选。微秒值(0-999999)。默认0。超过999999会自动进位到秒 |
返回修改后的 DateTime 对象。函数会修改原始对象并返回它,因此返回值和原始对象是同一个实例。
<?php
// 创建一个DateTime对象
$date = date_create('2023-12-25');
echo "原始日期: " . date_format($date, 'Y-m-d H:i:s') . "\n";
// 设置时间为14:30:45
date_time_set($date, 14, 30, 45);
echo "设置时间为14:30:45后: " . date_format($date, 'Y-m-d H:i:s') . "\n";
// 设置时间为09:15(秒和微秒使用默认值)
date_time_set($date, 9, 15);
echo "设置时间为09:15:00后: " . date_format($date, 'Y-m-d H:i:s') . "\n";
// 设置包含微秒的时间
date_time_set($date, 16, 45, 30, 123456);
echo "设置时间为16:45:30.123456后: " . $date->format('Y-m-d H:i:s.u') . "\n";
?>
输出:
原始日期: 2023-12-25 00:00:00
设置时间为14:30:45后: 2023-12-25 14:30:45
设置时间为09:15:00后: 2023-12-25 09:15:00
设置时间为16:45:30.123456后: 2023-12-25 16:45:30.123456
<?php
// 创建一个DateTime对象
$date = date_create('2023-12-25 10:00:00');
echo "原始日期时间: " . date_format($date, 'Y-m-d H:i:s') . "\n";
// 测试分钟进位到小时
date_time_set($date, 14, 70); // 70分钟 = 1小时10分钟
echo "设置14:70(70分钟自动进位): " . date_format($date, 'Y-m-d H:i:s') . "\n";
// 测试秒进位到分钟
date_time_set($date, 23, 45, 90); // 90秒 = 1分钟30秒
echo "设置23:45:90(90秒自动进位): " . date_format($date, 'Y-m-d H:i:s') . "\n";
// 测试微秒进位到秒
date_time_set($date, 8, 30, 0, 1500000); // 1,500,000微秒 = 1.5秒
echo "设置08:30:00.1500000(微秒自动进位): " . $date->format('Y-m-d H:i:s.u') . "\n";
// 综合测试:所有进位
date_time_set($date, 25, 70, 90, 2000000);
echo "设置25:70:90.2000000(所有进位): " . $date->format('Y-m-d H:i:s.u') . "\n";
echo "实际日期: " . $date->format('Y-m-d H:i:s') . "(注意:25小时进位到天数)\n";
?>
输出:
原始日期时间: 2023-12-25 10:00:00
设置14:70(70分钟自动进位): 2023-12-25 15:10:00
设置23:45:90(90秒自动进位): 2023-12-25 23:46:30
设置08:30:00.1500000(微秒自动进位): 2023-12-25 08:30:01.500000
设置25:70:90.2000000(所有进位): 2023-12-26 02:11:32.000000
实际日期: 2023-12-26 02:11:32(注意:25小时进位到天数)
<?php
/**
* 安排会议时间
* @param DateTime $meetingDate 会议日期
* @param int $startHour 开始小时
* @param int $startMinute 开始分钟
* @param int $durationMinutes 持续时间(分钟)
* @return array 返回会议开始和结束时间
*/
function scheduleMeeting(DateTime $meetingDate, int $startHour, int $startMinute, int $durationMinutes): array {
// 克隆对象以避免修改原始对象
$startTime = clone $meetingDate;
$endTime = clone $meetingDate;
// 设置开始时间
date_time_set($startTime, $startHour, $startMinute);
// 计算结束时间(添加持续时间)
date_time_set($endTime, $startHour, $startMinute + $durationMinutes);
return [
'start' => $startTime,
'end' => $endTime,
'duration_minutes' => $durationMinutes
];
}
/**
* 检查时间冲突
* @param array $meeting1 第一个会议
* @param array $meeting2 第二个会议
* @return bool 是否冲突
*/
function checkTimeConflict(array $meeting1, array $meeting2): bool {
$start1 = $meeting1['start']->getTimestamp();
$end1 = $meeting1['end']->getTimestamp();
$start2 = $meeting2['start']->getTimestamp();
$end2 = $meeting2['end']->getTimestamp();
return !($end1 <= $start2 || $start1 >= $end2);
}
// 使用示例:安排一天的会议
$day = date_create('2023-12-25');
// 安排多个会议
$meetings = [
scheduleMeeting($day, 9, 0, 60), // 9:00-10:00
scheduleMeeting($day, 10, 30, 90), // 10:30-12:00
scheduleMeeting($day, 14, 0, 120), // 14:00-16:00
scheduleMeeting($day, 15, 30, 30), // 尝试安排15:30-16:00(会冲突)
];
echo "2023年12月25日会议安排:\n\n";
foreach ($meetings as $index => $meeting) {
$meetingNumber = $index + 1;
echo "会议{$meetingNumber}:\n";
echo " 开始时间: " . $meeting['start']->format('H:i') . "\n";
echo " 结束时间: " . $meeting['end']->format('H:i') . "\n";
echo " 持续时间: " . $meeting['duration_minutes'] . "分钟\n";
// 检查与前一个会议是否冲突(除了第一个)
if ($index > 0) {
$hasConflict = checkTimeConflict($meetings[$index - 1], $meeting);
echo " 与会议{$index}冲突: " . ($hasConflict ? "是" : "否") . "\n";
}
echo "\n";
}
// 验证时间设置是否正确
echo "第一个会议详细信息:\n";
$firstMeeting = $meetings[0];
echo "开始时间: " . $firstMeeting['start']->format('Y-m-d H:i:s') . "\n";
echo "结束时间: " . $firstMeeting['end']->format('Y-m-d H:i:s') . "\n";
?>
输出:
2023年12月25日会议安排:
会议1:
开始时间: 09:00
结束时间: 10:00
持续时间: 60分钟
会议2:
开始时间: 10:30
结束时间: 12:00
持续时间: 90分钟
与会议1冲突: 否
会议3:
开始时间: 14:00
结束时间: 16:00
持续时间: 120分钟
与会议2冲突: 否
会议4:
开始时间: 15:30
结束时间: 16:00
持续时间: 30分钟
与会议3冲突: 是
第一个会议详细信息:
开始时间: 2023-12-25 09:00:00
结束时间: 2023-12-25 10:00:00
推荐使用面向对象风格的 DateTime::setTime() 方法,代码更清晰:
<?php
// 创建DateTime对象
$date = new DateTime('2023-12-25');
echo "原始: " . $date->format('Y-m-d H:i:s') . "\n";
// 设置时间
$date->setTime(14, 30, 45);
echo "设置后: " . $date->format('Y-m-d H:i:s') . "\n";
// 链式调用
$date = (new DateTime('2023-12-25'))
->setTime(9, 0) // 设置时间
->modify('+1 day'); // 修改日期
echo "链式调用结果: " . $date->format('Y-m-d H:i:s') . "\n";
// 设置带微秒的时间(PHP 7.1+)
$date->setTime(16, 45, 30, 123456);
echo "带微秒: " . $date->format('Y-m-d H:i:s.u') . "\n";
?>
输出:
原始: 2023-12-25 00:00:00
设置后: 2023-12-25 14:30:45
链式调用结果: 2023-12-26 09:00:00
带微秒: 2023-12-26 16:45:30.123456
DateTime::setTime() 方法,代码更易读且支持链式调用。
<?php
// 错误示例:未克隆对象
$originalDate = date_create('2023-12-25 10:00:00');
$modifiedDate = $originalDate;
date_time_set($modifiedDate, 14, 30);
// 两个变量都指向同一个对象,都会被修改
echo "原始日期: " . date_format($originalDate, 'Y-m-d H:i:s') . "(也被修改了!)\n";
// 正确做法:使用clone
$originalDate2 = date_create('2023-12-25 10:00:00');
$modifiedDate2 = clone $originalDate2;
date_time_set($modifiedDate2, 14, 30);
echo "克隆后修改 - 原始: " . date_format($originalDate2, 'Y-m-d H:i:s') . "\n";
echo "克隆后修改 - 修改后: " . date_format($modifiedDate2, 'Y-m-d H:i:s') . "\n";
?>
<?php
// 负数参数会导致意外结果
$date = date_create('2023-12-25 10:00:00');
date_time_set($date, -1, -30); // 负数会导致反向进位
echo "设置-1:-30后: " . date_format($date, 'Y-m-d H:i:s') . "\n";
echo "注意:-1小时 = 前一天的23小时,-30分钟 = 前一个小时的30分钟\n";
?>
$date = date_create('2023-12-25');
date_time_set($date, 14, 30, 0);
// 结果:2023-12-25 14:30:00
$date = date_create('2023-12-25');
date_modify($date, '+2 hours 30 minutes');
// 结果:2023-12-25 02:30:00
date_time_set() 会直接修改传入的 DateTime 对象。如果需要保留原始对象,请先使用 clone 关键字克隆对象。DateTime 对象包含时区信息,时间设置会考虑时区。clone 比创建新对象更高效。date_date_set()设置DateTime对象的日期部分
date_modify()使用字符串修改DateTime对象
date_timestamp_set()设置DateTime对象的Unix时间戳
DateTime::setTime()面向对象风格的设置时间方法
DateTime::setDate()设置DateTime对象的日期部分
date_create()创建新的DateTime对象