迁移至AWS时strtotime在两台服务器运行结果不一致求助
解决PHP strtotime('this week')在AWS服务器上返回不一致的问题
我之前也碰到过几乎一模一样的问题——多台服务器跑完全相同的PHP代码,结果strtotime('this week')返回的时间戳差了整整一周。其实这和你设置的UTC时区无关,核心原因是两台服务器的系统区域(LC_TIME)设置不一样!
问题原因拆解
先把你给出的两个时间戳转成UTC日期看看:
- 正确值
1520816400对应:2018-03-12 01:00:00 - 错误值
1520211600对应:2018-03-05 01:00:00
两者刚好差7天,说明一台服务器把周日当作一周的第一天,另一台把周一当作一周的第一天。PHP的strtotime处理this week这类相对时间字符串时,会读取系统的LC_TIME区域设置来判断周起始日——AWS不同区域的服务器镜像,默认的区域配置可能不一样(比如美国区默认en_US,欧洲区默认en_GB),这就导致了相同代码输出不同结果。
具体解决方案
1. 统一服务器的区域设置
针对Linux系统的AWS服务器,你可以通过以下步骤统一LC_TIME配置:
- 先查看当前区域设置:
locale | grep LC_TIME - 选择统一的区域,比如设置为周起始日为周日的
en_US.UTF-8:
或者设置为周起始日为周一的sudo update-locale LC_TIME=en_US.UTF-8en_GB.UTF-8:sudo update-locale LC_TIME=en_GB.UTF-8 - 重启PHP-FPM或Web服务器,让配置生效。
2. 用明确代码替代模糊时间表达式
如果不想修改服务器配置,更稳妥的方式是写死“本周起始”的计算逻辑,彻底摆脱系统设置的影响。比如你需要本周一的0点UTC时间,可以这样写:
date_default_timezone_set('UTC'); $baseTimestamp = 1520730000; // 获取给定时间戳对应的星期几(0=周日,1=周一,...6=周六) $dayOfWeek = date('w', $baseTimestamp); // 计算距离本周一的天数:周日减6天,其他星期减(当前星期-1)天 $daysToSubtract = $dayOfWeek == 0 ? 6 : ($dayOfWeek - 1); $mondayTimestamp = $baseTimestamp - ($daysToSubtract * 86400); // 调整到当天0点 $thisWeekStart = strtotime('midnight', $mondayTimestamp); echo $thisWeekStart . PHP_EOL; // 输出统一的本周一0点UTC时间戳 echo date('Y-m-d H:i:s', $thisWeekStart) . PHP_EOL;
3. 快速验证服务器配置差异
可以在两台服务器上运行以下代码,直接定位差异点:
date_default_timezone_set('UTC'); echo "当前时区: " . date_default_timezone_get() . PHP_EOL; echo "LC_TIME区域设置: " . setlocale(LC_TIME, 0) . PHP_EOL; echo "strtotime('this week')结果: " . strtotime('this week', 1520730000) . PHP_EOL; echo "对应日期: " . date('Y-m-d H:i:s', strtotime('this week', 1520730000)) . PHP_EOL;
对比两台服务器的LC_TIME输出,就能100%确认是不是区域设置导致的问题。
内容的提问来源于stack exchange,提问作者Nishant Nair
相关产品推荐
相关产品推荐

