Astro-MoonPhase-Simple

 view release on metacpan or  search on metacpan

lib/Astro/MoonPhase/Simple.pm  view on Meta::CPAN

package Astro::MoonPhase::Simple;

use 5.006;
use strict;
use warnings;

use DateTime;
use DateTime::Format::ISO8601;
use DateTime::TimeZone;
use Data::Roundtrip qw/perl2dump no-unicode-escape-permanently/;
####
# Note that we require conditionally Geo::Location::TimeZone, see below
####

# the real heavy lifter!!! thank you :
use Astro::MoonPhase;

our $VERSION = '0.03';

use Exporter 'import';
our (@EXPORT, @EXPORT_OK);

BEGIN {
	@EXPORT_OK = ('calculate_moon_phase');
	# nothing exported by default:
	@EXPORT = ('calculate_moon_phase');
} # end BEGIN

# The input is a HASHref consisting of
#   date : the date of when you want to calculate the moon phase, YYYY-MM-DD
#   time : optional time in hh:mm:ss
#   timezone : optional timezone as a TZ identifier e.g. Africa/Abidjan
#   location : optionally deduce timezone from location if above timezone is absent,
#              it is a nameplace string, e.g. 'Abidjan'
#        OR    it is a HASHref with keys 'lat' and 'lon'
#   verbosity: optionally specify a positive integer to increase verbosity, default is zero for no verbose messages (only errors and warnings)
# Returns:
#   a hash with results including 'asString' which contains a string description of the results.
#   or undef on failure
sub	calculate_moon_phase {
	my $params = $_[0];
	my $parent = ( caller(1) )[3] || "N/A";
	my $whoami = ( caller(0) )[3];

	if( ! defined($params) || ref($params) ne 'HASH' ){
		print STDERR "$whoami (via $parent) : parameters in the form of a HASHref are required.";
		return undef
	}
	my $verbosity = exists($params->{'verbosity'}) && defined($params->{'verbosity'}) ? $params->{'verbosity'} : 0;

	if( exists($params->{'date'}) && defined($params->{'date'}) ){
		if( $params->{'date'} !~ /^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$/ ){
			print STDERR "$whoami (via $parent) : parameter 'date' does not parse YYYY-MM-DD : ".$params->{'date'}."\n";
			return undef
		}
		print STDOUT "$whoami (via $parent) : found parameter 'date' : '".$params->{'date'}."'.\n" if $verbosity > 1;
	} else {
		print STDERR "$whoami (via $parent) : parameter 'date' was not specified.\n";
		return undef
	}
	if( exists($params->{'time'}) && defined($params->{'time'}) ){
		if( $params->{'time'} !~ /^(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)$/ ){
			print STDERR "$whoami (via $parent) : parameter 'time' does not parse hh:mm:ss : ".$params->{'time'}."\n";
			return undef
		}
		print STDOUT "$whoami (via $parent) : found parameter 'time' : '".$params->{'time'}."'.\n" if $verbosity > 1;
	}
	if( exists($params->{'location'}) && defined($params->{'location'}) ){
		if( (ref($params->{'location'})eq'' && ($params->{'location'}=~/^[- a-zA-Z]+$/)) ){
			print STDOUT "$whoami (via $parent) : found parameter 'location' (as a nameplace) : '".$params->{'location'}."'\n" if $verbosity > 1;
		} elsif( (ref($params->{'location'})eq'HASH' && exists($params->{'location'}->{'lon'}) && exists($params->{'location'}->{'lat'})) ){
			print STDOUT "$whoami (via $parent) : found parameter 'location' (as coordinates) : '".perl2dump($params->{'location'})."'\n" if $verbosity > 1;
		} else {
			print STDERR "$whoami (via $parent) : parameter 'location' is not a string of a location name (e.g. London) or it is not a HASHref which contains the two keys 'lon' and 'lat' : ".perl2dump(\$params->{'location'})."\n";
			return undef
		}
	}
	if( exists($params->{'localtimezone'}) && defined($params->{'localtimezone'}) ){
		print STDOUT "$whoami (via $parent) : found parameter 'localtimezone' : '".$params->{'localtimezone'}."'.\n" if $verbosity > 1;
	}

	my $parsed_results = _parse_event($params);
	if( ! defined $parsed_results ){ print STDERR perl2dump($params)."$whoami (via $parent) : error, call to ".'_parse_event()'." has failed for above parameters.\n"; return undef }
	my $epoch = $parsed_results->{'localepoch'};

	print STDOUT _event2str($params)."\n$whoami (via $parent) : deduced epoch as '$epoch' for above parameters, now calling Astro::MoonPhase::phase() ...\n"
	 if $verbosity > 0;

	my (	$MoonPhase,
		$MoonIllum,
		$MoonAge,
		$MoonDist,
		$MoonAng,
		$SunDist,
		$SunAng
	) = Astro::MoonPhase::phase($epoch);

	# the phases are unix epoch for each of the below moon phase names
	# we are printing the date via DateTime on that epoch and adjusting for the timezone
	# the user asked or UTC/or-local-see-below if none was specified.
	# localtime() uses locale timezone or envvar TZ
	# the DateTime as came from $parsed_results{'datetime'} knows the used timezone
	# so we will use that same timezone.



( run in 2.069 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )