DateTime-Calendar-Chinese

 view release on metacpan or  search on metacpan

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

    $self->{cycle}      = POSIX::floor( ($elapsed_years - 1) / 60) + 1;
    $self->{cycle_year} = $elapsed_years % 60 || 60;
    $self->{day}        = POSIX::ceil(moment($dt) - $m_moment + 1);

    if ($leap_year && no_major_term_on($m)) {
        my $end = new_moon_before($m - DateTime::Duration->new(days => 1));
        $self->{leap_month} = ! $self->_prior_leap_month($m12, $end);
    } else {
        $self->{leap_month} = 0;
    }

    if (DEBUG) {
        print STDERR 
            ">>>>>>\n",
            "        dt: ", $dt->datetime, "\n",
            "        s1: ", $s1->datetime, "\n",
            "        s2: ", $s2->datetime, "\n",
            "       m12: ", $m12->datetime, "\n",
            "     n_m11: ", $next_m11->datetime, "\n",
            "     11-12: ", round( (moment($next_m11) - $m12_moment) / MEAN_SYNODIC_MONTH), "\n",
            "         m: ", $m->datetime, "\n",
            " leap year: ", $leap_year ? "yes" : "no", "\n",
            "leap month: ", $self->{leap_month} ? "yes" : "no", "\n",
            "     m-m12: ", round(abs($m_moment - $m12_moment) / MEAN_SYNODIC_MONTH), "\n",
            "      sl_m: ", solar_longitude_from_moment($m_moment), "\n",
            "    sl_m12: ", solar_longitude_from_moment($m12_moment), "\n",

#            "pleap: ", $self->_prior_leap_month($m12, $m) ? "yes" : "no", "\n",
            "     month: ", $month, "\n",
            "   elapsed: ", $elapsed_years, "\n",
            "     cycle: ", $self->{cycle}, "\n",
            "cycle_year: ", $self->{cycle_year}, "\n",
            "<<<<<<\n";
    }

}

sub elapsed_years
{
    my $self = shift;
    if (DEBUG) {
        print  STDERR
            ">>>> elapsed_years\n",
            "moment: ", moment($self->{gregorian}), "\n",
            "epoch:  ", GREGORIAN_CHINESE_EPOCH_MOMENT, "\n",
            "month:  ", $self->month, "\n",
            "<<<<\n"
    }
    return POSIX::floor(
        1.5 - $self->month / 12 + (moment($self->{gregorian}) - GREGORIAN_CHINESE_EPOCH_MOMENT) / MEAN_TROPICAL_YEAR);
}

# [1] p.250
sub _prior_leap_month
{
    my($class, $start, $end) = @_;

    if (DEBUG) {
        print STDERR 
            ">>>> prior_leap_month\n",
            "caller: ", join(':', (caller)[1, 2]), "\n", 
            "start: ", $start, "\n",
            "end:   ", $end, "\n",
            "<<<<\n";
    }

    while ($start <= $end) {
        if (no_major_term_on($end)) {
            if (DEBUG) {
                print STDERR " + prior_leap_month: there are no major terms on $end\n";
            }
            return 1;
        }

        $end = new_moon_before($end - DateTime::Duration->new(minutes => 30));
    }
    if (DEBUG) {
        print " + prior_leap_month: nothing found, returning false\n";
    }

    return ();
}

1;
__END__

=head1 NAME

DateTime::Calendar::Chinese - Traditional Chinese Calendar Implementation

=head1 SYNOPSIS

  use DateTime::Calendar::Chinese;

  my $dt = DateTime::Calendar::Chinese->now();
  my $dt = DateTime::Calendar::Chinese->new(
    cycle      => $cycle,
    cycle_year => $cycle_year,
    month      => $month,
    leap_month => $leap_month,
    day        => $day,
  );

  $dt->cycle;
  $dt->cycle_year; # 1 - 60
  $dt->month;      # 1-12
  $dt->leap_month; # true/false
  $dt->day;        # 1-30 
  $dt->elapsed_years; # years since "Chinese Epoch"

  my ($rd_days, $rd_secs, $rd_nanosecs) = $dt->utc_rd_values();

=head1 DESCRIPTION

This is an implementation of the Chinese calendar as described in 
"Calendrical Calculations" [1]. Please note that the following description
is the description from [1], and the author has not made attempts to verify
the correctness of statements with other sources.

The Chinese calendar described in [1] is expressed in terms of "cycle",
"cycle_year", "month", "a boolean leap_month", and "day".



( run in 1.957 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )