Date-Tolkien-Shire-Data

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

{
   "abstract" : "Data functionality for Shire calendars.",
   "author" : [
      "Thomas R. Wyant, III F<wyant at cpan dot org>"
   ],
   "dynamic_config" : 1,
   "generated_by" : "Module::Build version 0.4234",
   "license" : [
      "perl_5"
   ],
   "meta-spec" : {
      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",

META.yml  view on Meta::CPAN

---
abstract: 'Data functionality for Shire calendars.'
author:
  - 'Thomas R. Wyant, III F<wyant at cpan dot org>'
build_requires:
  Test::More: '0.88'
configure_requires:
  Module::Metadata: '0'
  lib: '0'
  strict: '0'
  warnings: '0'
dynamic_config: 1

eg/display  view on Meta::CPAN

    my $rslt = Date::Tolkien::Shire::Data::__format( \%hash, $tplt );
    print "__format( \%hash, '$tplt' ) = '$rslt'\n";
    return;
}


__END__

=head1 TITLE

display - Display results of Shire calendar routines

=head1 SYNOPSIS

 display date_to_day_of_year 1419 3 25
 display weekday_name 2
 display -help
 display -version

=head1 OPTIONS

eg/on-date  view on Meta::CPAN


This option displays the documentation for this script. The script then
exits.

=head2 -version

This option displays the version of this script. The script then exits.

=head1 DETAILS

This Perl script displays the given date in the Shire calendar, and what
(if anything) happened in and around the War of the Ring on that date.
The date is specified as two command line arguments. Normal dates are
specified by month and day numbers. Holidays are specified by holiday
number.

=head1 AUTHOR

Thomas R. Wyant, III F<wyant at cpan dot org>

=head1 COPYRIGHT AND LICENSE

eg/scal  view on Meta::CPAN

# Highlight the given $text if -color is asserted and the $day_of_year
# is equal to global variable $today.
sub highlight {
    my ( $text, $day_of_year ) = @_;
    $opt{color}
	and $day_of_year == $today
	or return $text;
    return colored( $text, $opt{color_today} );
}

# Make the calendar for one month. The arguments are Shire Year and
# Shire month number (1-12). The return is an array of lines.
sub month {
    my ( $year, $month ) = @_;
    my @rslt;

    {	# Title
	my $name = join ' ', __month_name( $month ), $year;
	my $space = ' ' x int( ( $month_width - length $name ) / 2 );
	push @rslt, sprintf "%-${month_width}s", "$space$name";
    }

eg/scal  view on Meta::CPAN

    my ( $month, $day ) = __day_of_year_to_date( $year, $yd );
    defined( my $evt = $on_date->( $month, $day ) )
	or return;
    $evt =~ s/ \s+ \z //smx;
    $evt = highlight(
	sprintf( '%s: %s', $day_text->( $year, $yd ), $evt ), $yd );
    $evt =~ s/ (?<= \n ) /    /smxg;
    return ( '', $evt );
}

# Make the calendar for one quarter. The arguments are Shire Year and
# quarter number (1-4). The return is an array of lines.
sub period {
    my ( $year, $inx, $number ) = @_;

    $number ||= 3;
    my @rslt;
    my $start = ( $inx - 1 ) * $number;
    foreach my $month ( $start + 1 .. $start + $number ) {
	my $inx = 0;
	foreach my $line ( month( $year, $month ) ) {
	    push @{ $rslt[$inx++] ||= [] }, $line;
	}
    }
    return ( map { join '  ', @{ $_ } } @rslt );
}

__END__

=head1 TITLE

scal - Displays a Shire calendar

=head1 SYNOPSIS

 scal
 scal 7482
 scal 6 7482
 scal -y
 scal -y 7482
 scal -help
 scal -version

eg/scal  view on Meta::CPAN

=head2 -y

If this Boolean option is asserted, a whole year is displayed, including
Midyear's Day, and the Overlithe if any. If it is not asserted, only a
month is displayed.

The default is C<-noy>.

=head1 DETAILS

This Perl script displays the Shire calendar for the Shire Reckoning
month and year specified on the command line. The default is to display
the current month and year.

For the purpose of selecting dates to display, the holidays are
lumped in with months as follows.

 2 Yule -------- Afteryule (month 1)
 1 Lithe ------- Forelithe (month 6)
 Midyear's day - Forelithe (month 6)
 Overlithe ----- Forelithe (month 6)

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

    my ( $class ) = @_;
    ref $class and $class = ref $class;
    my $self = {
	distribution => $ENV{MAKING_MODULE_DISTRIBUTION},
    };
    bless $self, $class;
    return $self;
}

sub abstract {
    return 'Data functionality for Shire calendars.';
}

sub add_to_cleanup {
    return [ qw{ cover_db xt/author/optionals } ];
}

sub author {
    return 'Thomas R. Wyant, III F<wyant at cpan dot org>';
}

lib/Date/Tolkien/Shire/Data.pm  view on Meta::CPAN

	En	=> sub { $_[1]{prefix_new_line_unless_empty}++; '' },
	Eo	=> sub { __holiday_narrow( $_[0]->__fmt_shire_month() ? 0 :
		$_[0]->__fmt_shire_day() ) },
	Ex	=> sub { __format( $_[0],
		    '%{{%A %-e %B %Y||%A %EE %Y||%EE %Y}}' ) },
	e	=> sub {
		    return _fmt_number__2( @_[ 0, 1 ],
			$_[0]->__fmt_shire_day() );
		},
	F	=> sub { __format( $_[0], '%Y-%{{%m-%d||%Ee}}' ) },
#	G	Same as Y by definition of Shire calendar
	H	=> sub {
		    return _fmt_number_02( @_[ 0, 1 ],
			$_[0]->__fmt_shire_hour() );
		},
#	h	Same as b by definition of strftime()
	I	=> sub {
		    return _fmt_number_02( @_[ 0, 1 ],
			( $_[0]->__fmt_shire_hour() || 0 ) % 12 || 12,
		    );
		},

lib/Date/Tolkien/Shire/Data.pm  view on Meta::CPAN

	t	=> sub { "\t" },
	U	=> sub {
		    return _fmt_number_02( @_[ 0, 1 ],
			__week_of_year(
			    $_[0]->__fmt_shire_month(),
			    $_[0]->__fmt_shire_day(),
			),
		    );
		},
	u	=> sub { $_[0]->__fmt_shire_day_of_week() },
#	V	Same as U by definition of Shire calendar
	v	=> sub { __format( $_[0], '%{{%e-%b-%Y||%Ee-%Y}}' ) },
#	W	Same as U by definition of Shire calendar
#	X	Same as r, I think
	x	=> sub { __format( $_[0], '%{{%e %b %Y||%Ee %Y}}' ) }, 
	Y	=> sub { $_[0]->__fmt_shire_year() },
	y	=> sub {
		    return _fmt_number_02( @_[ 0, 1 ],
			$_[0]->__fmt_shire_year() % 100 );
		},
	Z	=> sub { $_[0]->__fmt_shire_zone_name() },
	z	=> sub { _fmt_offset( $_[0]->__fmt_shire_zone_offset() ) },
	'%'	=> sub { '%' },
    );
    $spec{G} = $spec{Y};	# By definition of Shire calendar.
    $spec{h} = $spec{b};	# By definition of strftime().
    $spec{V} = $spec{U};	# By definition of Shire calendar.
    $spec{W} = $spec{U};	# By definition of Shire calendar.
    $spec{w} = $spec{u};	# Because the strftime() definition of
				# %w makes no sense to me in terms of
				# the Shire calendar.
    $spec{X} = $spec{r};	# I think this is right ...
    $spec{'{'} = $spec{'}'} = $spec{'|'} = $spec{'%'};

    my %modifier_map = (
	0	=> sub { $_[0]{pad} = '0' },
	'-'	=> sub { $_[0]{pad} = '' },
	_	=> sub { $_[0]{pad} = ' ' },
	'^'	=> sub { $_[0]{uc} = 1 },
	'#'	=> sub { $_[0]{change_case} = 1 },
    );

lib/Date/Tolkien/Shire/Data.pm  view on Meta::CPAN

	return $tbl;
    }
}

1;

__END__

=head1 NAME

Date::Tolkien::Shire::Data - Data functionality for Shire calendars.

=head1 SYNOPSIS

 use Date::Tolkien::Shire::Data;
 
 say __on_date( 1, 2 ) // "Nothing happened\n";

=head1 DESCRIPTION

This Perl module carries common functionality for implementations of the
Shire calendar as described in Appendix D of J. R. R. Tolkien's novel
"Lord Of The Rings". What it really contains is anything that was common
to L<Date::Tolkien::Shire|Date::Tolkien::Shire> and
L<DateTime::Fiction::JRRTolkien::Shire|DateTime::Fiction::JRRTolkien::Shire>
and I felt like factoring out. You probably do not want to use this
module directly, at least not without looking into the other two.

The Shire calendar has 12 months of 30 days each, plus 5 holidays (6 in
a leap year) that are not part of any month. Two of these holidays
(Midyear's day and the Overlithe) are also part of no week.

In all of the following, years are counted from the founding of the
Shire. Months are numbered C<1-12>, and days in months from C<1-30>.
Holidays are specified by giving a month of C<0> and the holiday number,
as follows:

=over

lib/Date/Tolkien/Shire/Data.pm  view on Meta::CPAN

C<' 1'> to C<' 6'>).

=item %F

For normal dates this is equivalent to C<'%Y-%m-%d'> (i.e. the ISO 8601
date format). For holidays it is equivalent to C<'%Y-%Er'>, which is
something ISO had nothing to do with.

=item %G

The ISO 8601 year number. Given how the Shire calendar is defined, the
ISO year number is the same as the calendar year (i.e. C<'%Y'>).

=item %H

The hour, zero-filled, in the range C<'00'> to C<'23'>.

=item %h

Equivalent to C<'%b'>.

=item %I

lib/Date/Tolkien/Shire/Data.pm  view on Meta::CPAN


=head2 __quarter

 say __quarter( $month, $day );

Given month and day numbers, returns the relevant quarter number. If the
date specified is Midyear's day or the Overlithe ("month" C<0>, days
C<3-4>), the result is C<0>; otherwise it is a number in the range
C<1-4>.

There is nothing I know of about hobbits using calendar quarters in
anything Tolkien wrote. But if they did use them I suspect they would be
rationalized this way.

=head2 __quarter_name

Given the quarter number, return the name of the quarter. If the quarter
number is C<0> (i.e. Midyear's day or Overlithe), C<''> is returned.

=head2 __quarter_abbr

lib/Date/Tolkien/Shire/Data.pm  view on Meta::CPAN


Given a Rata Die day, returns the year and day of the year corresponding
to that Rata Die day.

The algorithm used was inspired by Howard Hinnant's "C<chrono>-Compatible
Low-Level Date Algorithms" at
L<http://howardhinnant.github.io/date_algorithms.html>, and in
particular his C<civil_from_days()> algorithm at
L<http://howardhinnant.github.io/date_algorithms.html#civil_from_days>.

This subroutine assumes no particular calendar, though it does assume
the Gregorian year-length rules, which have also been adopted for the
Shire calendar. If you feed it an honest-to-God Rata Die day (i.e. days
since December 31 of proleptic Gregorian year 0) you get back the
Gregorian year and the day of that year (C<1-366>). If you feed it a
so-called Shire Rata Die (i.e. days since 1 Yule of Shire year 0) you
get back the Shire year and the day of that year.

=head2 __trad_weekday_name

 say 'Day 1 is ', __trad_weekday_name( 1 );

This subroutine computes the traditional (i.e. old-style) name of a

lib/Date/Tolkien/Shire/Data.pm  view on Meta::CPAN

returned.

=head2 __year_day_to_rata_die

 my $rata_die = __year_day_to_rata_die(
     $year, $day_of_year );

Given the year and day of the year, this subroutine returns the Rata Die
day of the given year and day. The day of the year defaults to C<1>.

This subroutine assumes no particular calendar, though it does assume
the Gregorian year-length rules, which have also been adopted for the
Shire calendar. If you feed it a Gregorian year, you get an
honest-to-God Rata Die, as in days since December 31 of proleptic
Gregorian year 0. If you feed it a Shire year, you get a so-called Shire
Rata Die, as in the days since 1 Yule of Shire year 0.

=head1 MANIFEST CONSTANTS

The following manifest constants are exportable to your name space. None
is exported by default. They can all be exported using export tag
C<:consts>.

t/year_day_to_rata_die.t  view on Meta::CPAN

    __year_day_to_rata_die
    __rata_die_to_year_day
    __is_leap_year
};
use POSIX ();
use Test::More 0.47;	# The best we can do with Perl 5.6.2.

use constant TOP_YEAR	=> 400;

# I find that on my system, a full round-trip test of every day in the
# 400-year calendar cycle takes ~37 wall clock seconds. My experience is
# that the last day of the year is the hard one to get right, and it
# takes a fraction of a second. So the ordinary test just does the last
# day, but for formal author testing we do them all.
#
# This would all be a lot simpler if I could go as far as Test::More
# 0.88 and use done_testing(), instead of computing how many tests I
# intend to run. But unfortunately I can not do that while targeting
# Perl 5.6.2, which I feel like I have to for the sake of
# Date::Tolkien::Shire.



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