Skip to content

日期时间处理技巧

PHP 中日期时间处理是常见需求,本文介绍 DateTime 类的使用方法和常见场景解决方案。

DateTime 基础使用

php
// 创建 DateTime 对象
$now = new DateTime();           // 当前时间
$date = new DateTime('2024-12-25 15:30:00');
$date = DateTime::createFromFormat('Y/m/d', '2024/12/25');

// 格式化输出
echo $now->format('Y-m-d H:i:s');      // 2024-12-25 15:30:00
echo $now->format('Y年m月d日');        // 2024年12月25日
echo $now->format('c');                // ISO 8601 格式

时间计算与比较

php
$date = new DateTime('2024-12-25');

// 加减时间
$date->modify('+1 day');      // 加1天
$date->modify('+3 months');   // 加3个月
$date->modify('-1 week');     // 减1周

// 链式操作
$date = (new DateTime())->modify('+7 days')->setTime(0, 0, 0);

// 计算时间差
$start = new DateTime('2024-12-01');
$end = new DateTime('2024-12-25');
$diff = $start->diff($end);

echo $diff->days;           // 24 天
echo $diff->format('%m 月 %d 天');

// 比较时间
if ($start < $end) {
    echo '开始时间早于结束时间';
}

时区处理

php
// 设置默认时区
date_default_timezone_set('Asia/Shanghai');

// 创建带时区的日期
$date = new DateTime('now', new DateTimeZone('Asia/Shanghai'));

// 时区转换
$utc = new DateTime('2024-12-25 12:00:00', new DateTimeZone('UTC'));
$utc->setTimezone(new DateTimeZone('Asia/Shanghai'));
echo $utc->format('Y-m-d H:i:s');  // 2024-12-25 20:00:00

// 获取所有时区
$timezones = DateTimeZone::listIdentifiers(DateTimeZone::ASIA);

获取时间范围

php
// 获取本周开始和结束
function getThisWeekRange() {
    $start = new DateTime('monday this week');
    $end = (clone $start)->modify('+6 days')->setTime(23, 59, 59);
    return ['start' => $start, 'end' => $end];
}

// 获取本月开始和结束
function getThisMonthRange() {
    $start = new DateTime('first day of this month');
    $end = new DateTime('last day of this month 23:59:59');
    return ['start' => $start, 'end' => $end];
}

// 获取最近 N 天的日期数组
function getLastDays($n) {
    $dates = [];
    for ($i = $n - 1; $i >= 0; $i--) {
        $dates[] = (new DateTime())->modify("-$i days")->format('Y-m-d');
    }
    return $dates;
}

人性化时间显示

php
function timeAgo($datetime) {
    $time = new DateTime($datetime);
    $now = new DateTime();
    $diff = $now->diff($time);

    if ($diff->y > 0) return $diff->y . '年前';
    if ($diff->m > 0) return $diff->m . '个月前';
    if ($diff->d > 0) return $diff->d . '天前';
    if ($diff->h > 0) return $diff->h . '小时前';
    if ($diff->i > 0) return $diff->i . '分钟前';
    return '刚刚';
}

// 使用示例
echo timeAgo('2024-12-25 10:00:00');

注意事项

  1. PHP 7.2+ 推荐使用 DateTime 类而非 date() 函数
  2. 数据库中存储时间推荐使用 UTC,显示时转换为本地时区
  3. 使用 cloneDateTimeImmutable 避免意外修改原对象
  4. 跨天时区转换可能导致日期变化,注意测试边界情况

Binstork