最近让我遇到麻烦的一件事就是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
请注意所有cacluated参数如何整齐地落入传递给函数的日历日期。但现在让我们来看看全球另一边的价值观:
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 - 或任何其他技巧 - 以获得所需的信息?
答案 0 :(得分:0)
我不确定我100%理解你的问题,但可能是你过分思考了这一点。我自己经常犯这样的罪。
此外,我不确定您使用的是哪个版本的PHP date_sun_info会返回associative array of timestamps 1 ,这与您的示例输出不匹配。
无论如何,要回答你的问题: -
是否有(未记录的)标志可以传递给PHP - 或任何其他技巧 - 以获得所需的信息?
没有标志(当然没有记录),但有一些技巧。返回的时间戳是事件的GMT(例如日出),因此您所要做的就是将所需的时区应用于它。 DateTime classes会让这很容易。
这里的例子是我如何重写你的功能: -
/**
* Get an array of human readable times for sun events
* @param \DateTime $date A \DateTime Object set to the desired date
* and the correct timezone for the place in question
* @param float $lat The latitude of the place in question
* @param float $lon The longitude of the place in question
*
* @return array An associative array of human readable times sorted in chronological order.
*/
function adjustedSunInfo(\DateTime $date,$lat,$lon) {
$sinfo=date_sun_info ($date->getTimestamp() ,$lat,$lon );
foreach($sinfo as $key=>$val) {
//You should check that $val isn't 1 or empty first
$time = new \DateTime('@' . $val);
$time->setTimezone($date->getTimeZone());
$sinfo[$key] = $time->format('Y m d H:i:s');
}
asort($sinfo);
return $sinfo;
}
$time = new \DateTime('2013-01-01', new \DateTimeZone('Pacific/Chatham'));
var_dump(adjustedSunInfo($time, -44.5, -176.2));
你的榜样位于查塔姆群岛附近,所以我使用了他们的时区。你需要知道有问题的时区才能得到准确的答案。
这种方法不会因为DST的变化或闰年而烦恼,我希望您同意,这种方法更简单易读。
我希望这可以解决你的问题。
1。有时可能返回1或空数组元素。