DateTime-Indic

 view release on metacpan or  search on metacpan

lib/DateTime/Indic/Chandramana.pm  view on Meta::CPAN

L<The Lunar Month (mAsa)> for the month corresponding to each number.

=item * adhikamasa

1 if this is an adhikamAsa (leap month), 0 otherwise.  Defaults to 0.

=item * paksha

1 if this is the kR^iShNapakSha (waning half)  of a mAsa, 0 if it is the
shuklapakSha (waxing half.)  Defaults to 0.

=item * tithi

The numeric tithi (lunar day) expressed as a number from 1 to 14 or by 
convention, 15 for the pUrNimA (full moon) and 30 for the amAvAsya (new moon.) 
Defaults to 1.

=item * adhikatithi

1 if this is an adhika (leap) tithi, 0 otherwise.  Defaults to 0.

=item * latitude

The latitude of the point for which the date is to be calculated 
expressed as decimal degrees.  Negative values are used for latitudes south of 
the equator so the allowable range for this argument is from -180 to 180.  
Defaults to 23.15, the latitude of avantika.

=item * longitude

The longitude of the point for which the panchanga is to be calculated 
expressed as decimal degrees.  Negative values are used for longitudes west of 
Greenwich so the allowable range for this argument is from -180 to 180.  
Defaults to 75.76, the longitude of avantika.

=item * time_zone

Time zone for which the panchanga is to be calculated.  It can either be a
timezone name accepted by L<DateTime::TimeZone> or a L<DateTime::TimeZone> 
object.  Defaults to 'Asia/Kolkata' (Indian Standard Time.)

=back

=cut

## no critic 'ProhibitConstantPragma'

sub new {
    my ( $class, @arguments ) = @_;

    my %args = validate(
        @arguments,
        {
            varsha => {
                type    => SCALAR,
                default => 0,
            },
            masa => {
                type      => SCALAR,
                default   => 1,
                callbacks => {
                    'between 1 and 12' => sub { ( $_[0] > 0 && $_[0] < 13 ) },
                },
            },
            adhikamasa => {
                type    => BOOLEAN,
                default => 0,
                callbacks =>
                  { '0 or 1' => sub { ( $_[0] == 0 || $_[0] == 1 ) }, },
            },
            paksha => {
                type    => BOOLEAN,
                default => 0,
                callbacks =>
                  { '0 or 1' => sub { ( $_[0] == 0 || $_[0] == 1 ) }, },
            },
            tithi => {
                type      => SCALAR,
                default   => 1,
                callbacks => {
                    'between 1 and 14, or 15 or 30' => sub {
                        ( $_[0] > 0 && $_[0] < 15 )
                          || $_[0] == 15
                          || $_[0] == 30;
                    },
                },
            },
            adhikatithi => {
                type    => BOOLEAN,
                default => 0,
                callbacks =>
                  { '0 or 1' => sub { ( $_[0] == 0 || $_[0] == 1 ) }, },
            },
            latitude => {
                type      => SCALAR,
                default   => '23.15',
                callbacks => {
                    'between -180 and 180' =>
                      sub { ( $_[0] >= -180 && $_[0] < 180 ) },
                },
            },
            longitude => {
                type      => SCALAR,
                default   => '75.76',
                callbacks => {
                    'between -180 and 180' =>
                      sub { ( $_[0] >= -180 && $_[0] < 180 ) },
                },
            },
            time_zone => {
                type    => SCALAR | OBJECT,
                default => 'Asia/Kolkata',    # Indian Standard Time
            },
        }
    );

    my $self = bless \%args, $class;

    $self->{lunar_day} =
      ( $self->{paksha} == 1 && $self->{tithi} < 30 )
      ? $self->{tithi} + 15
      : $self->{tithi};

    $self->{sun} = DateTime::Event::Sunrise->new(
        latitude  => $self->{latitude},
        longitude => $self->{longitude},
        altitude  => 0,
    );

    ( $self->{rd_days}, $self->{rd_secs}, $self->{rd_nanosecs} ) =
      $self->_fixed_from_lunar;

    $self->{vara} = amod( $self->{rd_days} - epoch - 1, 7 );

    return $self;
}

sub _fixed_from_lunar {
    my ($self) = @_;

    my $approx =
      epoch +
      sidereal_year * ( $self->{varsha} + $self->_era + $self->{masa} / 12.0 );

    if ( $self->{masa} < $self->_masa_offset ) {
        $approx += sidereal_year;
    }

    my $s = floor(
        $approx - ( 1.0 / 360.0 ) * sidereal_year * (
            mod(
                solar_longitude(
                    dt_from_moment($approx)->set_time_zone( $self->{time_zone} )
                      ->jd
                  ) - $self->{masa} * 30 + 180,
                360
              ) - 180
        )
    );

    my $k =
      tithi_at_dt( dt_from_moment( $s + ( 1.0 / 4.0 ) )
          ->set_time_zone( $self->{time_zone} ) );

    my $x;

lib/DateTime/Indic/Chandramana.pm  view on Meta::CPAN

        $result->{varsha}--;
    }

    return $result;
}

=head3 clone

Returns a copy of the object.

=cut

sub clone {
    my ($self) = @_;
    return bless { %{$self} }, ref $self;
}

=head3 from_object

Builds a C<DateTime::Calendar::Chandramana> object from another I<DateTime> 
object.  This function takes the following parameters:

=over 4

=item * object

a DateTime API compatible object.  (Basically this means it supports 
L<utc_rd_Values>.)  This parameter is required.

=item * latitude

The latitude of the point for which the date is to be calculated 
expressed as decimal degrees.  Negative values are used for latitudes south of 
the equator so the allowable range for this argument is from -180 to 180.  
Defaults to 23.15, the latitude of avantika.

=item * longitude

The longitude of the point for which the panchanga is to be calculated 
expressed as decimal degrees.  Negative values are used for longitudes west of 
Greenwich so the allowable range for this argument is from -180 to 180.  
Defaults to 75.76, the longitude of avantika.

=back

=cut

sub from_object {
    my ( $class, @arguments ) = @_;

    my %args = validate(
        @arguments,
        {
            object => {
                type => OBJECT,
                can  => 'utc_rd_values',
            },
            latitude => {
                type      => SCALAR,
                default   => '23.15',    # lat. of Avantika
                callbacks => {
                    'between -180 and 180' =>
                      sub { ( $_[0] >= -180 && $_[0] < 180 ) },
                },
            },
            longitude => {
                type      => SCALAR,
                default   => '75.76',    # long. of Avantika
                callbacks => {
                    'between -180 and 180' =>
                      sub { ( $_[0] >= -180 && $_[0] < 180 ) },
                },
            },

            #        locale    => {
            #                        type => SCALAR | OBJECT | UNDEF,
            #                        default => undef,
            #                     },
        }
    );

    my $sun = DateTime::Event::Sunrise->new(
        latitude  => $args{latitude},
        longitude => $args{longitude},
        altitude  => 0,
    );

    my $results = $class->_lunar_from_fixed( $args{object}, $sun, );

    my $newobj = $class->new(
        varsha      => $results->{varsha},
        masa        => $results->{masa},
        adhikamasa  => $results->{adhikamasa},
        paksha      => $results->{paksha},
        tithi       => $results->{tithi},
        adhikatithi => $results->{adhikatithi},
        latitude    => $args{latitude},
        longitude   => $args{longitude},
        time_zone   => $args{object}->time_zone,
    );
    return $newobj;
}

=head3 strftime(@formats)

This function takes one or more parameters consisting of strings
containing special specifiers.  For each such string it will return a
string formatted according to the specifiers, er, specified.  The following
specifiers are allowed in the format string:

=over 4

=item * %a Equivalent to L<adhikamasa_abbrev>.

=item * %A Equivalent to L<adhikamasa_name>.

=item * %l Equivalent to L<adhikatithi_abbrev>.

=item * %L Equivalent to L<adhikatithi_name>.

=item * %m Equivalent to L<masa_abbrev>.

=item * %M Equivalent to L<masa_name>.

=item * %p Equivalent to L<paksha_abbrev>.

=item * %P Equivalent to L<paksha_name>.

=item * %t Equivalent to L<tithi_abbrev>.



( run in 1.711 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )