You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux UTC系统下将指定时区日期转为UTC起止时间的PHP实现

没问题,我来帮你搞定这两个需求——先把Linux服务器改成UTC时区,再用PHP算出目标时区对应日期的UTC起止时间,方便你查询数据库~

一、将Linux服务器设置为UTC时区

不同Linux发行版的设置方式略有差异,我给你两种常用的方法:

  • 方法一:用timedatectl(适用于systemd系统,比如Ubuntu 16.04+、CentOS 7+)

    1. 先查看当前服务器的时区状态:
      timedatectl status
      
    2. 设置为UTC时区:
      sudo timedatectl set-timezone UTC
      
    3. 再次执行timedatectl status验证,看到Time zone: UTC (UTC, +0000)就说明设置成功了。
  • 方法二:传统符号链接方式(适用于非systemd系统)

    1. 先备份原来的时区配置文件:
      sudo mv /etc/localtime /etc/localtime.bak
      
    2. 创建UTC时区的符号链接:
      sudo ln -sf /usr/share/zoneinfo/UTC /etc/localtime
      
    3. 执行date命令验证,输出里会显示UTC字样,比如Sat Mar 23 15:00:00 UTC 2024
二、PHP中获取目标时区对应日期的UTC起止时间

你举的例子是America/Denver时区的2018-03-24,要获取该日期当日记录的UTC时间范围,核心思路是:先构造目标时区当日的开始和结束时刻,再把这两个时刻转换为UTC时区。

1. 已知目标日期的情况

比如明确要处理2018-03-24这个日期,代码可以这么写:

// 定义目标时区
$targetTz = new DateTimeZone('America/Denver');
// 构造目标日期的00:00:00时刻(目标时区)
$dayStart = new DateTime('2018-03-24 00:00:00', $targetTz);
// 转换为UTC时区
$dayStartUtc = clone $dayStart;
$dayStartUtc->setTimezone(new DateTimeZone('UTC'));

// 构造目标日期的23:59:59时刻(目标时区)
$dayEnd = new DateTime('2018-03-24 23:59:59', $targetTz);
// 转换为UTC时区
$dayEndUtc = clone $dayEnd;
$dayEndUtc->setTimezone(new DateTimeZone('UTC'));

// 输出结果
echo "目标时区当日开始的UTC时间:" . $dayStartUtc->format('Y-m-d H:i:s') . "\n";
echo "目标时区当日结束的UTC时间:" . $dayEndUtc->format('Y-m-d H:i:s') . "\n";

执行后,America/Denver时区的2018-03-24 00:00:00会转换为UTC的2018-03-24 06:00:00(因为当时是夏令时,Denver比UTC晚6小时),而23:59:59会转换为2018-03-25 05:59:59

2. 基于当前时间自动获取目标时区日期的情况

如果要根据当前时间,自动获取目标时区当天的UTC范围,代码可以调整为:

$targetTz = new DateTimeZone('America/Denver');
// 获取当前时间在目标时区的日期
$nowInTarget = new DateTime('now', $targetTz);
$currentDate = $nowInTarget->format('Y-m-d');

// 构造当日开始和结束时刻
$dayStart = new DateTime($currentDate . ' 00:00:00', $targetTz);
$dayStartUtc = clone $dayStart;
$dayStartUtc->setTimezone(new DateTimeZone('UTC'));

$dayEnd = new DateTime($currentDate . ' 23:59:59', $targetTz);
$dayEndUtc = clone $dayEnd;
$dayEndUtc->setTimezone(new DateTimeZone('UTC'));

echo "当前目标时区日期的UTC开始时间:" . $dayStartUtc->format('Y-m-d H:i:s') . "\n";
echo "当前目标时区日期的UTC结束时间:" . $dayEndUtc->format('Y-m-d H:i:s') . "\n";

小提示:更严谨的查询边界

23:59:59作为结束时间可能会漏掉毫秒级的记录(比如刚好在2018-03-24 23:59:59.999创建的记录),更稳妥的方式是用次日的00:00:00作为结束边界,查询时用小于这个时间,而不是小于等于

// 构造目标日期的次日00:00:00时刻(目标时区)
$nextDayStart = new DateTime($currentDate . ' +1 day', $targetTz);
$nextDayStartUtc = clone $nextDayStart;
$nextDayStartUtc->setTimezone(new DateTimeZone('UTC'));

// 数据库查询条件就写成:
// created_at >= '$dayStartUtc' AND created_at < '$nextDayStartUtc'

这样就不会漏掉任何属于目标日期的记录啦。

内容的提问来源于stack exchange,提问作者Steve Lloyd

火山引擎 最新活动