monarch has asked for the wisdom of the Perl Monks concerning the following question:

I have some code:
use DateTime; use DateTime::Event::Sunrise; use strict; my $timezone = "Pacific/Auckland"; my ( $latitude, $longitude ) = ( -36.55, 174.45 ); my $dt_start = DateTime->new( year => 2006, month => 3, day => 1, hour => 4, time_zone => $timezone, ); my $dt_end = $dt_start->clone()->add(days=>31); for ( my $dt = $dt_start->clone(); $dt < $dt_end; $dt->add(days=>1) ) { my $sset = DateTime::Event::Sunrise->sunset( longitude => $longitude, latitude => $latitude, altitude => '-0.833', iteration => '1' ); my $dt_ss = $sset->next($dt); print( "Sunset on " . $dt->strftime("%d %B %Y") . " at " . $dt_ss->strftime("%H:%M") . "\n" ); }

This code prints out the sunset time for each day of March 2006 in Auckland, New Zealand.

When running this code it complains that the sun never sets on 22 March 2006, which is clearly not the case in Auckland.

Running the above code with the sunset object set to iteration => '0' works fine (although less accurately).

Any ideas why I'm getting this:

Sunset on 19 March 2006 at 18:38 Sunset on 20 March 2006 at 18:36 Sunset on 21 March 2006 at 18:33 Sun never sets!! at /usr/lib/perl5/vendor_perl/5.8.5/DateTime/Set.pm line 240 Sun never sets!! at /usr/lib/perl5/vendor_perl/5.8.5/DateTime/Set.pm line 240 Sun never rises!! at /usr/lib/perl5/vendor_perl/5.8.5/DateTime/Set.pm line 240 Sun never rises!!

Replies are listed 'Best First'.
Re: Sun Never Sets
by idsfa (Vicar) on Feb 20, 2006 at 02:50 UTC

    Spring starts then. Not only is the sun moving from a negative declination to a positive one, but the Right Ascension is moving from just under 24h back to 0h. All those zeroes can allow minor math errors to become hugely important.

    Without installing the modules myself, it looks like there may be a math error in the multiple (unnecessary) degree -> radian -> degree conversions leading to one too many factors of &pi/180 relating to the altitude term. If your problem goes away when you use the altitude of zero, that would confirm a problem in the _sunrise_sunset routine.

    Assuming it is true for other years, I encourage you to report this bug to the author even if the altitude suggestion is incorrect.


    The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. — Cyrus H. Gordon
Re: Sun Never Sets
by bart (Canon) on Feb 20, 2006 at 00:47 UTC
    Could it be mistaking due to a change in Daylight Saving Time?
      March 22 is a Wednesday, daylight savings time only kicks in on a Sunday.
Re: Sun Never Sets
by spiritway (Vicar) on Feb 19, 2006 at 23:58 UTC

    What's in DateTime/Set.pm? Looks like that would be a good place to start digging, seeing what values it's receiving, and what it's doing with them.

      It appears to be failing in DateTime::Event::Sunrise.pm because:
      if ( $cost >= 1.0 ) { carp "Sun never rises!!\n"; $t = 0.0; # Sun always below altit } elsif ( $cost <= -1.0 ) { carp "Sun never sets!!\n"; $t = 12.0; # Sun always above altit } else {

      I might have to submit this as a potential module bug if no one else has encountered this.

        This is a very old thread, but I found it by googling after I ran into the same bug. I believe that I have found the source of the bug, and a fix.

        In the routine _sunrise_sunset, these lines appear:

        my $sradius = 0.2666 / $sRA; if ($upper_limb) { $altit -= $sradius; }

        Apparently the intent here is to shift the calculation from being referenced to the Sun's midpoint, to its upper limb, by subtracting the angular radius from the desired altitude. However, for some reason the radius variable is divided by the Sun's RA. Near the equinox, this can be arbitrarily close to zero, and so the altitude can become an arbitrarily large negative number, causing the calculation to fail. The fix is to remove the division by $sRA, i.e. just to write

        my $sradius = 0.2666;

        instead. In my test case, that fixed the problem, even with iteration enabled.

Re: Sun Never Sets
by Eradicatore (Monk) on Dec 17, 2012 at 07:14 UTC
    I tried the suggestions given here, but nothing worked. So I found this alternative:
    use DateTime; use DateTime::Astro::Sunrise; $latitude = "+48.857"; $longitude = "+2.351"; $sr = DateTime::Astro::Sunrise->new($longitude, $latitude, 0, 3); $date = DateTime->now; $date->set_time_zone("local"); ($rise, $set) = $sr->sunrise($date); $rise->set_time_zone("local"); $set->set_time_zone("local"); print $rise, " to ", $set, "\n";
    and this works great for me.