Astro-Utils

 view release on metacpan or  search on metacpan

lib/Astro/Utils.pm  view on Meta::CPAN

    my $jd = _calc_jd($k, $year);
    return _jd_to_utc($jd);
}

sub _calc_utc_solstice {
    my ($k, $year) = @_;

    die "ERROR: Invalid type for solstice.\n" unless (defined $k && ($k =~ /^[1|3]$/));
    my $jd = _calc_jd($k, $year);
    return _jd_to_utc($jd);
}

sub _calc_tdt_equinox {
    my ($k, $year) = @_;

    die "ERROR: Invalid type for equinox.\n" unless (defined $k && ($k =~ /^[0|2]$/));
    my $jd = _calc_jd($k, $year);
    return _jd_to_tdt($jd);
}

sub _calc_tdt_solstice {
    my ($k, $year) = @_;

    die "ERROR: Invalid type for solstice.\n" unless (defined $k && ($k =~ /^[1|3]$/));
    my $jd = _calc_jd($k, $year);
    return _jd_to_tdt($jd);
}

sub _calc_jd {
    my ($k, $year) = @_;

    # Astronmical Algorithms, Chapter 27.
    my $jde0 = _jde0($k, $year);
    my $t    = ($jde0 - 2451545.0) / 36525;
    my $w    = 35999.373 * $t - 2.47;
    my $dl   = 1 + 0.0334 * _cos($w) + 0.0007 * _cos(2 * $w);
    my $s    = _periodic_term_24($t);

    return ($jde0 + ( (0.00001 * $s) / $dl ));
}

sub _jd_to_utc {
    my ($jd) = @_;

    my ($yr, $mon, $day, $hr, $min, $sec) = _process($jd);

    my $date = DateTime->new(year => $yr, month => $mon, day => $day, hour => $hr, minute => $min, second => $sec);

    # Astronmical Algorithms, Chapter 10, page 79 (Table 10.A).
    my $first = 1620;
    my $last  = 2002;
    my @tbl   = (121,112,103,95,88,82,77,72,68,63,60,56,53,51,48,46,44,42,40,38,             # 1620
                 35,33,31,29,26,24,22,20,18,16,14,12,11,10,9,8,7,7,7,7,                      # 1660
                 7,7,8,8,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,                         # 1700
                 11,11,12,12,12,12,13,13,13,14,14,14,14,15,15,15,15,15,16,16,                # 1740
                 16,16,16,16,16,16,15,15,14,13,                                              # 1780
                 13.1,12.5,12.2,12.0,12.0,12.0,12.0,12.0,12.0,11.9,11.6,11.0,10.2,9.2,8.2,   # 1800
                 7.1,6.2,5.6,5.4,5.3,5.4,5.6,5.9,6.2,6.5,6.8,7.1,7.3,7.5,7.6,                # 1830
                 7.7,7.3,6.2,5.2,2.7,1.4,-1.2,-2.8,-3.8,-4.8,-5.5,-5.3,-5.6,-5.7,-5.9,       # 1860
                 -6.0,-6.3,-6.5,-6.2,-4.7,-2.8,-0.1,2.6,5.3,7.7,10.4,13.3,16.0,18.2,20.2,    # 1890
                 21.1,22.4,23.5,23.8,24.3,24.0,23.9,23.9,23.7,24.0,24.3,25.3,26.2,27.3,28.2, # 1920
                 29.1,30.0,30.7,31.4,32.2,33.1,34.0,35.0,36.5,38.3,40.2,42.2,44.5,46.5,48.5, # 1950
                 50.5,52.5,53.8,54.9,55.8,56.9,58.3,60.0,61.6,63.0,63.8,64.3                 # 1980, 2002 last entry
    );

    my $delta_t = 0;
    my $t = ($yr - 2000) / 100;

    if ($yr >= $first && $yr <= $last) {
        if ($yr % 2) {
            $delta_t = ($tbl[($yr - $first - 1) / 2] + $tbl[($yr - $first + 1) / 2] ) / 2;
        }
        else {
            $delta_t = $tbl[($yr - $first) / 2];
        }
    } elsif ($yr < 948) {
        $delta_t = 2177 + 497 * $t + (44.1 * _pow($t, 2));
    } elsif ($yr >= 948) {
        $delta_t =  102 + 102 * $t + (25.3 * _pow($t, 2));
        if ($yr >= 2000 && $yr <= 2100) {
            $delta_t += 0.37 * ($yr - 2100);
        }
    }

    $date->subtract(seconds => $delta_t);

    return sprintf("%04d-%02d-%02d %02d:%02d:%02d",
                   $date->year, $date->month, $date->day, $date->hour, $date->minute, $date->second);
}

sub _jd_to_tdt {
    my ($jd) = @_;

    my ($yr, $mon, $day, $hr, $min, $sec) = _process($jd);
    return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $yr, $mon, $day, $hr, $min, $sec);
}

sub _process {
    my ($jd) = @_;

    # Astronmical Algorithms Chapter 7, page 63.
    my ($a, $alpha);
    my $z = int($jd + 0.5);
    my $f = ($jd + 0.5) - $z;

    if ($z < 2299161) {
        $a = $z;
    }
    else {
        $alpha = int(($z - 1867216.25) / 36524.25);
        $a = $z + 1 + $alpha - int($alpha / 4);
    }

    my $b   = $a + 1524;
    my $c   = int(($b - 122.1) / 365.25);
    my $d   = int(365.25 * $c);
    my $e   = int(($b -$d) / 30.6001);
    my $dt  = $b - $d - int(30.6001 * $e) + $f;
    my $mon = $e - (($e < 13.5)?(1):(13));
    my $yr  = $c - (($mon > 2.5)?(4716):(4715));
    my $day = int($dt);



( run in 1.705 second using v1.01-cache-2.11-cpan-39bf76dae61 )