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