Date-Lectionary
view release on metacpan or search on metacpan
lib/Date/Lectionary/Day.pm view on Meta::CPAN
package Date::Lectionary::Day;
use v5.22;
use strict;
use warnings;
use Moose;
use MooseX::StrictConstructor;
use MooseX::Aliases;
use Carp;
use Try::Catch;
use Time::Piece;
use Time::Seconds;
use Date::Advent;
use Date::Easter;
use Date::Lectionary::Time qw(nextSunday prevSunday closestSunday);
use namespace::autoclean;
use Moose::Util::TypeConstraints;
use File::Share ':all';
use XML::LibXML;
=head1 NAME
Date::Lectionary::Day - Determines the Day in the Christian Liturgical Year
=head1 VERSION
Version 1.20200203
=cut
use version; our $VERSION = version->declare("v1.20200203");
=head1 SYNOPSIS
A helper object for Date::Lectionary to determine the liturgical name(s) and type for the given day according to a given lectionary.
=cut
enum 'DayType', [qw(fixedFeast moveableFeast Sunday noLect)];
enum 'LectionaryType', [qw(acna rcl)];
enum 'MultiLect', [qw(yes no)];
enum 'IncludeFeasts', [qw(yes no)];
enum 'XianSeason', [qw(Advent Christmas Epiphany Ordinary Lent Easter Pentecost NaN)];
no Moose::Util::TypeConstraints;
=head1 SUBROUTINES/METHODS/ATTRIBUTES
=head2 ATTRIBUTES
=head3 date
The Time::Piece object date given at object construction.
=head3 lectionary
An optional attribute given at object creation time. Valid values are 'acna' for the Anglican Church of North America lectionary and 'rcl' for the Revised Common Lectionary. This attribute defaults to 'acna' if no value is given.
=head3 type
Stores the type of liturgical day. 'fixedFeast' is returned for non-moveable feast days such as Christmas Day. 'moveableFeast' is returned for moveable feast days. Moveable feasts move to a Monday when they occure on a Sunday. 'Sunday' is returned f...
=head3 name
The name of the day in the lectionary. For noLect days a String representation of the day is returned as the name.
=head3 alt
The alternative name --- if one is given --- of the day in the lectionary. If there is no alternative name for the day, then the empty string will be returned.
=head3 multiLect
Returns 'yes' if the day has multiple services with readings associated with it. (E.g. Christmas Day, Easter, etc.) Returns 'no' if the day is a normal lectioanry day with only one service and one set of readings.
=head3 subLects
An ArrayRef of the names of the multiple services that occur on a multiLect day.
=head3 includeFeasts
If this is set to 'yes' --- the default value --- the module will include fixed and moveable feasts in its determination of which liturgical Sunday it is.
If set to 'no', it will exclude fixed and moveable feasts. Excluding feasts is useful when using Date::Lectionary::Day in combination with a daily lectionary such as Date::Lectioary::Daily where a fixed feast such as The Transfiguration can conflict...
=head3 season
The liturgical season the day falls within.
Valid values are 'Advent', 'Christmas', 'Epiphany', 'Ordinary', 'Lent', 'Easter', or 'Pentecost'.
If a date is given that is not a Sunday nor a pricipal holy day 'NaN' will be given for the season.
=cut
has 'date' => (
is => 'ro',
isa => 'Time::Piece',
required => 1,
);
has 'type' => (
is => 'ro',
isa => 'DayType',
writer => '_setType',
init_arg => undef,
);
has 'lectionary' => (
is => 'ro',
isa => 'LectionaryType',
default => 'acna',
);
has 'displayName' => (
is => 'ro',
isa => 'Str',
writer => '_setDisplayName',
init_arg => undef,
alias => 'name',
);
has 'altName' => (
is => 'ro',
isa => 'Str',
writer => '_setAltName',
init_arg => undef,
alias => 'alt',
);
has 'commonName' => (
is => 'ro',
isa => 'Str',
writer => '_setCommonName',
init_arg => undef,
);
has 'multiLect' => (
is => 'ro',
isa => 'MultiLect',
writer => '_setMultiLect',
init_arg => undef,
);
has 'subLects' => (
is => 'ro',
isa => 'ArrayRef',
writer => '_setSubLects',
init_arg => undef,
);
has 'includeFeasts' => (
lib/Date/Lectionary/Day.pm view on Meta::CPAN
Private method that takes a Time::Piece date object to returns a Date::Advent object containing the dates for Advent of the current liturgical year.
=cut
sub _determineAdvent {
my $date = shift;
my $advent = undef;
try {
$advent = Date::Advent->new( date => $date );
return $advent;
}
catch {
confess "Could not calculate Advent for the given date [" . $date->ymd . "].";
};
}
=head2 _determineEaster
Private method that takes a four-digit representation of a Common Era year and calculates the date for Easter as a Time::Piece object.
=cut
sub _determineEaster {
my $easterYear = shift;
my $easter = undef;
try {
my ( $easterMonth, $easterDay ) = easter($easterYear);
$easter = Time::Piece->strptime( $easterYear . "-" . $easterMonth . "-" . $easterDay, "%Y-%m-%d" );
return $easter;
}
catch {
confess "Could not calculate Easter for the year [" . $easterYear . "]";
};
}
=head2 _determineFeasts
Private method that takes the Time::Piece date given at construction and determines if the date is one of many feasts in the liturgical calendar. Feasts are taken from the Anglican Church in North America's revision of the revised common lectionary.
=cut
sub _determineFeasts {
my $date = shift;
my $lectionary = shift;
my $yesterday = $date - ONE_DAY;
my $yesterdayName;
if ( $yesterday->wday == 1 ) {
$yesterdayName = _buildMoveableDays( $yesterday, $lectionary );
}
if ($yesterdayName) {
return (
commonName => $yesterdayName,
type => 'moveableFeast',
season => 'NaN'
);
}
my $fixedDayName = _buildFixedDays( $date, $lectionary );
if ($fixedDayName) {
return (
commonName => $fixedDayName->{commonName},
type => 'fixedFeast',
season => $fixedDayName->{season}
);
}
my $moveableDayName = _buildMoveableDays( $date, $lectionary );
if ( $moveableDayName && $date->wday != 1 ) {
return (
commonName => $moveableDayName,
type => 'moveableFeast',
season => 'NaN'
);
}
return ( commonName => undef, type => undef, season => 'NaN' );
}
=head2 _buildMoveableDays
Private method that takes the Time::Piece date given at construction and determines if the date is one of many moveable feasts in the liturgical calendar. Feasts are taken from the Anglican Church in North America's revision of the revised common le...
=cut
sub _buildMoveableDays {
my $date = shift;
my $lectionary = shift;
#Moveable holidays in January
if ( $date->mon == 1 ) {
if ( $date->mday == 18 && $lectionary eq 'acna' ) {
return "Confession of St. Peter";
}
if ( $date->mday == 25 && $lectionary eq 'acna' ) {
return "Conversion of St. Paul";
}
}
#Moveable holidays in February
elsif ( $date->mon == 2 ) {
if ( $date->mday == 2 ) {
return "The Presentation of Christ in the Temple";
}
if ( $date->mday == 24 && $lectionary eq 'acna' ) {
return "St. Matthias";
}
}
#Moveable holidays in March
elsif ( $date->mon == 3 ) {
if ( $date->mday == 19 && $lectionary eq 'acna' ) {
return "St. Joseph";
}
if ( $date->mday == 25 ) {
return "The Annunciation";
}
}
#Moveable holidays in April
elsif ( $date->mon == 4 ) {
if ( $date->mday == 25 && $lectionary eq 'acna' ) {
return "St. Mark";
}
}
#Moveable holidays in May
elsif ( $date->mon == 5 ) {
if ( $date->mday == 1 && $lectionary eq 'acna' ) {
return "St. Philip & St. James";
}
if ( $date->mday == 31 ) {
return "The Visitation";
}
}
#Moveable holidays in June
lib/Date/Lectionary/Day.pm view on Meta::CPAN
}
#Holy Week
my $holyWeekDay = _determineHolyWeek( $date, $easter );
if ($holyWeekDay) {
return (
commonName => $holyWeekDay,
type => 'fixedFeast',
season => 'Lent'
);
}
#Easter Week
my $easterWeekDay = _determineEasterWeek( $date, $easter );
if ($easterWeekDay) {
return (
commonName => $easterWeekDay,
type => 'fixedFeast',
season => 'Easter'
);
}
#Ascension is 40 days after Easter
my $ascension = _determineAscension($easter);
if ( $date == $ascension ) {
return (
commonName => "Ascension Day",
type => 'fixedFeast',
season => 'Easter'
);
}
#Pentecost is 50 days after Easter
my $pentecost = _determinePentecost($easter);
if ( $date == $pentecost ) {
return (
commonName => "Pentecost",
type => 'fixedFeast',
season => 'Pentecost'
);
}
#Feast Day Celebrations
if ( $includeFeasts eq 'yes' ) {
my %feastDay = _determineFeasts( $date, $lectionary );
if ( $feastDay{commonName} ) {
return (
commonName => $feastDay{commonName},
type => $feastDay{type},
season => $feastDay{season}
);
}
}
#If the date isn't a Sunday and we've determined it is not a fixed holiday
#then there are no readings for that day.
if ( $date->wday != 1 ) {
return (
commonName => $date->fullday . ', ' . $date->fullmonth . ' ' . $date->mday . ', ' . $date->year,
type => 'noLect',
season => 'NaN'
);
}
#Sundays of the Liturgical Year
if ( $date < $ashWednesday ) {
my %xmasEpiphany = (
commonName => _determineChristmasEpiphany( $date, $advent, $ashWednesday, $lectionary ),
type => 'Sunday'
);
if ( $xmasEpiphany{commonName} =~ m/Christmas/ig ) {
$xmasEpiphany{season} = 'Christmas';
return %xmasEpiphany;
}
else {
$xmasEpiphany{season} = 'Epiphany';
return %xmasEpiphany;
}
}
if ( $date < $easter ) {
return (
commonName => _determineLent( $date, $ashWednesday ),
type => 'Sunday',
season => 'Lent'
);
}
if ( $date > $easter && $date < $pentecost ) {
return (
commonName => _determineEasterSeason( $date, $easter ),
type => 'Sunday',
season => 'Easter'
);
}
if ( $date > $pentecost ) {
return (
commonName => _determineOrdinary( $date, $pentecost ),
type => 'Sunday',
season => 'Ordinary'
);
}
}
=head1 AUTHOR
Michael Wayne Arnold, C<< <michael at rnold.info> >>
=head1 BUGS
Please report any bugs or feature requests to C<bug-date-lectionary at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Date-Lectionary-Day>. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Date::Lectionary::Day
( run in 0.541 second using v1.01-cache-2.11-cpan-437f7b0c052 )