You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DigitalOcean服务器时区设置后PHP时间仍偏差3小时求助

问题分析与解决方案

你的问题核心是PHP处理日期时的时区解析不一致——虽然系统时区已设置正确,但PHP的时区配置或函数内的日期解析逻辑存在漏洞,导致计算出的时间差偏移3小时(正好是内罗毕与UTC的时差)。

修复步骤:

1. 修正函数内的日期解析逻辑(优先处理)

当前函数中new DateTime($date)未明确指定时区,可能受PHP全局时区配置影响导致解析错误。修改函数,明确指定时区并统一时间戳获取方式:

// prettify time date
function soshDate($date) {
    $timezone = new DateTimeZone("Africa/Nairobi");
    // 设置PHP默认时区
    date_default_timezone_set("Africa/Nairobi");
    // 当前UTC时间戳(与时区无关)
    $now = time();
    // 明确按内罗毕时区解析传入的日期
    $old = new DateTime($date, $timezone);
    $oldTime = $old->getTimestamp();
    $diff = $now - $oldTime;

    // 时间间隔判断逻辑
    if ($diff <= 60) { return "1 sec"; }
    else if (intval($diff/60) == 1) { return "1 min"; }
    else if ($diff / 60 < 60){ return intval($diff/60)." mins"; }
    else if (intval($diff / 3600) == 1){ return "1 hr"; }
    else if ($diff / 3600 <24){ return intval($diff/3600) . " hrs"; }
    else if ($diff/86400 == 1 ){ return "yesterday"; }
    else if ($diff/86400 > 1 && $diff/86400 <= 7){ return $old->format('D'); }
    else if ($diff/86400 > 7 && $diff/86400 <= 31){ return $old->format('j M'); }
    else{ return $old->format('j M');  }
}

如果你的数据库中存储的是UTC时间(而非内罗毕本地时间),则需要调整解析逻辑,先按UTC解析再转内罗毕时区:

// 针对UTC存储的日期
function soshDate($date) {
    $nairobiTz = new DateTimeZone("Africa/Nairobi");
    $utcTz = new DateTimeZone("UTC");
    date_default_timezone_set("Africa/Nairobi");
    
    $now = time();
    // 先按UTC解析日期,再转换为内罗毕时区
    $old = new DateTime($date, $utcTz);
    $old->setTimezone($nairobiTz);
    $oldTime = $old->getTimestamp();
    $diff = $now - $oldTime;

    // 时间间隔判断逻辑不变
    if ($diff <= 60) { return "1 sec"; }
    else if (intval($diff/60) == 1) { return "1 min"; }
    else if ($diff / 60 < 60){ return intval($diff/60)." mins"; }
    else if (intval($diff / 3600) == 1){ return "1 hr"; }
    else if ($diff / 3600 <24){ return intval($diff/3600) . " hrs"; }
    else if ($diff/86400 == 1 ){ return "yesterday"; }
    else if ($diff/86400 > 1 && $diff/86400 <= 7){ return $old->format('D'); }
    else if ($diff/86400 > 7 && $diff/86400 <= 31){ return $old->format('j M'); }
    else{ return $old->format('j M');  }
}

2. 检查并修正PHP全局时区配置

即使函数内设置了时区,PHP全局配置的时区可能影响其他日期处理逻辑,建议统一设置:

  • 在服务器上创建临时文件phpinfo.php,内容为:
    <?php phpinfo(); ?>
    
  • 访问该文件,查找date.timezone项,确认是否为Africa/Nairobi。
  • 如果不是,找到PHP配置文件(路径通常为/etc/php/{版本号}/apache2/php.ini或/etc/php/{版本号}/fpm/php.ini),修改:
    date.timezone = Africa/Nairobi
    
  • 重启Web服务:
    # Apache
    sudo systemctl restart apache2
    # PHP-FPM(根据版本调整)
    sudo systemctl restart php7.4-fpm
    

3. 验证系统时区与PHP时区一致性

再次确认系统时区设置:

timedatectl

输出应包含Time zone: Africa/Nairobi (EAT, +0300)。

内容的提问来源于stack exchange,提问作者Max Njoroge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:42:32