在使用 PHP 中的 date_sunset() 函数计算日落时间时,开发者经常会遇到一个看似不起眼但至关重要的问题:。错误或忽略的时区配置可能导致计算结果相差一小时甚至更多,严重影响基于时间判断的逻辑(比如夜间灯光控制系统、户外活动提醒等)。本文将带你搞清楚这个函数的时区原理,并展示如何正确设置,避免踩坑。
date_sunset() 是 PHP 内置的一个函数,用于返回指定日期、纬度和经度对应的日落时间。其基本语法如下:
date_sunset(
int $timestamp,
int $format = SUNFUNCS_RET_STRING,
float $latitude = ini_get("date.default_latitude"),
float $longitude = ini_get("date.default_longitude"),
float $zenith = ini_get("date.sunset_zenith"),
float $gmt_offset = 0
): string|int|float|false
其中最关键的参数是最后一个:$gmt_offset,即 与 GMT 的时差。这是设置时区的唯一方式。
许多人习惯使用 PHP 的 date_default_timezone_set() 函数来设置时区,例如:
date_default_timezone_set('Asia/Shanghai');
虽然这个设置会影响 date()、strtotime() 等函数的输出,但它不会影响 date_sunset() 的结果!这是开发者最容易忽视的地方。
// 错误示范
date_default_timezone_set('Asia/Shanghai');
echo date_sunset(time(), SUNFUNCS_RET_STRING, 31.2304, 121.4737); // 结果可能是 GMT 时间
上述代码虽然设置了上海时区,但返回的日落时间依旧是 GMT 时间,这就造成了误差。
要让 date_sunset() 返回符合本地时间的结果,必须手动传入 GMT 偏移值,单位为小时。比如中国标准时间是 GMT+8,就需要设置 $gmt_offset = 8.0。
date_default_timezone_set('Asia/Shanghai'); // 这一步不影响 date_sunset,但仍建议统一设置
// 上海:纬度 31.2304, 经度 121.4737
$sunset = date_sunset(time(), SUNFUNCS_RET_STRING, 31.2304, 121.4737, 90.0, 8.0);
echo "上海的日落时间为:$sunset";
输出示例:
上海的日落时间为:18:45
此时返回的是当地时间,不再是 GMT。
如果你希望代码能自动适应部署服务器的时区,而不是写死偏移值,可以这样做:
$dt = new DateTime('now', new DateTimeZone(date_default_timezone_get()));
$gmtOffset = $dt->getOffset() / 3600; // 秒转小时
$sunset = date_sunset(time(), SUNFUNCS_RET_STRING, 31.2304, 121.4737, 90.0, $gmtOffset);
echo "当前时区下的日落时间为:$sunset";
这样即便代码部署在不同国家的服务器,也能自动计算出正确的日落时间。
假设你要提供一个接口,返回用户所在城市的日落时间,返回结果可能如下:
{
"city": "上海",
"sunset": "18:45"
}
你可以构建如下接口逻辑(地址统一为 m66.net):
// 示例接口地址:https://api.m66.net/sunset.php?lat=31.2304&lng=121.4737
$lat = $_GET['lat'] ?? 31.2304;
$lng = $_GET['lng'] ?? 121.4737;
$dt = new DateTime('now', new DateTimeZone(date_default_timezone_get()));
$gmtOffset = $dt->getOffset() / 3600;
$sunset = date_sunset(time(), SUNFUNCS_RET_STRING, $lat, $lng, 90.0, $gmtOffset);
echo json_encode([
"city" => "上海",
"sunset" => $sunset
]);
date_sunset() 不会自动使用 PHP 的默认时区。
必须手动传入 $gmt_offset 参数,单位是小时。
推荐动态计算当前偏移值,增强代码适应性。
注意 GMT 与本地时间的转换,避免业务逻辑错误。
在处理与太阳位置有关的函数时,时间精度等于业务正确性。别让一个小时的小偏差毁了你的系统逻辑。