Astro-App-Satpass2

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

0.035		2018-01-26	T. R. Wyant
    TODO test because of changed equinox algorithm.

    Remove mailto: bug reporting metadata.  Not that I refuse these, it
    is just that it appears to cause RT to think I will not accept bug
    reports from them.

    Support for decayed Iridium satellites.

0.034		2017-04-01	T. R. Wyant
  Update FormatTime/DateTime.pm calendar_name code to take advantage of
    the calendar_name() method if present.

  Add 'provides' data to ExtUtils::MakeMaker output

0.033		2017-01-12	T. R. Wyant
  Protect tests from local zone problems

  Use 'use parent' instead of 'use base'.

0.032		2016-12-11	T. R. Wyant
  Use time_local() and time_gm() from Astro::Coord::ECI::Utils. This

Changes  view on Meta::CPAN

    and document its arguments.

  The formatter object now displays its time_formatter attribute as a
    short name where possible.

  Add time_formatter value to 'show' output.

  Allow specifying a time as a scalar reference, The dereferenced value
    is interpreted as epoch.

  Special-case DateTime strftime() format %{calendar_name} to display
    the name of the calendar in use.

  Heuristics to make ODF geocoding more useful. I hope.

  Retract support for Geo::Coder::Geocoder::US. The underlying web site
    has been AWOL since late 2015.

0.031		2016-02-24	T. R. Wyant
  Consolidate development changes into next production release.

  Correct and clean up recommended-module code.

Changes  view on Meta::CPAN

0.016		2014-01-20	T. R. Wyant
  Make the rounding of time for display configurable. The default is to
    round to the nearest second.

  Support body-specific pass events. This is really in support of a
    project to predict sounding rocket visibility based on published KMZ
    files for the launch.

  Add options to the quarters() method to select which are displayed.

  Add eg/quarters_vcalendar.

  In Astro::App::Satpass2::FormatValue:

  * Add formatter method list() to handle TLE output. Handle individual
      lines of the list with sub-templates.

  * Build time formats when used. This to allow subclasses to add time
      formatters.

  "Code macro" support tweaks. This is all still experimental:

Changes  view on Meta::CPAN


0.012		2012-12-26	T. R. Wyant
  Fix tests to work under versions of Perl that do not allow multiple
    labels for the same block.

0.011		2012-12-24	T. R. Wyant
  Adjust tests for the fact that geocoder.us is (temporarily, I hope!)
    not honoring the requests generated by Geo::Coder::Geocoder::US.

  Add an extra notification to the events generated by
    eg/{pass,flare}_vcalendar, at a minute before the nominal event.

  Another crack at properly testing if two files are in fact the same.

  Tweak eg/pass_vcalendar to work with Mac OS 10.8 calendar.

  Add attribute 'permissive' (and associated accessor/mutator
    permissive()) to Astro::App::Satpass2::Format::Template. This
    defaults to false, If set true, Template-Toolkit is configured to
    accept absolute path names for templates.

  Correct Astro::App::Satpass2::FormatTime::DateTime documentation.

  Try to fix test failure under DragonFly BSD 3.1.0. I believe the
    failure is cosmetic, but ...

MANIFEST  view on Meta::CPAN

Build.PL
Changes
CONTRIBUTING
eg/almanac
eg/es.pm
eg/flare_vcalendar
eg/My/Macros.pm
eg/pass_ics
eg/quarters_vcalendar
eg/README
eg/tle_celestia.tt2
eg/tle_json.tt2
eg/tle_stellarium.tt2
inc/My/Module/Build.pm
inc/My/Module/Meta.pm
inc/My/Module/Recommend.pm
inc/My/Module/Recommend/All.pm
inc/My/Module/Recommend/Any.pm
inc/My/Module/Test/App.pm

eg/README  view on Meta::CPAN

	set for the given day (defaulting to today), and the quarters of
	the moon, solstices and equinoxes for the next 30 days after the
	given day.

es.pm - A very, very rough Spanish localization. This is intended as a
	user-specific localization, though it could be installed as a
	system-wide localization by uncommenting the 'package'
	statement. The main thing wrong with it is that it has not been
	edited by someone who actually is fluent in Spanish.

flare_vcalendar - A source file, to be executed by, for example,
	satpass2> source eg/flare_vcalendar
	This makes Iridium flare calculations for any satellites that
	have been loaded, and displays the results in vCalendar format.

	CAVEAT: My ancient Palm desktop software appears not to properly
	handle the switch between normal and daylight-saving  time
	(a.k.a. summer time), in that predictions made before the switch
	for events after the switch get assigned the wrong time, even
	though the UT event time is correct in the emitted file. I have
	not changed the event times to local times in eg/flare_vcalendar
	because the vcalendar standard specifies UT.

My/Macros.pm - A module that implements the following code macros
	* angle - Given the names or OIDs of two objects (either
		satellites or background bodies like the Moon or Sun)
		computes the angle between them at the time specified by
		the third argument, which defaults to the current time.
		Options specify radians or degrees, and the number of
		decimal places.
	* hi - A 'hello world' macro. It takes one argument, which
		defaults to 'world'.
	* test - A macro that issues a command (or not) based on whether
		or not specified conditions are met.
	* dumper - A diagnostic macro, which displays the class of its
		first argument, and all other arguments as a YAML dump.

	To use this, it must be placed in directory My/ somewhere in
	@INC, remembering that the lib/ directory in your configuration
	directory is added to @INC before your module is loaded.

pass_ics - A source file, to be executed by, for example,
	satpass2> source eg/pass_vcalendar
	This makes pass calculations for any satellites that have been
	loaded, and displays the results in iCal format.

	CAVEAT: Under macOS (at least), this needs to be redirected to a
	file named something.ics for the escaped characters to be
	properly interpreted.

quarters_vcalendar - A source file, to be executed by, for example,
        satpass2> source eg/quarters_vcalendar
	This makes quarters calculations, and displays the results in
	vCalendar format.

	CAVEAT: The same as for flare_vcalendar.

tle_celestia.tt - A Template-Toolkit file to display TLE data in the
	format needed for the Celestia planetarium software. You would
	use this by loading the orbital elements you want, and then
	issuing the command
	    satpass2> formatter format eg/tle_celestia.tt
	All options to the tle command work here (e.g. -choose).

	CAVEAT: The file generated by this template is in the correct
	format, but is known (or at least strongly suspected) NOT to put

eg/flare_vcalendar  view on Meta::CPAN

# Astro::App::Satpass2 source file. Invoke as (e.g.)
# satpass2> source eg/flare_vcalendar
#
# Do iridium flare calculations, displaying the results in vCalendar
# format. The output may be redirected to a .vcal file. Any arguments
# passed to the source statement will in turn be passed to the flare
# command.
#
# This whole thing (less the comments) could be wrapped up as a macro
# if desired.

#	CAVEAT: My ancient Palm desktop software appears not to properly
#	handle the switch between normal and daylight-saving  time
#	(a.k.a. summer time), in that predictions made before the switch
#	for events after the switch get assigned the wrong time, even
#	though the UT event time is correct in the emitted file. I have
#	not changed the event times to local time eg/flare_vcalendar
#	because the vcalendar standard specifies UT.

localize formatter

# We intend to use date(units='z') to format the event begin and end. We
# truncate the time to the previous minute.

formatter date_format %Y%m%dT%H%M00Z

# We intend to use time() to format the individual event times.

eg/pass_ics  view on Meta::CPAN

# Astro::App::Satpass2 source file. Invoke as (e.g.)
# satpass2> source eg/pass_vcalendar
#
# Do satellite pass calculations, displaying the results in vCalendar
# format. The output may be redirected to a .vcal file. The start and
# end dates for the pass calculation can be passed as arguments to the
# 'source' statement, and default to 'today noon' and '+8' respectively.
# This whole thing (less the comments) could be wrapped up as a macro
# if desired.

#	CAVEAT: My ancient Palm desktop software appears not to properly
#	handle the switch between normal and daylight-saving  time
#	(a.k.a. summer time), in that predictions made before the switch
#	for events after the switch get assigned the wrong time, even
#	though the UT event time is correct in the emitted file. I have
#	not changed the event times to local time eg/flare_vcalendar
#	because the vcalendar standard specifies UT.

localize formatter

# An iCal file is supposed to have <cr><lf> line breaks

# set output_layers :encoding(utf-8):crlf

# The individual pass events get concatenated to the description, with
# no newline between.

eg/pass_ics  view on Meta::CPAN

EOD

# Do the pass calculation. I do not know that the vcal format requires
# the data to be chronological, but ...

# TODO: The iCal spec (RFC 5545 section 3.1) says that content lines
# SHOULD NOT be longer than 75 octets (NOT characters) excluding the
# line break, and longer lines SHOULD be broken.

# NOTE that at least under macOS (as they spell it these days) this must
# be saved as a .ics file to be successfully imported into the calendar
# application.

# pass -chronological "${1:-today noon}" "${2:-+8}"
pass -chronological -default "'today noon' +8" "$@"

eg/quarters_vcalendar  view on Meta::CPAN

# Astro::App::Satpass2 source file. Invoke as (e.g.)
# satpass2> source eg/quarters_vcalendar
#
# Do quarter calculations, displaying the results in vCalendar format.
# The output may be redirected to a .vcal file. The start and end dates
# for the calculation can be passed as arguments to the 'source'
# statement, and default to 'today noon' and '+30' respectively.  This
# whole thing (less the comments) could be wrapped up as a macro if
# desired.

localize formatter

inc/My/Module/Recommend.pm  view on Meta::CPAN

    # - lib/Astro/App/Satpass2/Utils.pm
    # - inc/My/Module/Recommend.pm
    # - inc/My/Module/Test/App.pm
    # These all need to stay the same. Sigh.
    # Any such should be in xt/author/consistent_module_versions.t

    __any( 'DateTime::Calendar::Christian=0.06'	=> <<'EOD' ),
      This module is used to parse (maybe) and format dates that might
      be either Julian or Gregorian. Currently the only parser that has
      this capability is ISO8601. If historical dates in the proleptic
      Gregorian calendar are fine with you, you do not need this module.
EOD
    __any( 'Geo::Coder::OSM'		=> <<'EOD' ),
      This module is required for the Astro::App::Satpass2 geocode()
      method, which computes latitude and longitude based on street
      address. If you do not intend to determine your observing
      locations this way, this module is not needed.
EOD
    __any( 'Geo::WebService::Elevation::USGS'	=> <<'EOD' ),
      This module is required for the Astro::App::Satpass2 height()
      method, which determines height above the reference ellipsoid for

lib/Astro/App/Satpass2/FormatTime/DateTime.pm  view on Meta::CPAN

	< _expand_strftime_format( $dt_obj, $1, $2, $3, $4 ) >smxge;
    return $fmt;
}

use constant CALENDAR_GREGORIAN	=> 'Gregorian';
use constant CALENDAR_JULIAN	=> 'Julian';

{
    my %special = (
	'%'		=> sub { return '%' },
	calendar_name	=> sub {
	    my ( $dt_obj ) = @_;
	    my $code;
	    $code = $dt_obj->can( 'calendar_name' )
		and return $code->( $dt_obj );
	    $code = $dt_obj->can( 'is_julian' )
		and return $code->( $dt_obj ) ?
		    CALENDAR_JULIAN :
		    CALENDAR_GREGORIAN;
	    ( ref $dt_obj ) =~ m/ \A DateTime:: (?: \w+ :: )* ( \w+ ) \z /smx
		and return "$1";
	    return CALENDAR_GREGORIAN;
	},
    );

lib/Astro/App/Satpass2/FormatTime/DateTime.pm  view on Meta::CPAN

represents either a special-case string or the name of a method on the
C<$dt_obj> object. If it is neither, the substring is left unmodified.
The special-case names are:

=over

=item %

This causes a literal C<'%'> to be inserted.

=item calendar_name

This causes either C<'Gregorian'> or C<'Julian'> to be inserted. You get
C<'Julian'> only if C<$dt_obj> has an C<is_julian()> method, and that
method returns a true value. Otherwise, if the class name of the back
end object begins with C<'DateTime::Calendar::'> you get the shortened
name. Otherwise you get C<'Gregorian'>. There is no provision for
localization, unfortunately.

=back

lib/Astro/App/Satpass2/FormatTime/DateTime/Cldr.pm  view on Meta::CPAN


All this class really provides is the interface to
C<< DateTime->format_cldr() >>. Everything else is inherited.

As an enhancement (I hope!) to the L<DateTime|DateTime> C<cldr>
functionality, this module, before calling C<format_cldr()>, finds all
embedded literals and calls
L<Astro::App::Satpass2::FormatTime::DateTime|Astro::App::Satpass2::FormatTime::DateTime>
L<__preprocess_strftime_format()|Astro::App::Satpass2::FormatTime::DateTime/__preprocess_strftime_format>
to expand them. This provides special-case things like
C<'%{calendar_name}'> and the results of L<DateTime|DateTime> method
calls, plus some control over formatting.

Use of this formatter with Julian dates enabled (i.e. with
L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> doing the
heavy lifting) is B<unsupported>, because 
L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> lacks
some of the methods you might want it to have, including
C<format_cldr()> itself. This package checks for the following methods
when it loads
L<DateTime::Calendar::Christian|DateTime::Calendar::Christian>, and

lib/Astro/App/Satpass2/FormatTime/DateTime/Strftime.pm  view on Meta::CPAN

This subclass of
L<Astro::App::Satpass2::FormatTime::DateTime|Astro::App::Satpass2::FormatTime::DateTime>
formats times using C<DateTime->strftime()>. Time zones other than the
default local zone are handled using
L<DateTime::TimeZone|DateTime::TimeZone> objects.

All this class really provides is the interface to
C<< DateTime->strftime() >>. Everything else is inherited.

The L<DateTime|DateTime> C<strftime()> template extensions have been
further extended to add C<'%{calendar_name}'> and some control over
formatting. See the documentation to
L<Astro::App::Satpass2::FormatTime::DateTime|Astro::App::Satpass2::FormatTime::DateTime>
L<__preprocess_strftime_format()|Astro::App::Satpass2::FormatTime::DateTime/__preprocess_strftime_format>
for the details.

=head1 METHODS

This class provides no public methods over and above those provided by
L<Astro::App::Satpass2::FormatTime::DateTime|Astro::App::Satpass2::FormatTime::DateTime>
and

lib/Astro/App/Satpass2/TUTORIAL.pod  view on Meta::CPAN

 satpass2>
 satpass2> # Display the time as 1-12 AM or PM
 satpass2> formatter time_format '%I:%M:%S %p'
 satpass2>
 satpass2> # Save the configuration, overwriting any previous one
 satpass2> save -changes -overwrite

=head2 The Julian Calendar

No, there were no satellites in orbit when the last known holdout
(Romania) adopted the Gregorian calendar. But the Sun and Moon have been
rising and setting much longer than satellites have.

If you install
L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> and
properly configure C<satpass2>, you will be able to both parse and
display dates in both the Gregorian and Julian calendars.

=head3 Parsing Julian Calendar Dates

The primary date parser is L<Date::Manip|Date::Manip>, which does not
support Julian dates. But if you use the C<ISO8601> parser, you can
configure it to parse a date as either Julian or Gregorian, depending on
the date itself.

What you have to do, in general, is use date parser
L<Astro::App::Satpass2::ParseTime::ISO8601>, and set its

lib/Astro/App/Satpass2/TUTORIAL.pod  view on Meta::CPAN

it are

 satpass2> # Configure the time formatter and reform date
 satpass2> formatter time_formatter \
 > DateTime::Strftime,back_end=Christian

A non-default reform date is specified the same way as for the parser,
and the two reform dates need not be the same.

The C<DateTime> C<strftime> formatter also supports, as a special case,
format pattern C<'%{calendar_name}'>, which renders as either
C<'Julian'> or C<'Gregorian'> as appropriate. Given

 satpass2> formatter time_format \
 > '%{year_with_era}-%m-%d %{calendar_name}'

The date of the assassination of Julius Caesar would be displayed as

 '44BC-03-15 Julian'

In point of fact, the way the C<%{calendar_name}> machinery works is
that if the back end provides the C<is_julian()> method, you get
C<'Julian'> if that method returns a true value, and C<'Gregorian'> if
it does not. If the back end does not provide the C<is_julian()> method,
whatever follows C<'DateTime::Calendar::'> in the back end's class name
is used. If the back end does not begin with C<'DateTime::Calendar::'>,
C<'Gregorian'> is used.

Formatting Julian calendar dates in
L<Astro::App::Satpass2::FormatTime::DateTime::Cldr|Astro::App::Satpass2::FormatTime::DateTime::Cldr>
is unsupported, because
L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> lacks the
C<format_cldr()> method. You may find that it works, because this module
patches in C<format_cldr()> when it loads
L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> if it
finds that that method does not already exist. But you may find that it
does not work, because the patch messes with the internals of
L<DateTime::Calendar::Christian|DateTime::Calendar::Christian>, and
those might change without warning. I<Caveat coder.>

t/format_template.t  view on Meta::CPAN

	defined $err
		or $err = 'Cannot determine local time zone';
	chomp $err;
	skip "$err under $^O", 1;
    };


    $ft->template( fubar => q<[% data.date( width = '' ) %]> );
    $ft->time_formatter(
	q<DateTime::Strftime,back_end=DateTime::Calendar::Christian> );
    $ft->date_format( '%{year_with_christian_era}-%m-%d %{calendar_name}' );

    my $dt = DateTime::Calendar::Christian->new(
	year		=> -43,
	month		=> 3,
	day		=> 15,
	time_zone	=> 'UTC',
    );

    is $ft->format(
	template	=> 'fubar',

t/format_time_datetime_cldr.t  view on Meta::CPAN


call_m( round_time => 60, TRUE, 'Round to nearest minute' );

call_m( format_datetime => DATE_TIME_FORMAT, $time, 1,
    '2011/04/01 00:01:00', 'Explicit GMT time, rounded to minute' );

SKIP: {
    check_datetime_timezone_local() 
	or skip 'Cannot determine local time zone', 1;

    call_m( format_datetime => q<'%{calendar_name}'>, 1,
	'Gregorian', 'Calendar name' );
}

SKIP: {
    my $tests = 2;

    my $back_end = 'DateTime::Calendar::Christian';

    load_or_skip( $back_end, $tests );

t/format_time_datetime_cldr.t  view on Meta::CPAN

	    year	=> -43,
	    month	=> 3,
	    day		=> 15,
	    time_zone	=> 'UTC',
	);

	$dt->is_julian()
	    or skip 'DateTime::Calendar::Christian thinks date is not Julian', $tests;

	call_m( format_datetime =>
	    q<'%{year_with_christian_era:06}'-MM-dd '%{calendar_name:t3}'>,
	    $dt->epoch(), '0044BC-03-15 Jul',
	    'Method and Julian calendar name' );
    }

}

done_testing;

1;

# ex: set textwidth=72 :

t/format_time_datetime_strftime.t  view on Meta::CPAN

call_m( gmt => 0, TRUE, 'Turn off gmt' );

call_m( format_datetime => DATE_TIME_FORMAT, $time, 1,
    '2011/04/01 00:00:50', 'Explicit GMT time' );

call_m( round_time => 60, TRUE, 'Round to nearest minute' );

call_m( format_datetime => DATE_TIME_FORMAT, $time, 1,
    '2011/04/01 00:01:00', 'Explicit GMT time, rounded to minute' );

call_m( format_datetime => '%{year_with_christian_era} %{calendar_name}',
    $time, 1, '2011AD Gregorian', 'Explicit GMT year, with calendar' );

SKIP: {
    my $tests = 8;

    my $back_end = 'DateTime::Calendar::Christian';

    load_or_skip( $back_end, $tests );

    call_m( 'new', back_end => $back_end, gmt => 1, INSTANTIATE, 'Instantiate' );

t/format_time_datetime_strftime.t  view on Meta::CPAN

	month	=> 3,
	day	=> 15,
	time_zone	=> 'UTC',
    );

    SKIP: {
	$dt->is_julian()
	    or skip "$back_end 44BC not Julian(?!)", 1;

	call_m( format_datetime =>
	    '%{year_with_christian_era:06}-%m-%d %{calendar_name:t3}',
	    $dt->epoch(), '0044BC-03-15 Jul', 'Julian date, with era' );
    }

    $dt = $back_end->new(
	year	=> 1700,
	month	=> 1,
	day	=> 1,
	time_zone	=> 'UTC',
    );

    call_m( 'new', back_end => $back_end,
	gmt => 1, INSTANTIATE, 'Instantiate' );

    call_m( back_end => $back_end, 'Get back end' );

    SKIP: {
	$dt->is_gregorian()
	    or skip 'DateTime::Calendar::Christian 1700 not Gregorian', 1;
	call_m( format_datetime =>
	    '%Y-%m-%d %{calendar_name}',
	    $dt->epoch(), '1700-01-01 Gregorian', 'Gregorian date' );
    }

    $dt = $back_end->new(
	year	=> 1700,
	month	=> 1,
	day	=> 1,
	time_zone	=> 'UTC',
	reform_date	=> 'uk',
    );

    call_m( 'new', back_end => "$back_end,reform_date=uk",
	gmt => 1, INSTANTIATE, 'Instantiate' );

    call_m( back_end => "$back_end,reform_date=uk", 'Get back end' );

    SKIP: {
	$dt->is_julian()
	    or skip 'DateTime::Calendar::Christian 1700 not Julian under UK reform', 1;
	call_m( format_datetime =>
	    '%Y-%m-%d %{calendar_name}',
	    $dt->epoch(), '1700-01-01 Julian', 'UK reform Julian date' );
    }
}

done_testing;

1;

# ex: set textwidth=72 :

t/parse_time_iso8601.t  view on Meta::CPAN

SKIP: {
    my $tests = 5;

    load_or_skip( 'DateTime', $tests );

    note <<'EOD';

We only do the following if DateTime can be loaded, because Time::Local
does strange things with long-past dates.

Yes, we're using the Gregorian calendar for dates that really should be
Julian, but for the moment we're stuck with that.

EOD

    my $dt = DateTime->new(	# Battle of Hastings
	year	=> 1066,
	month	=> 10,
	day	=> 14,
	time_zone	=> 'UTC',
    );



( run in 0.492 second using v1.01-cache-2.11-cpan-5dc5da66d9d )