【发布时间】:2014-03-03 12:29:35
【问题描述】:
我一直在研究这个问题很长一段时间。我觉得我太努力了,一直在兜圈子。
问题
我需要计算夜间月光的小时数,即月亮在白天以外的地平线上的时间。已知的是给定日期的 UTC 日出/日落和月出/月落时间。最简单的(假设的)场景如下:
sunrise: 06:45
sunset: 18:20
moonrise: 02:30
moonset: 19:50
计算月光时间的算法是:
if(moonrise<sunset && sunrise<moonset) {
moonlighthours = (sunrise-moonrise)-(moonset-sunset);
}
同样简单:
sunrise: 06:45
sunset: 18:20
moonrise: 10:30
moonset: 19:50
if(moonrise>sunset && sunrise<moonset) {
moonlighthours = (moonset-sunset);
}
但是当我们处理 UTC 时,它可能会根据时区变得相当复杂,因为日出/日落和月出/日落时间可能会跨越三个不同的日期:
sunrise: 2014-02-05 23:30
sunset: 2014-02-06 12:20
moonrise: 2014-02-06 11:00
moonset: 2014-03-07 00:50
所以要计算 2014-02-06 的月光时间,我会尝试这样复杂的事情:
if(sunrise<midnight) { sunrise = midnight; }
if(sunset>midnight+24) { sunset = midnight+24; }
if(moonrise<midnight) { moonrise = midnight; }
if(moonset>midnight+24) { moonset = midnight+24 }
if(moonrise<sunset && sunrise<moonset) {
moonlighthours = (sunrise-moonrise)-(moonset-sunset);
} else if (moonrise>sunset && sunrise<moonset) {
moonlighthours = (moonset-sunset);
} else if (moonrise<sunset && sunrise>moonset) {
moonlighthours = (sunrise-moonrise);
} else {
moonlighthours=0;
}
试图使用if... else 结构覆盖由于月光和白天之间的相移而导致的所有可能场景是一场噩梦。所以我希望有人对这个问题有新的看法。任何帮助将不胜感激。
编辑
这是我根据@Ilmari Karonen 的建议提出的解决方案。这将计算给定日历日期内的月光小时数(使用 PHP 语法):
$mid00 = midnight; // unixtimestamp , e.g. 1391558400 (2014-02-05 00:00:00)
$mid24 = midnight+86399; // 1399075199 (2014-02-05 23:59:59)
$mr = moonrise;
$ms = moonset;
$sr = sunrise;
$ss = sunset;
$mr = $mr < $mid00 ? $mid00 : $mr;
$ms = $ms > $mid24 ? $mid24 : $ms;
$sr = $sr < $mid00 ? $mid00 : $sr;
$ss = $ss > $mid24 ? $Mid24 : $ss;
$ml_morn = 0; // moonlight hours during morning night
$ml_even = 0; // moonlight hours during evening night
if($ms > $mr) { // moon set later than moon rise
$ml_morn = $mr < $sr ? $sr-$mr : 0; // moon rises before sunrise?
$ml_even = $ms > $ss ? $ms-$ss : 0; // moon sets after sunset?
} else { // moon set before moon rise
$ml_even = $mr > $ss ? $mid24-$mr : $mid24 - $ss; // moon rises before sunset?
$ml_morn = $ms < $sr ? $ms-$mid00 : $sr - $mid00; // moon sets before sunrise?
}
moonlight_hours = $ml_morn = $ml_even;
【问题讨论】:
-
??? - 我不明白那个。
-
直到今天我才知道夏令时......认为太阳总是重要的,与每 28 天一次的罕见月亮相比......;)
-
您的输入是否实际上也包含日期,或者您只是获取一天中的时间并且必须猜测它是哪一天?
-
另外,您真的需要某个特定日历日期(可能包括两个时段,一个在早上和另一个在晚上)或一个晚上的月光小时数吗?您是否真的需要足够的精度才能有所作为?
-
@Ilmari Karonen - 是的,是的。所有输入的格式为
datetime。是的,我需要特定日历日期的月光,因为我正在处理时间序列数据,其中需要测试其他日期特定参数与夜间可见度的相关性。
标签: php algorithm datetime timezone date-arithmetic