File Coverage

blib/lib/Date/Maya.pm
Criterion Covered Total %
statement 71 71 100.0
branch 28 28 100.0
condition 2 3 66.6
subroutine 12 12 100.0
pod 0 3 0.0
total 113 117 96.5


line stmt bran cond sub pod time code
1             package Date::Maya;
2              
3 1     1   546 use 5.006;
  1         3  
  1         36  
4              
5 1     1   5 use strict;
  1         1  
  1         27  
6 1     1   1305 use integer;
  1         21  
  1         6  
7 1     1   46 use warnings;
  1         2  
  1         32  
8 1     1   5 no warnings 'syntax';
  1         2  
  1         36  
9 1     1   5 use Exporter;
  1         2  
  1         146  
10              
11             our $VERSION = '2010011301';
12              
13              
14             our @ISA = qw (Exporter);
15             our @EXPORT = qw (julian_to_maya maya_to_julian);
16             our @EXPORT_OK = qw (MAYA_EPOCH1 MAYA_EPOCH2 MAYA_EPOCH3 maya_epoch);
17             our %EXPORT_TAGS = (MAYA_EPOCH => [qw /MAYA_EPOCH1 MAYA_EPOCH2
18             MAYA_EPOCH3/]);
19              
20              
21 1     1   5 use constant MAYA_EPOCH1 => 584285; # 13 Aug 3114 BC, Gregorian.
  1         2  
  1         222  
22 1     1   5 use constant MAYA_EPOCH2 => 584283; # 11 Aug 3114 BC, Gregorian.
  1         2  
  1         42  
23 1     1   5 use constant MAYA_EPOCH3 => 489384; # 15 Oct 3374 BC, Gregorian.
  1         2  
  1         1077  
24              
25             my $epoch = MAYA_EPOCH1;
26              
27 1     1 0 10 sub maya_epoch ($) {$epoch = shift;}
28              
29              
30             my $date_parts = [
31             [kin => 20],
32             [unial => 18],
33             [tun => 20],
34             [katun => 20],
35             [baktun => 20],
36             [pictun => 20],
37             [calabtun => 20],
38             [kinchiltun => 20],
39             [alautun => undef],
40             ];
41              
42             my $max_baktun = 13;
43              
44             my @tzolkin = qw /Ahau Imix Ik Akbal Kan Chicchan Cimi Manik Lamat Muluc
45             Oc Chuen Eb Ben Ix Men Cib Caban Etznab Caunac/;
46              
47             my $tzolkin_sweek_length = 13;
48             my $tzolkin_sweek_offset = 4;
49              
50             my @haab = qw /Pop Uo Zip Zotz Tzec Xul Yaxkin Mol Chen Yax Zac Ceh
51             Mac Kankin Muan Pax Kayab Cumku/;
52              
53             my $haab_month_length = 20;
54             my $haab_uayeb_length = 5;
55             my $haab_year_length = $haab_month_length * @haab;
56             my $haab_fyear_length = $haab_year_length + $haab_uayeb_length;
57             my $haab_offset = 348; # 8 Cumku.
58              
59              
60             sub julian_to_maya ($) {
61 28 100   28 0 899 die "No argument to julian_to_maya\n" unless @_;
62              
63 27         39 my $julian = shift;
64              
65 27 100       135 die "Undefined argument to julian_to_maya\n" unless defined $julian;
66 26 100       74 die "Illegal argument `$julian' to julian_to_maya\n" if $julian =~ /\D/;
67              
68 25         33 my $days = $julian - $epoch;
69 25 100       50 die "Cannot deal with dates before epoch.\n" if $days < 0;
70              
71             # Calculation of the Long Count.
72 24         23 my @results;
73              
74 24         43 foreach my $part (@$date_parts) {
75 120         204 push @results => $days % $part -> [1];
76 120 100       240 last if $part -> [0] eq "baktun";
77 96         116 $days /= $part -> [1];
78             }
79              
80 24         31 @results = reverse @results;
81 24         27 $results [0] %= $max_baktun;
82 24 100       50 $results [0] = $max_baktun if $results [0] == 0;
83              
84 24         85 my $long_count = join "." => @results;
85              
86 24 100       47 unless (wantarray) {
87 12         45 return $long_count;
88             }
89              
90              
91             # Calculation of the Tzolkin.
92 12         20 my $tzolkin_day = ($julian - $epoch + $tzolkin_sweek_offset) %
93             $tzolkin_sweek_length;
94 12 100       25 $tzolkin_day = $tzolkin_sweek_length if $tzolkin_day == 0;
95              
96 12         27 my $tzolkin = "$tzolkin_day $tzolkin[$results[4]]";
97              
98              
99             # Calculation of the Haab.
100 12         19 my $haab_y_day = ($julian - $epoch + $haab_offset) % $haab_fyear_length;
101 12         13 my $haab;
102 12 100       25 if ($haab_y_day >= $haab_year_length) {
103 2         4 $haab = ($haab_y_day - $haab_year_length) . " Uayeb";
104             }
105             else {
106 10         36 $haab = join " " => ($haab_y_day % $haab_month_length),
107             $haab [$haab_y_day / $haab_month_length];
108             }
109              
110 12         72 ($long_count, $tzolkin, $haab);
111             }
112              
113              
114              
115             sub maya_to_julian ($) {
116 13 100   13 0 134 die "Failed to supply argument to maya_to_julian\n" unless @_;
117              
118 12         41 my $maya = shift;
119              
120 12 100       27 die "Undefined argument to maya_to_julian\n" unless defined $maya;
121              
122 11         44 my @parts = split /\./ => $maya;
123 50         123 die "Illegal argument `$maya' to maya_to_julian\n"
124 11 100 66     40 unless 5 == @parts && !grep {/\D/} @parts;
125             # Normalize the baktun.
126 10 100       29 $parts [0] = 0 if $parts [0] == $max_baktun;
127              
128 10         12 my $julian = $epoch;
129              
130 10         12 my $mod = 1;
131 10         10 my $i = 0;
132 10         17 foreach my $part (reverse @parts) {
133 45 100       91 if ($part >= $date_parts -> [$i] -> [1]) {
134 2         11 die "Out of bounds argument to maya_to_julian\n";
135             }
136 43         45 $julian += $part * $mod;
137 43         49 $mod *= $date_parts -> [$i] -> [1];
138 43         56 $i ++;
139             }
140              
141 8         29 $julian;
142             }
143              
144             __END__