【发布时间】:2016-06-08 00:53:14
【问题描述】:
最近让我陷入困境的一件事是 PHP 的 date_sun_info() 函数。它返回一个数组,其中包含有关日光的信息,例如日出和日落,以及各种黄昏阶段。然而,当使用这个函数时,似乎 PHP 总是按时间顺序计算适当的参数。这可能会产生问题,具体取决于您想要这些参数的时区。
我们以这两个例子为例(假设我们使用 UTC 作为默认时区,即date_default_timezone_set("UTC")):
date_sun_info(strtotime("2013-01-01"),31.5,35.2)
返回
sunrise: 2013-01-01 04:38:39
sunset: 2013-01-01 14:47:28
transit: 2013-01-01 09:43:03
civil_twilight_begin: 2013-01-01 04:12:02
civil_twilight_end: 2013-01-01 15:14:05
nautical_twilight_begin: 2013-01-01 03:41:47
nautical_twilight_end: 2013-01-01 15:44:20
astronomical_twilight_begin: 2013-01-01 03:12:11
astronomical_twilight_end: 2013-01-01 16:13:56
注意所有计算参数如何巧妙地落入传递给函数的日历日期。但现在让我们看看地球另一端的价值:
date_sun_info(strtotime("2013-01-01"),-44.5,-176.2)
返回
sunrise: 2013-01-01 16:05:13
sunset: 2013-01-02 07:32:39
transit: 2013-01-01 23:48:56
civil_twilight_begin: 2013-01-01 15:28:55
civil_twilight_end: 2013-01-02 08:08:56
nautical_twilight_begin: 2013-01-01 14:41:04
nautical_twilight_end: 2013-01-02 08:56:47
astronomical_twilight_begin: 2013-01-01 13:40:01
astronomical_twilight_end: 2013-01-02 09:57:50
显然,某些参数不属于提供给函数的日历日期,而是针对指定时区计算的。 I noticed that this has thrown other people off in the past as well。但是,在某些情况下,需要获取指定日历日期的一天中不同阶段的时间。在上述示例的情况下,输出必须如下所示:
transit: 2013-01-01 00:48:26
sunset: 2013-01-01 08:32:38
civil_twilight_end: 2013-01-01 09:09:01
nautical_twilight_end: 2013-01-01 09:57:01
astronomical_twilight_end: 2013-01-01 10:58:26
astronomical_twilight_begin: 2013-01-01 14:39:57
nautical_twilight_begin: 2013-01-01 15:41:01
civil_twilight_begin: 2013-01-01 16:28:52
sunrise: 2013-01-01 17:05:10
我编写了一个自定义函数来解决这个问题:
function adjustedSunInfo($date,$lat,$lon) {
$sinfo=date_sun_info ( strtotime($date) ,$lat,$lon );
$sinfoMinus=date_sun_info ( strtotime($date)-86400 ,$lat,$lon );
$sinfoPlus=date_sun_info ( strtotime($date)+86400 ,$lat,$lon );
foreach($sinfo as $key=>$val) {
if(date("d",$val)>date("d",strtotime($date))) {
$sinfo[$key]=$sinfoMinus[$key];
} else if(date("d",$val)>date("d",strtotime($date))) {
$sinfo[$key]=$sinfoPlus[$key];
}
}
asort($sinfo);
return $sinfo;
}
但是,问题是是否有(未记录的)标志可以传递给 PHP - 或任何其他技巧 - 以获得所需的信息?
【问题讨论】:
-
对所有试图在使用 DST 的时区中使用
86400或60*60*24或类似方法来增加时间的读者的一般警告,您将在特定日期增加或减少一个小时,您的输出可能会受到负面影响。我意识到这个问题使用 UTC(没有 DST),但答案确实如此。幸运的是,答案不会使用86400增加时间。我之所以提出这一点,是因为在 SO 上有很多情况下,时间被86400增加而没有承认可能的后果。
标签: php date datetime calendar