| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Date::Baha::i; |
|
2
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:GENE'; |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
# ABSTRACT: Convert to and from Baha'i dates |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.2001'; |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
3
|
|
|
3
|
|
2423
|
use strict; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
89
|
|
|
10
|
3
|
|
|
3
|
|
16
|
use warnings; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
87
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
3
|
|
|
3
|
|
1186
|
use parent 'Exporter'; |
|
|
3
|
|
|
|
|
868
|
|
|
|
3
|
|
|
|
|
15
|
|
|
13
|
3
|
|
|
3
|
|
229
|
use vars qw(@EXPORT @EXPORT_OK); |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
195
|
|
|
14
|
|
|
|
|
|
|
@EXPORT = @EXPORT_OK = qw( |
|
15
|
|
|
|
|
|
|
as_string |
|
16
|
|
|
|
|
|
|
cycles |
|
17
|
|
|
|
|
|
|
days |
|
18
|
|
|
|
|
|
|
days_of_the_week |
|
19
|
|
|
|
|
|
|
from_bahai |
|
20
|
|
|
|
|
|
|
holy_days |
|
21
|
|
|
|
|
|
|
months |
|
22
|
|
|
|
|
|
|
next_holy_day |
|
23
|
|
|
|
|
|
|
to_bahai |
|
24
|
|
|
|
|
|
|
years |
|
25
|
|
|
|
|
|
|
); |
|
26
|
|
|
|
|
|
|
|
|
27
|
3
|
|
|
|
|
241
|
use Date::Calc qw( |
|
28
|
|
|
|
|
|
|
Add_Delta_Days |
|
29
|
|
|
|
|
|
|
Date_to_Days |
|
30
|
|
|
|
|
|
|
Day_of_Week |
|
31
|
|
|
|
|
|
|
leap_year |
|
32
|
3
|
|
|
3
|
|
841
|
); |
|
|
3
|
|
|
|
|
12139
|
|
|
33
|
3
|
|
|
3
|
|
1519
|
use Lingua::EN::Numbers qw(num2en_ordinal); |
|
|
3
|
|
|
|
|
6162
|
|
|
|
3
|
|
|
|
|
182
|
|
|
34
|
3
|
|
|
3
|
|
1517
|
use Lingua::EN::Numbers::Years; |
|
|
3
|
|
|
|
|
14850
|
|
|
|
3
|
|
|
|
|
232
|
|
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# Set constants |
|
37
|
3
|
|
|
3
|
|
25
|
use constant FACTOR => 19; # Groups of 19 |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
283
|
|
|
38
|
3
|
|
|
3
|
|
20
|
use constant FEBRUARY => 2; # Handy |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
130
|
|
|
39
|
3
|
|
|
3
|
|
17
|
use constant MARCH => 3; # Handy |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
136
|
|
|
40
|
3
|
|
|
3
|
|
18
|
use constant SHARAF => 16; # Handy |
|
|
3
|
|
|
|
|
26
|
|
|
|
3
|
|
|
|
|
168
|
|
|
41
|
3
|
|
|
3
|
|
18
|
use constant LAST_START_DAY => 2; # 1st day of fast |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
148
|
|
|
42
|
3
|
|
|
3
|
|
61
|
use constant YEAR_START_DAY => 21; # Vernal equinox |
|
|
3
|
|
|
|
|
35
|
|
|
|
3
|
|
|
|
|
150
|
|
|
43
|
3
|
|
|
3
|
|
18
|
use constant LEAP_START_DAY => 26; # Intercalary days |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
177
|
|
|
44
|
3
|
|
|
3
|
|
20
|
use constant FIRST_YEAR => 1844; # History! |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
157
|
|
|
45
|
3
|
|
|
3
|
|
17
|
use constant ADJUST_YEAR => 1900; # Year factor |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
209
|
|
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
|
|
48
|
3
|
|
|
|
|
261
|
use constant CYCLE_YEAR => qw( |
|
49
|
|
|
|
|
|
|
Alif |
|
50
|
|
|
|
|
|
|
Ba |
|
51
|
|
|
|
|
|
|
Ab |
|
52
|
|
|
|
|
|
|
Dal |
|
53
|
|
|
|
|
|
|
Bab |
|
54
|
|
|
|
|
|
|
Vav |
|
55
|
|
|
|
|
|
|
Abad |
|
56
|
|
|
|
|
|
|
Jad |
|
57
|
|
|
|
|
|
|
Baha |
|
58
|
|
|
|
|
|
|
Hubb |
|
59
|
|
|
|
|
|
|
Bahhaj |
|
60
|
|
|
|
|
|
|
Javab |
|
61
|
|
|
|
|
|
|
Ahad |
|
62
|
|
|
|
|
|
|
Vahhab |
|
63
|
|
|
|
|
|
|
Vidad |
|
64
|
|
|
|
|
|
|
Badi |
|
65
|
|
|
|
|
|
|
Bahi |
|
66
|
|
|
|
|
|
|
Abha |
|
67
|
|
|
|
|
|
|
Vahid |
|
68
|
3
|
|
|
3
|
|
19
|
); |
|
|
3
|
|
|
|
|
6
|
|
|
69
|
3
|
|
|
|
|
528
|
use constant MONTH_DAY => qw( |
|
70
|
|
|
|
|
|
|
Baha |
|
71
|
|
|
|
|
|
|
Jalal |
|
72
|
|
|
|
|
|
|
Jamal |
|
73
|
|
|
|
|
|
|
'Azamat |
|
74
|
|
|
|
|
|
|
Nur |
|
75
|
|
|
|
|
|
|
Rahmat |
|
76
|
|
|
|
|
|
|
Kalimat |
|
77
|
|
|
|
|
|
|
Kamal |
|
78
|
|
|
|
|
|
|
Asma' |
|
79
|
|
|
|
|
|
|
'Izzat |
|
80
|
|
|
|
|
|
|
Mashiyyat |
|
81
|
|
|
|
|
|
|
'Ilm |
|
82
|
|
|
|
|
|
|
Qudrat |
|
83
|
|
|
|
|
|
|
Qawl |
|
84
|
|
|
|
|
|
|
Masa'il |
|
85
|
|
|
|
|
|
|
Sharaf |
|
86
|
|
|
|
|
|
|
Sultan |
|
87
|
|
|
|
|
|
|
Mulk |
|
88
|
|
|
|
|
|
|
'Ala |
|
89
|
|
|
|
|
|
|
Ayyam-i-Ha |
|
90
|
3
|
|
|
3
|
|
20
|
); |
|
|
3
|
|
|
|
|
5
|
|
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# We quote floats to avoid mis-computation. |
|
94
|
|
|
|
|
|
|
# Month => [Number, Start, End] # TODO ?, ? |
|
95
|
3
|
|
|
|
|
307
|
use constant MONTHS => { |
|
96
|
|
|
|
|
|
|
"Baha" => [ 0, '3.21', '4.08'], # 80, 98 |
|
97
|
|
|
|
|
|
|
"Jalal" => [ 1, '4.09', '4.27'], # 99, 117 |
|
98
|
|
|
|
|
|
|
"Jamal" => [ 2, '4.28', '5.16'], #118, 136 |
|
99
|
|
|
|
|
|
|
"'Azamat" => [ 3, '5.17', '6.04'], #137, 155 |
|
100
|
|
|
|
|
|
|
"Nur" => [ 4, '6.05', '6.23'], #156, 174 |
|
101
|
|
|
|
|
|
|
"Rahmat" => [ 5, '6.24', '7.12'], #175, 193 |
|
102
|
|
|
|
|
|
|
"Kalimat" => [ 6, '7.13', '7.31'], #194, 212 |
|
103
|
|
|
|
|
|
|
"Kamal" => [ 7, '8.01', '8.19'], #213, 231 |
|
104
|
|
|
|
|
|
|
"Asma'" => [ 8, '8.20', '9.07'], #232, 250 |
|
105
|
|
|
|
|
|
|
"'Izzat" => [ 9, '9.08', '9.26'], #251, 269 |
|
106
|
|
|
|
|
|
|
"Mashiyyat" => [10, '9.27', '10.15'], #270, 288 |
|
107
|
|
|
|
|
|
|
"'Ilm" => [11, '10.16', '11.03'], #289, 307 |
|
108
|
|
|
|
|
|
|
"Qudrat" => [12, '11.04', '11.22'], #308, 326 |
|
109
|
|
|
|
|
|
|
"Qawl" => [13, '11.23', '12.11'], #327, 345 |
|
110
|
|
|
|
|
|
|
"Masa'il" => [14, '12.12', '12.30'], #346, 364 |
|
111
|
|
|
|
|
|
|
"Sharaf" => [15, '12.31', '1.18'], #365, 18 |
|
112
|
|
|
|
|
|
|
"Sultan" => [16, '1.19', '2.06'], # 19, 37 |
|
113
|
|
|
|
|
|
|
"Mulk" => [17, '2.07', '2.25'], # 38, 56 |
|
114
|
|
|
|
|
|
|
"Ayyam-i-Ha" => [-1, '2.26', '3.01'], # 57, 60 |
|
115
|
|
|
|
|
|
|
"'Ala" => [18, '3.02', '3.20'], # 61, 79 |
|
116
|
3
|
|
|
3
|
|
21
|
}; |
|
|
3
|
|
|
|
|
5
|
|
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
|
|
119
|
3
|
|
|
|
|
331
|
use constant DOW_NAME => qw( |
|
120
|
|
|
|
|
|
|
Jalal |
|
121
|
|
|
|
|
|
|
Jamal |
|
122
|
|
|
|
|
|
|
Kaml |
|
123
|
|
|
|
|
|
|
Fidal |
|
124
|
|
|
|
|
|
|
'Idal |
|
125
|
|
|
|
|
|
|
Istijlal |
|
126
|
|
|
|
|
|
|
Istiqlal |
|
127
|
3
|
|
|
3
|
|
21
|
); |
|
|
3
|
|
|
|
|
5
|
|
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
|
|
130
|
3
|
|
|
|
|
6246
|
use constant HOLY_DAYS => { |
|
131
|
|
|
|
|
|
|
# Work suspended': |
|
132
|
|
|
|
|
|
|
"Naw Ruz" => [ '3.21' ], |
|
133
|
|
|
|
|
|
|
"First Day of Ridvan" => [ '4.21' ], |
|
134
|
|
|
|
|
|
|
"Ninth Day of Ridvan" => [ '4.29' ], |
|
135
|
|
|
|
|
|
|
"Twelfth Day of Ridvan" => [ '5.02' ], |
|
136
|
|
|
|
|
|
|
"Declaration of the Bab" => [ '5.23' ], |
|
137
|
|
|
|
|
|
|
"Ascension of Baha'u'llah" => [ '5.29' ], |
|
138
|
|
|
|
|
|
|
"Martyrdom of the Bab" => [ '7.09' ], |
|
139
|
|
|
|
|
|
|
"Birth of the Bab" => [ '10.20' ], |
|
140
|
|
|
|
|
|
|
"Birth of Baha'u'llah" => [ '11.12' ], |
|
141
|
|
|
|
|
|
|
# Work not suspended: |
|
142
|
|
|
|
|
|
|
"Ayyam-i-Ha" => [ '2.26', 4 ], # 5 days are calculated in leap years |
|
143
|
|
|
|
|
|
|
"The Fast" => [ '3.02', 19 ], |
|
144
|
|
|
|
|
|
|
"Days of Ridvan" => [ '4.21', 12 ], |
|
145
|
|
|
|
|
|
|
"Day of the Covenant" => [ '11.26' ], |
|
146
|
|
|
|
|
|
|
"Ascension of 'Abdu'l-Baha" => [ '11.28' ], |
|
147
|
3
|
|
|
3
|
|
20
|
}; |
|
|
3
|
|
|
|
|
14
|
|
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# List return functions |
|
150
|
0
|
|
|
0
|
1
|
0
|
sub cycles { return CYCLE_YEAR } |
|
151
|
0
|
|
|
0
|
1
|
0
|
sub years { return CYCLE_YEAR } |
|
152
|
0
|
|
|
0
|
1
|
0
|
sub months { return MONTH_DAY } |
|
153
|
0
|
|
|
0
|
1
|
0
|
sub days { return (MONTH_DAY)[0 .. 18] } |
|
154
|
0
|
|
|
0
|
1
|
0
|
sub days_of_the_week { return DOW_NAME } |
|
155
|
0
|
|
|
0
|
1
|
0
|
sub holy_days { return HOLY_DAYS } |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
sub to_bahai { |
|
158
|
2
|
|
|
2
|
1
|
1351
|
my %args = @_; |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# Grab the ymd from the arguments if they have been passed in. |
|
161
|
2
|
|
|
|
|
8
|
my ($year, $month, $day) = @args{qw(year month day)}; |
|
162
|
|
|
|
|
|
|
# Make sure we have a proper ymd before proceeding. |
|
163
|
2
|
|
|
|
|
9
|
($year, $month, $day) = _ymd( |
|
164
|
|
|
|
|
|
|
%args, |
|
165
|
|
|
|
|
|
|
year => $year, |
|
166
|
|
|
|
|
|
|
month => $month, |
|
167
|
|
|
|
|
|
|
day => $day, |
|
168
|
|
|
|
|
|
|
); |
|
169
|
|
|
|
|
|
|
|
|
170
|
2
|
|
|
|
|
4
|
my ($bahai_month, $bahai_day); |
|
171
|
|
|
|
|
|
|
|
|
172
|
2
|
|
|
|
|
3
|
for (values %{ MONTHS() }) { |
|
|
2
|
|
|
|
|
8
|
|
|
173
|
39
|
|
|
|
|
81
|
my ($days, $lower, $upper) = _setup_date_comparison( |
|
174
|
|
|
|
|
|
|
$year, $month, $day, @$_[1,2] |
|
175
|
|
|
|
|
|
|
); |
|
176
|
|
|
|
|
|
|
|
|
177
|
39
|
100
|
100
|
|
|
116
|
if ($days >= $lower && $days <= $upper) { |
|
178
|
2
|
|
|
|
|
4
|
$bahai_month = $_->[0]; |
|
179
|
2
|
|
|
|
|
4
|
$bahai_day = $days - $lower; |
|
180
|
2
|
|
|
|
|
5
|
last; |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
# Build the date hash to return. |
|
185
|
2
|
|
|
|
|
8
|
return _build_date( |
|
186
|
|
|
|
|
|
|
$year, $month, $day, $bahai_month, $bahai_day, |
|
187
|
|
|
|
|
|
|
%args |
|
188
|
|
|
|
|
|
|
); |
|
189
|
|
|
|
|
|
|
} |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub from_bahai { |
|
192
|
366
|
|
|
366
|
1
|
197064
|
my %args = @_; |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# Figure out the year. |
|
195
|
366
|
|
|
|
|
769
|
my $year = $args{year} + FIRST_YEAR; |
|
196
|
366
|
100
|
100
|
|
|
1517
|
$year-- unless $args{month} > SHARAF || $args{month} == -1; |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Reset the month number if we are given Ayyam-i-Ha. |
|
199
|
366
|
100
|
|
|
|
865
|
$args{month} = 0 if $args{month} == -1; |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
# This ugliness actually finds the month and day number. |
|
202
|
366
|
|
|
|
|
1061
|
my $day = (MONTHS->{ (MONTH_DAY)[$args{month} - 1] })->[1]; |
|
203
|
366
|
|
|
|
|
1252
|
(my $month, $day) = split /\./, $day; |
|
204
|
|
|
|
|
|
|
($year, $month, $day) = Add_Delta_Days( |
|
205
|
366
|
|
|
|
|
1306
|
$year, $month, $day, $args{day} - 1 |
|
206
|
|
|
|
|
|
|
); |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
return wantarray |
|
209
|
366
|
50
|
|
|
|
1421
|
? ($year, $month, $day) |
|
210
|
|
|
|
|
|
|
: join '/', $year, $month, $day; |
|
211
|
|
|
|
|
|
|
} |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub as_string { |
|
214
|
|
|
|
|
|
|
# XXX With Lingua::EN::Numbers, naively assume that we only care about English. |
|
215
|
8
|
|
|
8
|
1
|
5918
|
my ($date_hash, %args) = @_; |
|
216
|
|
|
|
|
|
|
|
|
217
|
8
|
50
|
|
|
|
25
|
$args{size} = 1 unless defined $args{size}; |
|
218
|
8
|
50
|
|
|
|
25
|
$args{numeric} = 0 unless defined $args{numeric}; |
|
219
|
8
|
50
|
|
|
|
15
|
$args{alpha} = 1 unless defined $args{alpha}; |
|
220
|
|
|
|
|
|
|
|
|
221
|
8
|
|
|
|
|
12
|
my $date; |
|
222
|
|
|
|
|
|
|
|
|
223
|
8
|
50
|
|
|
|
22
|
my $is_ayyam_i_ha = $date_hash->{month} == -1 ? 1 : 0; |
|
224
|
|
|
|
|
|
|
|
|
225
|
8
|
100
|
100
|
|
|
85
|
if (!$args{size} && $args{numeric} && $args{alpha}) { |
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# short alpha-numeric |
|
227
|
|
|
|
|
|
|
$date .= sprintf '%s (%d), %s (%d) of %s (%d), year %d, %s (%d) of %s (%d)', |
|
228
|
1
|
|
|
|
|
10
|
@$date_hash{qw( |
|
229
|
|
|
|
|
|
|
dow_name dow day_name day month_name month |
|
230
|
|
|
|
|
|
|
year year_name cycle_year cycle_name cycle |
|
231
|
|
|
|
|
|
|
)}; |
|
232
|
|
|
|
|
|
|
} |
|
233
|
|
|
|
|
|
|
elsif ($args{size} && $args{numeric} && $args{alpha}) { |
|
234
|
|
|
|
|
|
|
# long alpha-numeric |
|
235
|
|
|
|
|
|
|
# XXX Fugly hacking begins. |
|
236
|
1
|
50
|
|
|
|
5
|
my $month_string = $is_ayyam_i_ha ? '%s%s' : 'the %s month %s'; |
|
237
|
1
|
|
|
|
|
5
|
my $n = year2en($date_hash->{year}); |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
$date .= sprintf |
|
240
|
|
|
|
|
|
|
"%s week day %s, %s day %s of $month_string, year %s (%d), %s year %s of the %s vahid %s of the %s kull-i-shay", |
|
241
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{dow}), |
|
242
|
|
|
|
|
|
|
$date_hash->{dow_name}, |
|
243
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{day}), |
|
244
|
|
|
|
|
|
|
$date_hash->{day_name}, |
|
245
|
|
|
|
|
|
|
($is_ayyam_i_ha ? '' : num2en_ordinal($date_hash->{month})), |
|
246
|
|
|
|
|
|
|
$date_hash->{month_name}, |
|
247
|
|
|
|
|
|
|
$n, |
|
248
|
|
|
|
|
|
|
$date_hash->{year}, |
|
249
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{cycle_year}), |
|
250
|
|
|
|
|
|
|
$date_hash->{year_name}, |
|
251
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{cycle}), |
|
252
|
|
|
|
|
|
|
$date_hash->{cycle_name}, |
|
253
|
1
|
50
|
|
|
|
149
|
num2en_ordinal($date_hash->{kull_i_shay}); |
|
254
|
|
|
|
|
|
|
} |
|
255
|
|
|
|
|
|
|
elsif (!$args{size} && $args{numeric} && !$args{alpha}) { |
|
256
|
|
|
|
|
|
|
# short numeric |
|
257
|
1
|
|
|
|
|
5
|
$date .= sprintf '%s/%s/%s', @$date_hash{qw(month day year)}; |
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
elsif ($args{size} && $args{numeric}) { |
|
260
|
|
|
|
|
|
|
# long numeric |
|
261
|
|
|
|
|
|
|
$date .= sprintf |
|
262
|
|
|
|
|
|
|
'%s day of the week, %s day of the %s month, year %s, %s year of the %s vahid of the %s kull-i-shay', |
|
263
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{dow}), |
|
264
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{day}), |
|
265
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{month}), |
|
266
|
|
|
|
|
|
|
$date_hash->{year}, |
|
267
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{cycle_year}), |
|
268
|
|
|
|
|
|
|
num2en_ordinal($date_hash->{cycle}), |
|
269
|
1
|
|
|
|
|
4
|
num2en_ordinal($date_hash->{kull_i_shay}); |
|
270
|
|
|
|
|
|
|
} |
|
271
|
|
|
|
|
|
|
elsif (!$args{size} && $args{alpha}) { |
|
272
|
|
|
|
|
|
|
# short alpha |
|
273
|
|
|
|
|
|
|
$date .= sprintf '%s, %s of %s, %s of %s', |
|
274
|
1
|
|
|
|
|
9
|
@$date_hash{qw( |
|
275
|
|
|
|
|
|
|
dow_name day_name month_name year_name cycle_name |
|
276
|
|
|
|
|
|
|
)}; |
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
else { |
|
279
|
|
|
|
|
|
|
# long alpha |
|
280
|
3
|
50
|
|
|
|
7
|
my $month_string = $is_ayyam_i_ha ? '%s' : 'month %s'; |
|
281
|
3
|
|
|
|
|
10
|
my $n = year2en($date_hash->{year}); |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
$date .= sprintf |
|
284
|
|
|
|
|
|
|
"week day %s, day %s of $month_string, year %s, %s of the vahid %s of the %s kull-i-shay", |
|
285
|
|
|
|
|
|
|
@$date_hash{qw(dow_name day_name month_name)}, |
|
286
|
|
|
|
|
|
|
$n, |
|
287
|
|
|
|
|
|
|
@$date_hash{qw(year_name cycle_name)}, |
|
288
|
3
|
|
|
|
|
217
|
num2en_ordinal($date_hash->{kull_i_shay}); |
|
289
|
|
|
|
|
|
|
} |
|
290
|
|
|
|
|
|
|
|
|
291
|
8
|
0
|
33
|
|
|
426
|
if ($date_hash->{holy_day} && $args{size}) { |
|
292
|
0
|
|
|
|
|
0
|
$date .= ', holy day: ' . join '', keys %{ $date_hash->{holy_day} }; |
|
|
0
|
|
|
|
|
0
|
|
|
293
|
|
|
|
|
|
|
} |
|
294
|
|
|
|
|
|
|
|
|
295
|
8
|
|
|
|
|
28
|
return $date; |
|
296
|
|
|
|
|
|
|
} |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
sub next_holy_day { |
|
299
|
0
|
|
|
0
|
1
|
0
|
my ($year, $month, $day) = @_; |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
# Use today if we are not provided with a date. |
|
302
|
0
|
|
|
|
|
0
|
($year, $month, $day) = _ymd( |
|
303
|
|
|
|
|
|
|
year => $year, |
|
304
|
|
|
|
|
|
|
month => $month, |
|
305
|
|
|
|
|
|
|
day => $day, |
|
306
|
|
|
|
|
|
|
); |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
# Construct our lists of pseudo real number dates. |
|
309
|
0
|
|
|
|
|
0
|
my %inverted = _invert_holy_days($year); |
|
310
|
0
|
|
|
|
|
0
|
my @sorted = sort { $a <=> $b } keys %inverted; |
|
|
0
|
|
|
|
|
0
|
|
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
# Make the month and day a pseudo real number. |
|
313
|
0
|
|
|
|
|
0
|
my $m_d = "$month.$day"; |
|
314
|
0
|
|
|
|
|
0
|
my $holy_date; |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
# Find the first date greater than the one provided. |
|
317
|
0
|
|
|
|
|
0
|
for (@sorted) { |
|
318
|
0
|
0
|
|
|
|
0
|
if ($m_d < $_) { |
|
319
|
0
|
|
|
|
|
0
|
$holy_date = $_; |
|
320
|
0
|
|
|
|
|
0
|
last; |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
} |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
# If one was not found, grab the last date in the list. |
|
325
|
0
|
0
|
|
|
|
0
|
$holy_date = $sorted[-1] unless $holy_date; |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
# Make this look like a date again. |
|
328
|
0
|
|
|
|
|
0
|
(my $date = $holy_date) =~ s/\./\//; |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
return wantarray |
|
331
|
0
|
0
|
|
|
|
0
|
? ($inverted{$holy_date}, $date) |
|
332
|
|
|
|
|
|
|
: "$inverted{$holy_date} $date"; |
|
333
|
|
|
|
|
|
|
} |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
# Helper functions |
|
336
|
|
|
|
|
|
|
# Date comparison gymnastics. |
|
337
|
|
|
|
|
|
|
sub _setup_date_comparison { |
|
338
|
39
|
|
|
39
|
|
61
|
my ($y, $m, $d, $s, $e) = @_; |
|
339
|
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
# Dates are encoded as decimals. |
|
341
|
39
|
|
|
|
|
88
|
my ($start_month, $start_day) = split /\./, $s; |
|
342
|
39
|
|
|
|
|
91
|
my ($end_month, $end_day) = split /\./, $e; |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
# Slide either the start or end year, given the month we're |
|
345
|
|
|
|
|
|
|
# looking at. |
|
346
|
39
|
|
|
|
|
68
|
my ($start_year, $end_year) = ($y, $y); |
|
347
|
39
|
100
|
|
|
|
79
|
if ($end_month < $start_month) { |
|
348
|
2
|
50
|
|
|
|
12
|
if ($m == $start_month) { |
|
|
|
50
|
|
|
|
|
|
|
349
|
0
|
|
|
|
|
0
|
$end_year++; |
|
350
|
|
|
|
|
|
|
} |
|
351
|
|
|
|
|
|
|
elsif ($m == $end_month) { |
|
352
|
0
|
|
|
|
|
0
|
$start_year--; |
|
353
|
|
|
|
|
|
|
} |
|
354
|
|
|
|
|
|
|
} |
|
355
|
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
return |
|
357
|
39
|
|
|
|
|
148
|
Date_to_Days($y, $m, $d), |
|
358
|
|
|
|
|
|
|
Date_to_Days($start_year, $start_month, $start_day), |
|
359
|
|
|
|
|
|
|
Date_to_Days($end_year, $end_month, $end_day); |
|
360
|
|
|
|
|
|
|
} |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
sub _build_date { |
|
363
|
2
|
|
|
2
|
|
7
|
my ($year, $month, $day, $new_month, $new_day, %args) = @_; |
|
364
|
|
|
|
|
|
|
|
|
365
|
2
|
|
|
|
|
3
|
my %date; |
|
366
|
2
|
|
|
|
|
6
|
@date{qw(month day)} = ($new_month, $new_day); |
|
367
|
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
# Set the day of the week (rotated by 2). |
|
369
|
2
|
|
|
|
|
9
|
$date{dow} = Day_of_Week($year, $month, $day); |
|
370
|
2
|
|
|
|
|
4
|
$date{dow} += 2; |
|
371
|
2
|
50
|
|
|
|
15
|
$date{dow} = $date{dow} - 7 if $date{dow} > 7; |
|
372
|
2
|
|
|
|
|
7
|
$date{dow_name} = (DOW_NAME)[$date{dow} - 1]; |
|
373
|
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
# Set the day. |
|
375
|
2
|
|
|
|
|
5
|
$date{day_name} = (MONTH_DAY)[$date{day}]; |
|
376
|
2
|
|
|
|
|
4
|
$date{day}++; |
|
377
|
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
# Set the the month. |
|
379
|
2
|
|
|
|
|
3
|
$date{month_name} = (MONTH_DAY)[$date{month}]; |
|
380
|
|
|
|
|
|
|
# Fix the month number, unless we are in Ayyam-i-Ha. |
|
381
|
2
|
50
|
|
|
|
12
|
$date{month}++ unless $date{month} == -1; |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
# Set the year. |
|
384
|
|
|
|
|
|
|
# Algorithm lifted from Danesh's "bahaidate". |
|
385
|
2
|
50
|
33
|
|
|
23
|
$date{year} = ($month < MARCH) || |
|
386
|
|
|
|
|
|
|
($month == MARCH && $day < YEAR_START_DAY) |
|
387
|
|
|
|
|
|
|
? $year - FIRST_YEAR |
|
388
|
|
|
|
|
|
|
: $year - (FIRST_YEAR - 1); |
|
389
|
|
|
|
|
|
|
|
|
390
|
2
|
|
|
|
|
16
|
$date{year_name} = (CYCLE_YEAR)[($date{year} - 1) % FACTOR]; |
|
391
|
2
|
|
|
|
|
5
|
$date{cycle_year} = $date{year} % FACTOR; |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
# Set the cycle. |
|
394
|
2
|
|
|
|
|
9
|
$date{cycle} = int($date{year} / FACTOR) + 1; |
|
395
|
2
|
|
|
|
|
4
|
$date{cycle_name} = (CYCLE_YEAR)[($date{cycle} - 1) % FACTOR]; |
|
396
|
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
# Set the Kull-i-Shay. |
|
398
|
2
|
|
|
|
|
5
|
$date{kull_i_shay} = int($date{cycle} / FACTOR) + 1; |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
# $date{timezone} = tz_local_offset(); |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
# Get the holy day. |
|
403
|
2
|
|
|
|
|
6
|
my %inverted = _invert_holy_days($year); |
|
404
|
2
|
|
|
|
|
12
|
my $m_d = sprintf '%d.%d', $month, $day; |
|
405
|
2
|
50
|
|
|
|
7
|
$date{holy_day} = $inverted{$m_d} if exists $inverted{$m_d}; |
|
406
|
|
|
|
|
|
|
|
|
407
|
2
|
50
|
|
|
|
33
|
return wantarray ? %date : as_string(\%date, %args); |
|
408
|
|
|
|
|
|
|
} |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
sub _invert_holy_days { |
|
411
|
2
|
|
33
|
2
|
|
6
|
my $year = shift || (localtime)[5] + ADJUST_YEAR; |
|
412
|
|
|
|
|
|
|
|
|
413
|
2
|
|
|
|
|
4
|
my %inverted; |
|
414
|
|
|
|
|
|
|
|
|
415
|
2
|
|
|
|
|
3
|
while (my ($name, $date) = each %{ HOLY_DAYS() }) { |
|
|
30
|
|
|
|
|
74
|
|
|
416
|
28
|
|
|
|
|
68
|
$inverted{$date->[0]} = $name; |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
# Does this date contain a day span? |
|
419
|
28
|
100
|
|
|
|
59
|
if (@$date > 1) { |
|
420
|
|
|
|
|
|
|
# Increment the Ayyam-i-Ha day if we are in a leap year. |
|
421
|
6
|
50
|
66
|
|
|
22
|
$date->[1]++ if $name eq 'Ayyam-i-Ha' && leap_year($year); |
|
422
|
|
|
|
|
|
|
|
|
423
|
6
|
|
|
|
|
16
|
for (1 .. $date->[1] - 1) { |
|
424
|
64
|
|
|
|
|
197
|
(undef, my $month, my $day) = Add_Delta_Days( |
|
425
|
|
|
|
|
|
|
$year, split(/\./, $date->[0]), $_ |
|
426
|
|
|
|
|
|
|
); |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
# Pre-pad the day number with a zero. |
|
429
|
64
|
|
|
|
|
240
|
$inverted{ sprintf '%d.%d', $month, $day } = $name; |
|
430
|
|
|
|
|
|
|
} |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
} |
|
433
|
|
|
|
|
|
|
|
|
434
|
2
|
|
|
|
|
54
|
return %inverted; |
|
435
|
|
|
|
|
|
|
} |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
# Return a ymd date array but try to honor the epoch and use_gmtime settings. |
|
438
|
|
|
|
|
|
|
sub _ymd { |
|
439
|
2
|
|
|
2
|
|
6
|
my %args = @_; |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
# Use the system time, if a ymd is not provided. |
|
442
|
2
|
50
|
33
|
|
|
22
|
unless($args{year} && $args{month} && $args{day}) { |
|
|
|
|
33
|
|
|
|
|
|
443
|
0
|
|
0
|
|
|
0
|
$args{epoch} ||= time; |
|
444
|
|
|
|
|
|
|
($args{year}, $args{month}, $args{day}) = $args{use_gmtime} |
|
445
|
|
|
|
|
|
|
? (gmtime $args{epoch})[5,4,3] |
|
446
|
0
|
0
|
|
|
|
0
|
: (localtime $args{epoch})[5,4,3]; |
|
447
|
|
|
|
|
|
|
# Fix the year and the month. |
|
448
|
0
|
|
|
|
|
0
|
$args{year} += ADJUST_YEAR; |
|
449
|
0
|
|
|
|
|
0
|
$args{month}++; |
|
450
|
|
|
|
|
|
|
} |
|
451
|
|
|
|
|
|
|
|
|
452
|
2
|
|
|
|
|
7
|
return $args{year}, $args{month}, $args{day}; |
|
453
|
|
|
|
|
|
|
} |
|
454
|
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
1; |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
__END__ |