xref: /webtrees/app/Date/HijriDate.php (revision 728c8c2714cc197d45bad7363eb52e0bff3297bb)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Date;
21
22use Fisharebest\ExtCalendar\ArabicCalendar;
23use Fisharebest\Webtrees\I18N;
24
25/**
26 * Definitions for Hijri dates.
27 *
28 * Note that these are "theoretical" dates.
29 * "True" dates are based on local lunar observations, and can be a +/- one day.
30 */
31class HijriDate extends AbstractCalendarDate
32{
33    // GEDCOM calendar escape
34    public const ESCAPE = '@#DHIJRI@';
35
36    // Convert GEDCOM month names to month numbers
37    protected const MONTH_ABBREVIATIONS = [
38        ''      => 0,
39        'MUHAR' => 1,
40        'SAFAR' => 2,
41        'RABIA' => 3,
42        'RABIT' => 4,
43        'JUMAA' => 5,
44        'JUMAT' => 6,
45        'RAJAB' => 7,
46        'SHAAB' => 8,
47        'RAMAD' => 9,
48        'SHAWW' => 10,
49        'DHUAQ' => 11,
50        'DHUAH' => 12,
51    ];
52
53    /**
54     * Create a date from either:
55     * a Julian day number
56     * day/month/year strings from a GEDCOM date
57     * another CalendarDate object
58     *
59     * @param array<string>|int|AbstractCalendarDate $date
60     */
61    public function __construct($date)
62    {
63        $this->calendar = new ArabicCalendar();
64        parent::__construct($date);
65    }
66
67    /**
68     * Full month name in nominative case.
69     *
70     * @param int  $month
71     * @param bool $leap_year Some calendars use leap months
72     *
73     * @return string
74     */
75    protected function monthNameNominativeCase(int $month, bool $leap_year): string
76    {
77        static $translated_month_names;
78
79        if ($translated_month_names === null) {
80            $translated_month_names = [
81                0  => '',
82                /* I18N: https://en.wikipedia.org/wiki/Muharram */
83                1  => I18N::translateContext('NOMINATIVE', 'Muharram'),
84                /* I18N: https://en.wikipedia.org/wiki/Safar */
85                2  => I18N::translateContext('NOMINATIVE', 'Safar'),
86                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
87                3  => I18N::translateContext('NOMINATIVE', 'Rabi’ al-awwal'),
88                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
89                4  => I18N::translateContext('NOMINATIVE', 'Rabi’ al-thani'),
90                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
91                5  => I18N::translateContext('NOMINATIVE', 'Jumada al-awwal'),
92                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
93                6  => I18N::translateContext('NOMINATIVE', 'Jumada al-thani'),
94                /* I18N: https://en.wikipedia.org/wiki/Rajab */
95                7  => I18N::translateContext('NOMINATIVE', 'Rajab'),
96                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
97                8  => I18N::translateContext('NOMINATIVE', 'Sha’aban'),
98                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
99                9  => I18N::translateContext('NOMINATIVE', 'Ramadan'),
100                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
101                10 => I18N::translateContext('NOMINATIVE', 'Shawwal'),
102                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
103                11 => I18N::translateContext('NOMINATIVE', 'Dhu al-Qi’dah'),
104                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
105                12 => I18N::translateContext('NOMINATIVE', 'Dhu al-Hijjah'),
106            ];
107        }
108
109        return $translated_month_names[$month];
110    }
111
112    /**
113     * Full month name in genitive case.
114     *
115     * @param int  $month
116     * @param bool $leap_year Some calendars use leap months
117     *
118     * @return string
119     */
120    protected function monthNameGenitiveCase(int $month, bool $leap_year): string
121    {
122        static $translated_month_names;
123
124        if ($translated_month_names === null) {
125            $translated_month_names = [
126                0  => '',
127                /* I18N: https://en.wikipedia.org/wiki/Muharram */
128                1  => I18N::translateContext('GENITIVE', 'Muharram'),
129                /* I18N: https://en.wikipedia.org/wiki/Safar */
130                2  => I18N::translateContext('GENITIVE', 'Safar'),
131                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
132                3  => I18N::translateContext('GENITIVE', 'Rabi’ al-awwal'),
133                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
134                4  => I18N::translateContext('GENITIVE', 'Rabi’ al-thani'),
135                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
136                5  => I18N::translateContext('GENITIVE', 'Jumada al-awwal'),
137                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
138                6  => I18N::translateContext('GENITIVE', 'Jumada al-thani'),
139                /* I18N: https://en.wikipedia.org/wiki/Rajab */
140                7  => I18N::translateContext('GENITIVE', 'Rajab'),
141                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
142                8  => I18N::translateContext('GENITIVE', 'Sha’aban'),
143                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
144                9  => I18N::translateContext('GENITIVE', 'Ramadan'),
145                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
146                10 => I18N::translateContext('GENITIVE', 'Shawwal'),
147                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
148                11 => I18N::translateContext('GENITIVE', 'Dhu al-Qi’dah'),
149                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
150                12 => I18N::translateContext('GENITIVE', 'Dhu al-Hijjah'),
151            ];
152        }
153
154        return $translated_month_names[$month];
155    }
156
157    /**
158     * Full month name in locative case.
159     *
160     * @param int  $month
161     * @param bool $leap_year Some calendars use leap months
162     *
163     * @return string
164     */
165    protected function monthNameLocativeCase(int $month, bool $leap_year): string
166    {
167        static $translated_month_names;
168
169        if ($translated_month_names === null) {
170            $translated_month_names = [
171                0  => '',
172                /* I18N: https://en.wikipedia.org/wiki/Muharram */
173                1  => I18N::translateContext('LOCATIVE', 'Muharram'),
174                /* I18N: https://en.wikipedia.org/wiki/Safar */
175                2  => I18N::translateContext('LOCATIVE', 'Safar'),
176                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
177                3  => I18N::translateContext('LOCATIVE', 'Rabi’ al-awwal'),
178                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
179                4  => I18N::translateContext('LOCATIVE', 'Rabi’ al-thani'),
180                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
181                5  => I18N::translateContext('LOCATIVE', 'Jumada al-awwal'),
182                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
183                6  => I18N::translateContext('LOCATIVE', 'Jumada al-thani'),
184                /* I18N: https://en.wikipedia.org/wiki/Rajab */
185                7  => I18N::translateContext('LOCATIVE', 'Rajab'),
186                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
187                8  => I18N::translateContext('LOCATIVE', 'Sha’aban'),
188                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
189                9  => I18N::translateContext('LOCATIVE', 'Ramadan'),
190                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
191                10 => I18N::translateContext('LOCATIVE', 'Shawwal'),
192                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
193                11 => I18N::translateContext('LOCATIVE', 'Dhu al-Qi’dah'),
194                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
195                12 => I18N::translateContext('LOCATIVE', 'Dhu al-Hijjah'),
196            ];
197        }
198
199        return $translated_month_names[$month];
200    }
201
202    /**
203     * Full month name in instrumental case.
204     *
205     * @param int  $month
206     * @param bool $leap_year Some calendars use leap months
207     *
208     * @return string
209     */
210    protected function monthNameInstrumentalCase(int $month, bool $leap_year): string
211    {
212        static $translated_month_names;
213
214        if ($translated_month_names === null) {
215            $translated_month_names = [
216                0  => '',
217                /* I18N: https://en.wikipedia.org/wiki/Muharram */
218                1  => I18N::translateContext('INSTRUMENTAL', 'Muharram'),
219                /* I18N: https://en.wikipedia.org/wiki/Safar */
220                2  => I18N::translateContext('INSTRUMENTAL', 'Safar'),
221                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
222                3  => I18N::translateContext('INSTRUMENTAL', 'Rabi’ al-awwal'),
223                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
224                4  => I18N::translateContext('INSTRUMENTAL', 'Rabi’ al-thani'),
225                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
226                5  => I18N::translateContext('INSTRUMENTAL', 'Jumada al-awwal'),
227                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
228                6  => I18N::translateContext('INSTRUMENTAL', 'Jumada al-thani'),
229                /* I18N: https://en.wikipedia.org/wiki/Rajab */
230                7  => I18N::translateContext('INSTRUMENTAL', 'Rajab'),
231                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
232                8  => I18N::translateContext('INSTRUMENTAL', 'Sha’aban'),
233                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
234                9  => I18N::translateContext('INSTRUMENTAL', 'Ramadan'),
235                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
236                10 => I18N::translateContext('INSTRUMENTAL', 'Shawwal'),
237                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
238                11 => I18N::translateContext('INSTRUMENTAL', 'Dhu al-Qi’dah'),
239                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
240                12 => I18N::translateContext('INSTRUMENTAL', 'Dhu al-Hijjah'),
241            ];
242        }
243
244        return $translated_month_names[$month];
245    }
246
247    /**
248     * Abbreviated month name
249     *
250     * @param int  $month
251     * @param bool $leap_year Some calendars use leap months
252     *
253     * @return string
254     */
255    protected function monthNameAbbreviated(int $month, bool $leap_year): string
256    {
257        return $this->monthNameNominativeCase($month, $leap_year);
258    }
259}
260