PHP中面向过程与面向对象代码获取本地时间结果不一致问题
核心问题出在Unix时间戳的本质和**date()函数的时区依赖**上:
date_timestamp_get($dt)返回的是UTC时间戳
Unix时间戳本身是基于UTC的绝对时间(从1970-01-01 00:00:00 UTC开始的秒数),与时区无关。不管你DateTime对象用的是America/Los_Angeles还是其他时区,date_timestamp_get拿到的都是同一个UTC时间戳。date()函数默认使用PHP配置时区
当你用date('Y.m.d H:i:s', $now)格式化时间戳时,date()会根据PHP的date.timezone配置(比如php.ini里的设置,或代码中date_default_timezone_set设置的时区),把UTC时间戳转换为该时区的本地时间。这和你DateTime对象里指定的America/Los_Angeles时区没有关联。临时方法的“有效”逻辑
你的临时方法是先把LA时区的DateTime对象格式化为本地时间字符串(比如"10/05/2024, 12:30:00"),再用strtotime()解析这个字符串。由于字符串里没有时区信息,strtotime()会默认用当前PHP配置的时区去解析这个字符串,得到一个对应该时区下该时间点的时间戳,最后再用date()格式化——相当于你把LA的时间“强行”当成了PHP默认时区的时间,所以输出结果和LA时区的时间一致,但这其实是一种巧合(或者说刚好匹配了你需要的结果)。
如果想用面向过程写法得到和DateTime对象一致的LA时区时间,不需要绕弯子,有两种直接的方式:
方式一:给date()指定时区参数(PHP 5.2+支持)
$dt = new DateTime("now", new DateTimeZone('America/Los_Angeles')); $now = date_timestamp_get($dt); // 第三个参数传入LA时区,直接格式化对应时区的时间 $pc = date('Y.m.d H:i:s', $now, new DateTimeZone('America/Los_Angeles'));
方式二:临时设置全局时区
// 先保存原有时区 $originalTimezone = ini_get('date.timezone'); // 临时切换到LA时区 date_default_timezone_set('America/Los_Angeles'); $dt = new DateTime("now", new DateTimeZone('America/Los_Angeles')); $now = date_timestamp_get($dt); $pc = date('Y.m.d H:i:s', $now); // 恢复原有时区(如果业务需要) date_default_timezone_set($originalTimezone);
内容的提问来源于stack exchange,提问作者Ken

