Calendar-Any

 view release on metacpan or  search on metacpan

ChangeLog  view on Meta::CPAN


	* lib/Calendar/Julian.pm (check_date): add check_date to validate
	parameter in constructor.
	(absolute_date): Validate parameter before calculate absolute
	date.

	* lib/Calendar/China.pm: Fix document error in SYNOPSIS.
	(check_date): add check_date to validate parameter in constructor.

	* bin/cal.pl: Add default value for $week_start_day to fix error
	when compile. Initial upcase $type to allow lower case calendar
	type. Add document to advice set configuration.


2006-12-15 Ye Wenbin  <wenbinye@163.com>
	* original version created by h2xs 1.23 with options -A -n Calendar

META.yml  view on Meta::CPAN

---
abstract: 'Perl extension for calendar convertion'
author:
  - 'Ye Wenbin<wenbinye@gmail.com>'
build_requires: {}
configure_requires:
  ExtUtils::MakeMaker: 6.30
dynamic_config: 0
generated_by: 'Dist::Zilla version 4.300003, CPAN::Meta::Converter version 2.112150'
license: perl
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html

Makefile.PL  view on Meta::CPAN

use strict;
use warnings;



use ExtUtils::MakeMaker 6.30;



my %WriteMakefileArgs = (
  "ABSTRACT" => "Perl extension for calendar convertion",
  "AUTHOR" => "Ye Wenbin<wenbinye\@gmail.com>",
  "BUILD_REQUIRES" => {},
  "CONFIGURE_REQUIRES" => {
    "ExtUtils::MakeMaker" => "6.30"
  },
  "DISTNAME" => "Calendar-Any",
  "EXE_FILES" => [
    "bin/cal.pl"
  ],
  "LICENSE" => "perl",

README  view on Meta::CPAN



This archive contains the distribution Calendar-Any,
version 0.5:

  Perl extension for calendar convertion

This software is copyright (c) 2012 by Ye Wenbin.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.


README.md  view on Meta::CPAN

perl-Calendar-Any
=================

Perl extension for calendar convertion

bin/cal.pl  view on Meta::CPAN

} elsif ( $julian ) {
    $type = "Julian";
}
$type = ucfirst($type);

## ensure the package is implement
unless ( defined($type) && grep { $type eq $_ } qw(China Gregorian Julian) ) {
    pod2usage();
}

my $cal = Calendar::Any::Util::Calendar::calendar($month, $year, $type)."\n";
if ( $type =~ /China/ ) {
    # out put using locale
    require Encode;
    Encode::_utf8_on($cal);
    print Encode::encode($Config{locale}, $cal);
} else {
    print $cal;
}

__END__

=head1 NAME

cal.pl - Print calendar of multiple type

=head1 VERSION

version 0.5

=head1 SYNOPSIS

cal.pl [-l locale -w weekstart [-c|-g|-j|-t calendar_type] month year]

    Options:
       -l, --locale locale
           The locale of system. Only for Non english calendar.

       -w, --weekstart start
           The week start day for the output. Default is 0, means the
           first day of the week is Sunday

       -c, --china
           Output chinese calendar

       -g, --gregorian
           Output gregorian calendar

       -j, --julian
           Output Julian calendar

       -t, --type calendar_type
           Specific a type of calendar.
           Available type: china, gregorian, julian

       month, year
           The month and year of the calendar

=head1 Example

    * Output current month gregorian calendar

       cal.pl

    * Output chinese calendar of February in current year
     
       cal.pl -c 2

    * Output the julian calendar in 1752 September. You can see the
      difference from cal(1)

       cal.pl -j 9 1752

    * Output chinese calendar in gbk language environment

       cal.pl -c -l gbk

=head1 Configuration

Add your default command parameter to the %Config in this file.

=head1 AUTHOR

Ye Wenbin <wenbinye@gmail.com>

lib/Calendar/Any.pm  view on Meta::CPAN

        die "Unknown function $AUTOLOAD\n";
    }
}

1;

__END__

=head1 NAME

Calendar::Any - Perl extension for calendar convertion

=head1 VERSION

version 0.5

=head1 SYNOPSIS

   use Calendar::Any;
   my $date = Calendar::Any->new_from_Gregorian(12, 16, 2006);
   print $date->date_string("Gregorian date: %M %W %d %Y"), "\n";

lib/Calendar/Any.pm  view on Meta::CPAN

   
   my $diff = $date-$newdate;
   printf "There is %d days between %s and %s\n",
       $diff, $date->date_string("%D"), $newdate->date_string("%D");
   
   $date->to_Julian;
   print $date->date_string("Julian date: %M %W %d %Y"), "\n";

=head1 DESCRIPTION

Calendar::Any is a class for calendar convertion or calculation. The
algorithm is from emacs calendar library. Most functions of this class
is simply rewrite from elisp to perl. 

=head2 Constructor

=over 4

=item new

All class of Calendar should accept absolute date to construct the
object. Other type of argument may also be acceptable. For example:

lib/Calendar/Any.pm  view on Meta::CPAN

=back

=head2 Convertion

Calendar::Any object can convert from each other. The function is name
`to_{Module}'. For example:

    $date = Calendar::Any->new_from_Gregorian(12, 17, 2006);
    $date->to_Julian;

Now $date is a Julian calendar date. If you want maintain $date not
change, use Calendar::Any->new_from_Julian($date->absolute_date) instead.

=head2 Operator

Calendar overload several operator. 

=over 4

=item +

lib/Calendar/Any.pm  view on Meta::CPAN


=item ""

That means you can simply print the date without explicitly call a
method. For detail, read "Format date" section.

=back

=head2 Format date

Every calendar class has a format template: $default_format. You can
set the template. For example:

   Calendar::Any::Gregorian::$default_format = "%F";
   print Calendar::Any::Gregorian::today();  # 2012-05-18

The format function is `date_string'. The format
specifications as following:

   %%       PERCENT
   %A       Absoute date
   %d       numeric day of the month, with leading zeros (eg 01..31)
   %F       YYYY-MM-DD
   %D       MM/DD/YYYY
   %m       month number, with leading zeros (eg 01..31)
   %M       month name
   %W       day of the week
   %Y       year

For chinese calendar, the following specifications are available:

   %S       sexagesimal name, eg. "丙戌"
   %D       day name, eg. "初二"
   %Z       zodiac name, eg. "ç‹—"
   %M       month name in chinese, eg. "十一月"
   %W       week day name in chinese, eg. "星期一"

Meanwhile, %Y, %m and %d now stand for Gregorian year, month and day.

=head2 Other method

lib/Calendar/Any.pm  view on Meta::CPAN

=over 4

=item  absoute_date

The number of days elapsed between the Gregorian date 12/31/1 BC.
The Gregorian date Sunday, December 31, 1 BC is imaginary.

=item  astro_date

Astronomers use a simple counting of days elapsed since noon, Monday,
January 1, 4713 B.C. on the Julian calendar.  The number of days elapsed
is called the "Julian day number" or the "Astronomical day number".

=item  new_from_Astro

There is no package Calendar::Any::Astro. use new_from_Astro and astro_date
to convert between other type of calendar and astro calendar.

=item  today

Get the current date of local time. 

=item  weekday

The weekday number. 0 for sunday and 1 for monday.

=item  weekday_name

lib/Calendar/Any/Chinese.pm  view on Meta::CPAN

    if ( $self->month < 1 || $self->month > 12 ) {
        confess(sprintf('Not a valid month %d: should from 1 to 12 for %s', $self->month, ref $self));
    }
    if ( $self->day < 1 || $self->day > $self->last_day_of_month() ) {
        confess(sprintf('Not a valid day %d: should from 1 to %d in %d, %d for %s',
                        $self->day, $self->last_day_of_month, $self->month, $self->year, ref $self));
    }
}

#==========================================================
# Format calendar
#==========================================================
our @celestial_stem = qw(甲 乙 丙 丁 戊 已 庚 辛 壬 癸);
our @terrestrial_branch = qw(子 丑 寅 卯 辰 巳 午 未 申 酉 戌 亥);
our @weekday_name = qw(日 一 二 三 四 五 六);
our @month_name =
    qw(正月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 腊月);
our @day_name = qw
  (初一 初二 初三 初四 初五 初六 初七 初八 初九 初十
   十一 十二 十三 十四 十五 十六 十七 十八 十九 二十
   廿一 廿二 廿三 廿四 廿五 廿六 廿七 廿八 廿九 三十

lib/Calendar/Any/Chinese.pm  view on Meta::CPAN

    pop @list if $list[-1]>$end;
    return \@list;
}

1;

__END__

=head1 NAME

Calendar::Any::Chinese - Perl extension for Chinese calendar

=head1 VERSION

version 0.5

=head1 SYNOPSIS

   use Calendar::Any::Chinese;
   my $date = Calendar::Any::Chinese->new(78, 22, 12, 2);

   # or construct from Gregorian:
   my $date = Calendar::Any::Gregorian->new(1, 1, 2006)->to_Chinese();

=head1 DESCRIPTION

From "FREQUENTLY ASKED QUESTIONS ABOUT CALENDARS"(C<http://www.tondering.dk/claus/calendar.html>)

=over

The Chinese calendar - like the Hebrew - is a combined solar/lunar
calendar in that it strives to have its years coincide with the
tropical year and its months coincide with the synodic months. It is
not surprising that a few similarities exist between the Chinese and
the Hebrew calendar:

   * An ordinary year has 12 months, a leap year has 13 months.
   * An ordinary year has 353, 354, or 355 days, a leap year has 383,
     384, or 385 days.

When determining what a Chinese year looks like, one must make a
number of astronomical calculations:

First, determine the dates for the new moons. Here, a new moon is the
completely "black" moon (that is, when the moon is in conjunction with
the sun), not the first visible crescent used in the Islamic and
Hebrew calendars. The date of a new moon is the first day of a new
month.

Secondly, determine the dates when the sun's longitude is a multiple
of 30 degrees. (The sun's longitude is 0 at Vernal Equinox, 90 at
Summer Solstice, 180 at Autumnal Equinox, and 270 at Winter Solstice.)
These dates are called the "Principal Terms" and are used to determine
the number of each month:

Principal Term 1 occurs when the sun's longitude is 330 degrees.
Principal Term 2 occurs when the sun's longitude is 0 degrees.

lib/Calendar/Any/Chinese.pm  view on Meta::CPAN

=item  cycle

The number of the Chinese sexagesimal cycle

=item  is_leap_year

True if the chinese year of the date has leap month.

=item  gyear

The number of year in Gregorian calendar

=item  gmonth

The number of month in Gregorian calendar

=item  gday

The number of day in Gregorian calendar

=item  gdate

The Gregorian calendar date. 

=item  last_day_of_month

The last day of the chinese month.

=item  year_month_list

The month list of the chinese year. For example:

    use Calendar;

lib/Calendar/Any/Gregorian.pm  view on Meta::CPAN


version 0.5

=head1 SYNOPSIS

   use Calendar::Any::Gregorian;
   my $date = Calendar::Any::Gregorian->new(1, 1, 2006);

=head1 DESCRIPTION

From "FREQUENTLY ASKED QUESTIONS ABOUT CALENDARS"(C<http://www.tondering.dk/claus/calendar.html>)

=over

The Gregorian calendar is the one commonly used today. It was proposed
by Aloysius Lilius, a physician from Naples, and adopted by Pope
Gregory XIII in accordance with instructions from the Council of Trent
(1545-1563) to correct for errors in the older Julian Calendar. It was
decreed by Pope Gregory XIII in a papal bull on 24 February 1582. This
bull is named "Inter Gravissimas" after its first two words.

In the Gregorian calendar, the tropical year is approximated as
365 97/400 days = 365.2425 days. Thus it takes approximately 3300
years for the tropical year to shift one day with respect to the
Gregorian calendar.

The approximation 365 97/400 is achieved by having 97 leap years
every 400 years.

=back

=head1 METHOD

This class is inherited from L<Calendar::Any::Julian>. The method is the
same as Calendar::Any::Julian.

lib/Calendar/Any/Julian.pm  view on Meta::CPAN


version 0.5

=head1 SYNOPSIS

   use Calendar::Any::Julian;
   my $date = Calendar::Any::Julian->new(1, 1, 2006);

=head1 DESCRIPTION

From "FREQUENTLY ASKED QUESTIONS ABOUT CALENDARS"(C<http://www.tondering.dk/claus/calendar.html>)

=over

The Julian calendar was introduced by Julius Caesar in 45 BC. It was
in common use until the late 1500s, when countries started changing to
the Gregorian calendar (section 2.2). However, some countries (for
example, Greece and Russia) used it into the early 1900s, and the
Orthodox church in Russia still uses it, as do some other Orthodox
churches.

In the Julian calendar, the tropical year is approximated as 365 1/4
days = 365.25 days. This gives an error of 1 day in approximately 128
years.

The approximation 365 1/4 is achieved by having 1 leap year every 4
years.

=back

=head1 METHOD

lib/Calendar/Any/Util/Calendar.pm  view on Meta::CPAN

package Calendar::Any::Util::Calendar;
{
  $Calendar::Any::Util::Calendar::VERSION = '0.5';
}
use Calendar::Any;

require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
calendar $week_start_day
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our $week_start_day = 0;

sub calendar {
    my ($month, $year, $package) = @_;
    if ( defined($package) && $package =~ /China|Chinese/) {
        chinese_simple($month, $year);
    } else {
        generic_simple(@_);
    }
}

sub generic_simple {
    my ($month, $year) = @_;
    my @month = generic_calendar(@_);
    my $cal = "$Calendar::Any::month_name[$month-1] $year\n\n";
    $cal .= join(" ", map {
        substr($Calendar::Any::weekday_name[$_], 0, 2)
    } $week_start_day..6, 0..($week_start_day-1) ). "\n";
    $cal .= join("\n", map {
        join(" ", map { $_ ? sprintf "%2d", $_ : '  ' } @$_);
    } @month);
    return $cal;
}

sub generic_calendar {
    my ($month, $year, $package) = @_;
    defined($package) || ($package = "Gregorian");
    my $module = "Calendar::Any::$package";
    eval("require $module");
    if ( $@ ) {
        die "Can't load module $module: $@!\n"
    }
    my $start = $module->new(-month => $month, -day => 1, -year => $year);
    my $weekday = ($start->weekday-$week_start_day) % 7;
    my $last = $start->last_day_of_month;
    my @month = ((undef)x$weekday, 1..$last, (undef)x ( 7 - (($weekday+$last)%7  || 7) ));
    return map { [@month[$_*7..$_*7+6]] } 0..(@month/7-1);
}

sub chinese_simple {
    my ($month, $year) = @_;
    my ($months, $newmonth) = chinese_calendar(@_);
    # print it
    my $cal = center_han_string(
        sprintf("%d年%d月  %s年%s", $year, $month,
                      $newmonth->[-1][1]->sexagesimal_name,
                      join(",", map { sprintf "%s%s%d日始", $_->[1]->month_name(),
                                           ($_->[1]->last_day_of_month > 29 ? "大" : "小"),
                                               $_->[0] } @$newmonth)),
        9*7-3) . "\n";
    $cal .= join("   ", map {
        substr($Calendar::Any::weekday_name[$_], 0, 3) . " " . $Calendar::Any::Chinese::weekday_name[$_]

lib/Calendar/Any/Util/Calendar.pm  view on Meta::CPAN

            } else {
                $str = ' ' x 8;
            }
            $cal .= $str . " ";
        }
        $cal .= "\n";
    }
    return $cal;
}

sub chinese_calendar {
    require Encode;
    require Calendar::Any::Chinese;
    my ($month, $year) = @_;
    unless ( $month=~ /^\d+$/ && $year =~ /^\d+$/ && $month>0 && $month<13 ) {
        pod2usage();
    }
    my $tz = Calendar::Any::Chinese::timezone($year);
    my $start = Calendar::Any->new_from_Gregorian($month, 1, $year); # first date of Gregorian
    my $weekday = ($start->weekday - $week_start_day) % 7; # weekday of first date
    my $last = $start->last_day_of_month; # last day of this month

lib/Calendar/Any/Util/Calendar.pm  view on Meta::CPAN

    my $pad = ($len-length($enc))/2;
    return ' ' x $pad . $str . ' ' x $pad;
}

1;

__END__

=head1 NAME

Calendar::Any::Util::Calendar - A collection of function for create calendars

=head1 VERSION

version 0.5

=head1 SYNOPSIS

     use Calendar::Any::Util::Calendar qw(calendar);
     print calendar(12, 2006), "\n";

=head1 DESCRIPTION

A very simple module that output various calendars.

=over

=item calendar(month, year, [package])

Output the calendar for the month in the year. If given package,
output the calendar of the package. For example: 

     print calendar(12, 2006, 'Julian'), "\n";

This will output calendar in Julian calendar.

=item  generic_calendar(month, year, [package])

Return an array of dates in the month break by weekday:

    ( [ undef, undef, undef, undef, undef, 1, 2 ],
      [ 3, 4, 5, 6, 7, 8, 9 ],
      [ 10, 11, 12, 13, 14, 15, 16 ],
      [ 17, 18, 19, 20, 21, 22, 23 ],
      [ 24, 25, 26, 27, 28, 29, 30 ],
      [ 31, undef, undef, undef, undef, undef, undef ] )

The default week start day is Sunday. If you want start from Monday,
set $week_start_day to 1.

=item chinese_calendar($month, $year)

The difference between the generic_calendar is the return array,
contain not only the day of the month, but also the Calendar::China
date. And to address the start date of the new chinese month, the
return value of the function contain two elements, one is the month
calendar array, which like:

    [ [ undef, undef, undef, undef, undef, [1, D], [2, D] ],
        ...
      [ [31, D], undef, undef, undef, undef, undef, undef ] ]

The D stands for Calendar::China date. The second element is an array
of new chinese month date. A month may contain two new chinese month
date. 

=back



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