From: dtorop932 at gmail dot com
Operating system: GNU/Linux
PHP version: 5CVS-2004-11-29 (dev)
PHP Bug Type: Date/time related
Bug description: date_sunrise() & date_sunset() don't handle endless day/night
at high latitudes
Description:
------------
php_do_date_sunrise_sunset() in ext/standard/sunfuncs.c should know about
midnight sun and endless night at high latitudes. The relevant code to
handle this is currently commented out at lines 116-120.
In addition, nonsensical times (such as "-3:-4") can be returned with
format SUNFUNCS_RET_STRING due to negative gmt_offset parameters.
It is unclear how this data should be returned, e.g. a descriptive string
("none"?) for SUNFUNCS_RET_STRING. Also, whether endless day and endless
night should somehow be differentiated.
Below is the start of a patch for this. It is a bit ugly and makes some
inelegant decisions of how to represent these cases. Regardless, the
"expected result" below is the output from a patched sunfuncs.c.
--- ext/standard/sunfuncs.c.orig 2004-11-29 15:59:48.000000000
-0500
+++ ext/standard/sunfuncs.c 2004-11-29 17:09:34.000000000 -0500
@@ -113,11 +113,14 @@
/* step 7a: calculate the sun's local hour angle */
cosH = (cos(to_rad(zenith)) - (sinDec * sin(to_rad(latitude)))) /
(cosDec * cos(to_rad(latitude)));
- /* XXX: What's the use of this block.. ?
- * if (!calc_sunset && cosH > 1 || calc_sunset && cosH < -1) {
- * throw doesnthappen();
- * }
- */
+ if (cosH > 1) {
+ /* the sun will not rise */
+ return -1;
+ }
+ if (cosH < -1) {
+ /* the sun will not set */
+ return -2;
+ }
/* step 7b: finish calculating H and convert into hours */
if (calc_sunset) {
@@ -200,11 +203,37 @@
break;
}
- ret = php_sunrise_sunset(N, latitude, longitude, zenith,
calc_sunset) + gmt_offset;
+ ret = php_sunrise_sunset(N, latitude, longitude, zenith,
calc_sunset);
+ /* is there no sunrise or sunset? */
+ if (ret < 0) {
+ switch (retformat) {
+ case SUNFUNCS_RET_TIMESTAMP:
+ RETURN_LONG((int) ret);
+ break;
+ case SUNFUNCS_RET_STRING:
+ if (ret == -1) {
+ RETURN_STRING("none", 1);
+ } else {
+ RETURN_STRING("always up", 1);
+ }
+ break;
+ case SUNFUNCS_RET_DOUBLE:
+ RETURN_DOUBLE(ret);
+ break;
+ }
+ }
+
+ ret += gmt_offset;
+ while (ret < 0) {
+ ret += 24;
+ }
+ while (ret > 24) {
+ ret -= 24;
+ }
switch (retformat) {
case SUNFUNCS_RET_TIMESTAMP:
Reproduce code:
---------------
<?php
$longitude = 0; // arbitrary longitude -- doesn't matter for
// arbitrarily look at May 15 and November 29, both of which have no
sunrise or sunset above 70th latitude
foreach (array("15 May 2004", "20 November 2004") as $date) {
print "\nDate: $date\n";
$time = strtotime($date);
foreach (array("SUNFUNCS_RET_TIMESTAMP", "SUNFUNCS_RET_STRING",
"SUNFUNCS_RET_DOUBLE") as $format_name) {
print " Format: $format_name\n";
$format = constant($format_name);
foreach (range(69,72) as $latitude) {
print " latitude: $latitude" .
" sunrise: " . date_sunrise($time, $format, $latitude,
$longitude, 90.83, -5) .
" sunset: " . date_sunset($time, $format, $latitude, $longtitude,
90.83, -5) . "\n";
}
print "\n";
}
}
?>
Expected result:
----------------
Date: 15 May 2004
Format: SUNFUNCS_RET_TIMESTAMP
latitude: 69 sunrise: 1084580415 sunset: 1084580261
latitude: 70 sunrise: 1084580364 sunset: 1084580325
latitude: 71 sunrise: -2 sunset: -2
latitude: 72 sunrise: -2 sunset: -2
Format: SUNFUNCS_RET_STRING
latitude: 69 sunrise: 20:15 sunset: 17:41
latitude: 70 sunrise: 19:24 sunset: 18:45
latitude: 71 sunrise: always up sunset: always up
latitude: 72 sunrise: always up sunset: always up
Format: SUNFUNCS_RET_DOUBLE
latitude: 69 sunrise: 20.253089585446 sunset: 17.694458258503
latitude: 70 sunrise: 19.40435878461 sunset: 18.754862725714
latitude: 71 sunrise: -2 sunset: -2
latitude: 72 sunrise: -2 sunset: -2
Date: 20 November 2004
Format: SUNFUNCS_RET_TIMESTAMP
latitude: 69 sunrise: 1100909101 sunset: 1100909307
latitude: 70 sunrise: 1100909130 sunset: 1100909276
latitude: 71 sunrise: -1 sunset: -1
latitude: 72 sunrise: -1 sunset: -1
Format: SUNFUNCS_RET_STRING
latitude: 69 sunrise: 05:01 sunset: 08:27
latitude: 70 sunrise: 05:30 sunset: 07:56
latitude: 71 sunrise: none sunset: none
latitude: 72 sunrise: none sunset: none
Format: SUNFUNCS_RET_DOUBLE
latitude: 69 sunrise: 5.0176291994972 sunset: 8.4611376500614
latitude: 70 sunrise: 5.5108334557604 sunset: 7.9447538821896
latitude: 71 sunrise: -1 sunset: -1
latitude: 72 sunrise: -1 sunset: -1
Actual result:
--------------
Date: 15 May 2004
Format: SUNFUNCS_RET_TIMESTAMP
latitude: 69 sunrise: 1084578976 sunset: 1084580261
latitude: 70 sunrise: 1084578925 sunset: 1084580325
latitude: 71 sunrise: -1062904448 sunset: -1062904448
latitude: 72 sunrise: -1062904448 sunset: -1062904448
Format: SUNFUNCS_RET_STRING
latitude: 69 sunrise: -3:-4 sunset: 17:41
latitude: 70 sunrise: -4:-3 sunset: 18:45
latitude: 71 sunrise: -2147 sunset: -2147
latitude: 72 sunrise: -2147 sunset: -2147
Format: SUNFUNCS_RET_DOUBLE
latitude: 69 sunrise: -3.746910414554 sunset: 17.694458258503
latitude: 70 sunrise: -4.5956412153904 sunset: 18.754862725714
latitude: 71 sunrise: NAN sunset: NAN
latitude: 72 sunrise: NAN sunset: NAN
Date: 20 November 2004
Format: SUNFUNCS_RET_TIMESTAMP
latitude: 69 sunrise: 1100909101 sunset: 1100909307
latitude: 70 sunrise: 1100909130 sunset: 1100909276
latitude: 71 sunrise: -1046574848 sunset: -1046574848
latitude: 72 sunrise: -1046574848 sunset: -1046574848
Format: SUNFUNCS_RET_STRING
latitude: 69 sunrise: 05:01 sunset: 08:27
latitude: 70 sunrise: 05:30 sunset: 07:56
latitude: 71 sunrise: -2147 sunset: -2147
latitude: 72 sunrise: -2147 sunset: -2147
Format: SUNFUNCS_RET_DOUBLE
latitude: 69 sunrise: 5.0176291994972 sunset: 8.4611376500614
latitude: 70 sunrise: 5.5108334557604 sunset: 7.9447538821896
latitude: 71 sunrise: NAN sunset: NAN
latitude: 72 sunrise: NAN sunset: NAN
--
Edit bug report at http://bugs.php.net/?id=30937&edit=1
--
Try a CVS snapshot (php4): http://bugs.php.net/fix.php?id=30937&r=trysnapshot4
Try a CVS snapshot (php5.0):
http://bugs.php.net/fix.php?id=30937&r=trysnapshot50
Try a CVS snapshot (php5.1):
http://bugs.php.net/fix.php?id=30937&r=trysnapshot51
Fixed in CVS: http://bugs.php.net/fix.php?id=30937&r=fixedcvs
Fixed in release: http://bugs.php.net/fix.php?id=30937&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=30937&r=needtrace
Need Reproduce Script: http://bugs.php.net/fix.php?id=30937&r=needscript
Try newer version: http://bugs.php.net/fix.php?id=30937&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=30937&r=support
Expected behavior: http://bugs.php.net/fix.php?id=30937&r=notwrong
Not enough info:
http://bugs.php.net/fix.php?id=30937&r=notenoughinfo
Submitted twice:
http://bugs.php.net/fix.php?id=30937&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=30937&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=30937&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=30937&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=30937&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=30937&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=30937&r=float
MySQL Configuration Error: http://bugs.php.net/fix.php?id=30937&r=mysqlcfg