PHP strtotime在夏令时结束时段生成时间小于当前时间是什么原因
问题原因分析
time()函数返回的是线性递增的Unix时间戳,本质是UTC时间1970-01-01 00:00:00到当前时刻的秒数,不受本地时区、夏令时规则影响,返回值永远是当前的绝对时间,不存在误差。strtotime('+15 minutes')的计算逻辑并不是直接在当前时间戳上加900秒:它会先把当前时间戳转换为你设置的本地时区(此处为America/New_York)的可读时间格式,在本地时间的基础上叠加15分钟后,再把新的本地时间字符串解析回Unix时间戳。- 美国纽约时区的夏令时结束时,会出现两次1:00~2:00的区间:第一次为夏令时(EDT,UTC-4)的时段,第二次为切换到冬令时(EST,UTC-5)后回拨产生的重复时段,两个时段的本地时间显示完全一致,但对应的Unix时间戳相差3600秒。
- 当系统时间已经进入冬令时的1:00~2:00区间时,
strtotime()叠加15分钟后得到的本地时间字符串,会被PHP默认解析为更早的夏令时对应的时间戳,这个时间戳比time()返回的当前真实时间戳小了至少2700秒,因此会直接触发会话过期的判定。
快速修复方案
直接基于Unix时间戳做数值计算即可,完全避开本地时间解析的夏令时坑:
date_default_timezone_set('America/New_York'); // 直接在当前时间戳上加15分钟的秒数,不要用strtotime做相对时间计算 $expire = time() + 15 * 60; if ($expire < time()) { // session expired }
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

