1#!/usr/local/bin/perl 2 3# Display Sun and Moon rise and set for a pre-programmed position. The 4# -help option gets you help. 5 6use 5.006002; 7 8use strict; 9use warnings; 10 11use Astro::Coord::ECI; 12use Astro::Coord::ECI::Sun; 13use Astro::Coord::ECI::Moon; 14use Astro::Coord::ECI::Utils qw{deg2rad}; 15use Getopt::Long 2.33; 16use Pod::Usage; 17use POSIX qw{strftime}; 18use Time::Local; 19 20our $VERSION = '0.122'; 21 22Getopt::Long::Configure( 'pass_through' ); # Numbers may be negative. 23 24my %opt = ( 25 format => '%d-%b-%Y %H:%M:%S', 26); 27 28GetOptions( \%opt, 29 qw{ date=s format=s moon! sun! tomorrow! }, 30 help => sub { pod2usage( { -verbose => 2 } ) }, 31) or pod2usage( { -verbose => 0 } ); 32 33my @args = @ARGV; 34@args 35 or not defined $ENV{ALMANAC_POSITION} 36 or @args = split '\s+', $ENV{ALMANAC_POSITION}; 37@args 38 or @args = ( 38.898748, -77.037684, 16.68 ); 39 40$opt{sun} 41 or $opt{moon} 42 or $opt{sun} = $opt{moon} = 1; 43 44# Stash position where it's convenient. 45 46my ( $lat, $lon, $hgt ) = @args; 47 48# Start time is the previous midnight. Unless -tomorrow is 49# set, in which case it's the next midnight. 50 51my $start; 52if ( defined $opt{date} ) { 53 require Date::Manip; 54 $start = Date::Manip::UnixDate( $opt{date}, '%s' ) 55 or die "Invalid date $opt{date}\n"; 56} else { 57 $start = timelocal (0, 0, 0, (localtime)[3 .. 5]); 58 $start += 86400 if $opt{tomorrow}; 59} 60 61# The end time is the start time + 1 day. 62 63my $end = $start + 86400; 64 65# Create an object representing our location. Remember that 66# angles are in radians, and distance in kilometers. 67 68my $loc = Astro::Coord::ECI->geodetic( 69 deg2rad( $lat ), deg2rad( $lon ), $hgt/1000 ); 70 71# Generate the almanac data for the Sun and Moon if each is 72# desired. We instantiate the luminary, call almanac() on it, and 73# then throw it away. 74 75my @almanac; 76foreach my $luminary ( qw{ sun moon } ) { 77 $opt{$luminary} 78 or next; 79 my $class = 'Astro::Coord::ECI::' . ucfirst $luminary; 80 push @almanac, $class->new( station => $loc )->almanac( 81 $start, $end ); 82} 83 84# Display the time and the text description of the events, in 85# order of increasing time. 86 87foreach (sort {$a->[0] <=> $b->[0]} @almanac) { 88 print strftime ($opt{format}, localtime $_->[0]), ' ', 89 ucfirst ($_->[3]), "\n"; 90} 91 92__END__ 93 94=head1 TITLE 95 96almanac - Generate almanac data for a given location 97 98=head1 SYNOPSIS 99 100 almanac # The White House by default 101 almanac 52.07 4.29 4 # The Hague 102 almanac -help 103 almanac -version 104 105=head1 OPTIONS 106 107=head2 -date=date_string 108 109This option specifies the date as a string that can be parsed by 110L<Date::Manip|Date::Manip>. If L<Date::Manip|Date::Manip> can not be 111loaded an error occurs. If this option is specified, C<-tomorrow> is 112ignored. 113 114=head2 -format=strftime_format 115 116This option specifies the C<strftime> format used to display dates and 117times. The default is C<'%d-%b-%Y %H:%M:%S'>. 118 119=head2 -help 120 121This option displays the documentation for this script. The script then 122exits. 123 124=head2 -moon 125 126Display data for the Moon. Defaults to C<-nomoon> if C<-sun> is 127asserted. 128 129=head2 -sun 130 131Display data for the Sun. Defaults to C<-nosun> if C<-moon> is asserted. 132 133=head2 -tomorrow 134 135Display data for tomorrow, rather than today. 136 137=head2 -version 138 139This option displays the version of this script. The script then exits. 140 141=head1 DETAILS 142 143This Perl script displays today's almanac for the position given on the 144command line, in latitude north of the Equator, longitude east of the 145prime meridian, and meters above sea level. If no position is given on 146the command line, the contents of environment variable 147C<ALMANAC_POSITION> are broken on spaces and used as the posiiton. If 148this environment variable is not found, the position of the White House 149in Washington DC USA is used. 150 151By default, data for both the Sun and Moon are displayed. If you 152explicitly assert either C<-sun> or C<-moon>, only the selected luminary 153will be displayed. 154 155You can look a day ahead by specifying C<-tomorrow>. 156 157The format of the time output can be specified using the C<-format> 158option. 159 160=head1 AUTHOR 161 162Thomas R. Wyant, III F<wyant at cpan dot org> 163 164=head1 COPYRIGHT AND LICENSE 165 166Copyright (C) 2012-2021 by Thomas R. Wyant, III 167 168This program is free software; you can redistribute it and/or modify it 169under the same terms as Perl 5.10.0. For more details, see the full text 170of the licenses in the directory LICENSES. 171 172This program is distributed in the hope that it will be useful, but 173without any warranty; without even the implied warranty of 174merchantability or fitness for a particular purpose. 175 176=cut 177 178# ex: set textwidth=72 : 179