PHP自定义UTC转本地时间函数返回异常结果求助
UTC转本地时间函数返回异常问题
我在PHP中编写了如下函数,用于将MySQL数据库中的UTC时间转换为本地时间,但调用时$dt_now_local_time始终返回9月13日(当前实际为14日),若将代码移出函数执行则结果正常,请问问题原因是什么?
原函数代码
function dt_utc_to_local($dt_utc, $timezone) { $dt_utc2 = new DateTimeImmutable($dt_utc, new DateTimeZone('UTC')); $dt_local_time = $dt_utc2->setTimezone(new DateTimeZone($timezone)); $dt_local_time_formated = $dt_local_time->format('Y-m-d H:i:s'); $dt_now_utc = new DateTimeImmutable(gmdate("Y-m-d H:i:s"), new DateTimeZone('UTC')); $dt_now_local_time = $dt_now_utc->setTimezone(new DateTimeZone($timezone)); $now_dt_local_time_formated = $dt_now_local_time->format('Y-m-d H:i:s'); return array($now_dt_local_time_formated, $dt_local_time_formated ); }
调用代码
$msg_date = '2022-09-14 12:00:00'; $timezone = 'America/New_York'; list($dt_now_local_time, $dt_local_time ) = dt_utc_to_local($msg_date, $timezone);
问题原因
核心问题出在当前UTC时间的创建逻辑:new DateTimeImmutable(gmdate("Y-m-d H:i:s"), new DateTimeZone('UTC'))
gmdate("Y-m-d H:i:s")确实会输出UTC时间的字符串,但DateTimeImmutable的第二个参数仅用于解析带时区标识的输入字符串。当输入字符串是无时区的Y-m-d H:i:s格式时,PHP会忽略你传入的UTC时区参数,转而使用php.ini中date.timezone配置的服务器本地时区去解析这个字符串。
如果服务器本地时区比UTC晚(比如西半球时区),解析出来的时间会被错误地偏移,导致转换为目标时区(如America/New_York)后日期提前一天。
而代码移出函数后正常,大概率是因为函数外的环境中date.timezone被临时设置为UTC,或者创建时间的方式没有触发这个解析冲突。
修复方案
直接使用'now'作为参数创建UTC时间对象,跳过gmdate的字符串中转,确保时间对象从初始化阶段就基于UTC:
function dt_utc_to_local($dt_utc, $timezone) { $dt_utc2 = new DateTimeImmutable($dt_utc, new DateTimeZone('UTC')); $dt_local_time = $dt_utc2->setTimezone(new DateTimeZone($timezone)); $dt_local_time_formated = $dt_local_time->format('Y-m-d H:i:s'); // 直接创建UTC时区下的当前时间,避免字符串解析的时区问题 $dt_now_utc = new DateTimeImmutable('now', new DateTimeZone('UTC')); $dt_now_local_time = $dt_now_utc->setTimezone(new DateTimeZone($timezone)); $now_dt_local_time_formated = $dt_now_local_time->format('Y-m-d H:i:s'); return array($now_dt_local_time_formated, $dt_local_time_formated ); }
内容的提问来源于stack exchange,提问作者electronixG
相关产品推荐
相关产品推荐

