date_sun_info()用于特定日历日期 [英] date_sun_info() for a specific calendar date

查看:119
本文介绍了date_sun_info()用于特定日历日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我遇到麻烦的一件事是PHP的 date_sun_info() 功能。它返回一个包含日光信息(如日出和日落)的数组,还有各种暮光阶段。但是,当使用此函数时,PHP总是按时间顺序计算适当的参数。这可能会产生一个问题,具体取决于您想要这些参数的时区。



让我们来看这两个例子(假设我们使用UTC作为默认时区,即 date_default_timezone_set(UTC)):

  date_sun_info(strtotime(2013-01-01),31.5,35.2)



返回

  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)

返回

 日出:2013-01-01 16:05:13 
日落: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

显然,一些参数不属于提供给函数的日历日期,计算指定的时区。 我注意到,其他人在过去也被抛弃了。然而,在一些情况下,期望的是获得指定日历日期的一天的不同阶段的时间。在上面的例子中,输出将如下所示:

  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
日出: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 )){
$ sinfo [$ key] = $ sinfoMinus [$ key];
} else if(date(d,$ val)> date(d,strtotime($ date))){
$ sinfo [$ key] = $ sinfoPlus [$ key] ;
}
}

asort($ sinfo);
return $ sinfo;
}

但是,问题是是否存在传递给PHP - 或任何其他技巧 - 获得所需的信息?

解决方案

我不确定我是否理解你的问题100%,但可能是你正在考虑这一点。我常常对自己有罪。



此外,我不确定您使用的PHP版本是 date_sun_info 返回关联时间戳数组 1 ,不符合您的示例输出。



无论如何,回答你的问题: -



< >

是否有一个(无证)的标志可以传递到PHP - 或任何其他的技巧 - 获得所需的信息?


没有标志(当然没有记录),但有一些技巧。返回的时间戳是事件的GMT(例如,日出),因此您只需将所需的时区应用到它。 日期时间类将使这一切变得容易。



下面的例子是我如何重写你的函数: -

  / ** 
*获取太阳事件的人类可读时间数组
* @param \DateTime $ date一个\DateTime对象设置为所需的日期
*和正确的所讨论位置的时区
* @param float $ lat相关位置的纬度
* @param float $ lon所讨论位置的经度
*
* @return array按时间顺序排序的人类可读时间的关联数组。
* /

function adjustedSunInfo(\DateTime $ date,$ lat,$ lon){
$ sinfo = date_sun_info($ date-> getTimestamp(),$ lat ,$ lon);

foreach($ sinfo as $ key => $ val){
//您应该检查$ val不是1或空的第一个
$ 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更改或Leap Years作为您的意见,



我希望这可以解决您的问题。



1。有时可能会返回1或一个空数组元素。


One thing that has gotten me into trouble recently was PHP's date_sun_info() function. It returns an array with information about daylight such as sunrise and sunset but also various twilight phases. However, when using this function it appears as if PHP always calculates the appropriate parameters chronologically. This can create a problem depending on the timezone you want these parameters for.

Let's take these two examples (assuming we're using UTC as default timezone, i.e. date_default_timezone_set("UTC")):

date_sun_info(strtotime("2013-01-01"),31.5,35.2)

returns

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

Note how all the cacluated parameters neatly fall into the calendar date that was passed to the function. But now let's look at values for the other side of the globe:

date_sun_info(strtotime("2013-01-01"),-44.5,-176.2)

which returns

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

Obviously, some of the parameters do not fall into the calendar date fed to the function but are calculated for the specified timezone. I noticed that this has thrown other people off in the past as well. However, in some cases what is desired is to get the times of the different phases of the day for the specified calendar date. In the case of above example the output would have to look like this:

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

I have written a custom function to get around this:

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;
}

However, the question is whether there are an (undocumented) flags that can be passed to PHP - or any other tricks - to get the desired info?

解决方案

I'm not sure that I understand your problem 100%, but it may be that you are overthinking this a bit. I am often guilty of that myself.

Also, I'm not sure what version of PHP you are using as date_sun_info returns an associative array of timestamps1, which doesn't match your example output.

Anyway, to answer your question:-

whether there are an (undocumented) flags that can be passed to PHP - or any other tricks - to get the desired info?

There are no flags (certainly non documented), but there are some tricks. The timestamp returned is the GMT of the event (e.g. sunrise), so all you have to do is to apply the required timezone to it. The DateTime classes will make this easy.

As an example here is how I would rewrite your function:-

/**
* 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));

See it working.

Your example position is just off the Chatham Islands, so I have used their time zone for this. You need to know the timezone in question to get an accurate answer.

This method will not be upset by DST changes or Leap Years as yours will and, I hope you'll agree, is a lot simpler and easier to read.

I hope this goes someway towards solving your problem.

1. Sometimes 1 or an empty array element may be returned.

这篇关于date_sun_info()用于特定日历日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆