xref: /webtrees/app/Date/HijriDate.php (revision d11be7027e34e3121be11cc025421873364403f9)
1a25f0a04SGreg Roach<?php
23976b470SGreg Roach
3a25f0a04SGreg Roach/**
4a25f0a04SGreg Roach * webtrees: online genealogy
5*d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
6a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
7a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
8a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
9a25f0a04SGreg Roach * (at your option) any later version.
10a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
11a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13a25f0a04SGreg Roach * GNU General Public License for more details.
14a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
16a25f0a04SGreg Roach */
17fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Date;
21a25f0a04SGreg Roach
22a25f0a04SGreg Roachuse Fisharebest\ExtCalendar\ArabicCalendar;
230e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
24a25f0a04SGreg Roach
25a25f0a04SGreg Roach/**
264a83f5d7SGreg Roach * Definitions for Hijri dates.
27a25f0a04SGreg Roach *
28a25f0a04SGreg Roach * Note that these are "theoretical" dates.
29a25f0a04SGreg Roach * "True" dates are based on local lunar observations, and can be a +/- one day.
30a25f0a04SGreg Roach */
314a83f5d7SGreg Roachclass HijriDate extends AbstractCalendarDate
32c1010edaSGreg Roach{
334a83f5d7SGreg Roach    // GEDCOM calendar escape
3416d6367aSGreg Roach    public const ESCAPE = '@#DHIJRI@';
354a83f5d7SGreg Roach
3652348eb8SGreg Roach    // Convert GEDCOM month names to month numbers
37d4ec5ec0SGreg Roach    protected const MONTH_TO_NUMBER = [
38c1010edaSGreg Roach        'MUHAR' => 1,
39c1010edaSGreg Roach        'SAFAR' => 2,
40c1010edaSGreg Roach        'RABIA' => 3,
41c1010edaSGreg Roach        'RABIT' => 4,
42c1010edaSGreg Roach        'JUMAA' => 5,
43c1010edaSGreg Roach        'JUMAT' => 6,
44c1010edaSGreg Roach        'RAJAB' => 7,
45c1010edaSGreg Roach        'SHAAB' => 8,
46c1010edaSGreg Roach        'RAMAD' => 9,
47c1010edaSGreg Roach        'SHAWW' => 10,
48c1010edaSGreg Roach        'DHUAQ' => 11,
49c1010edaSGreg Roach        'DHUAH' => 12,
50c1010edaSGreg Roach    ];
51a25f0a04SGreg Roach
52d8809d62SGreg Roach    protected const NUMBER_TO_MONTH = [
53d8809d62SGreg Roach        1  => 'MUHAR',
54d8809d62SGreg Roach        2  => 'SAFAR',
55d8809d62SGreg Roach        3  => 'RABIA',
56d8809d62SGreg Roach        4  => 'RABIT',
57d8809d62SGreg Roach        5  => 'JUMAA',
58d8809d62SGreg Roach        6  => 'JUMAT',
59d8809d62SGreg Roach        7  => 'RAJAB',
60d8809d62SGreg Roach        8  => 'SHAAB',
61d8809d62SGreg Roach        9  => 'RAMAD',
62d8809d62SGreg Roach        10 => 'SHAWW',
63d8809d62SGreg Roach        11 => 'DHUAQ',
64d8809d62SGreg Roach        12 => 'DHUAH',
65d8809d62SGreg Roach    ];
66d8809d62SGreg Roach
6776692c8bSGreg Roach    /**
6876692c8bSGreg Roach     * Create a date from either:
6976692c8bSGreg Roach     * a Julian day number
7076692c8bSGreg Roach     * day/month/year strings from a GEDCOM date
7176692c8bSGreg Roach     * another CalendarDate object
7276692c8bSGreg Roach     *
73f4c767fdSGreg Roach     * @param array<string>|int|AbstractCalendarDate $date
7476692c8bSGreg Roach     */
75c1010edaSGreg Roach    public function __construct($date)
76c1010edaSGreg Roach    {
7759f2f229SGreg Roach        $this->calendar = new ArabicCalendar();
78a25f0a04SGreg Roach        parent::__construct($date);
79a25f0a04SGreg Roach    }
80a25f0a04SGreg Roach
8176692c8bSGreg Roach    /**
8276692c8bSGreg Roach     * Full month name in nominative case.
8376692c8bSGreg Roach     *
847bb2eb25SGreg Roach     * @param int  $month
8576692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
8676692c8bSGreg Roach     *
8776692c8bSGreg Roach     * @return string
8876692c8bSGreg Roach     */
897bb2eb25SGreg Roach    protected function monthNameNominativeCase(int $month, bool $leap_year): string
90c1010edaSGreg Roach    {
91a25f0a04SGreg Roach        static $translated_month_names;
92a25f0a04SGreg Roach
93a25f0a04SGreg Roach        if ($translated_month_names === null) {
9413abd6f3SGreg Roach            $translated_month_names = [
95a25f0a04SGreg Roach                0  => '',
96ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Muharram */
97bbb76c12SGreg Roach                1  => I18N::translateContext('NOMINATIVE', 'Muharram'),
98ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Safar */
99bbb76c12SGreg Roach                2  => I18N::translateContext('NOMINATIVE', 'Safar'),
100ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
101bbb76c12SGreg Roach                3  => I18N::translateContext('NOMINATIVE', 'Rabi’ al-awwal'),
102ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
103bbb76c12SGreg Roach                4  => I18N::translateContext('NOMINATIVE', 'Rabi’ al-thani'),
104ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
105bbb76c12SGreg Roach                5  => I18N::translateContext('NOMINATIVE', 'Jumada al-awwal'),
106ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
107bbb76c12SGreg Roach                6  => I18N::translateContext('NOMINATIVE', 'Jumada al-thani'),
108ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rajab */
109bbb76c12SGreg Roach                7  => I18N::translateContext('NOMINATIVE', 'Rajab'),
110ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
111bbb76c12SGreg Roach                8  => I18N::translateContext('NOMINATIVE', 'Sha’aban'),
112ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
113bbb76c12SGreg Roach                9  => I18N::translateContext('NOMINATIVE', 'Ramadan'),
114ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
115bbb76c12SGreg Roach                10 => I18N::translateContext('NOMINATIVE', 'Shawwal'),
116ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
117bbb76c12SGreg Roach                11 => I18N::translateContext('NOMINATIVE', 'Dhu al-Qi’dah'),
118ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
119bbb76c12SGreg Roach                12 => I18N::translateContext('NOMINATIVE', 'Dhu al-Hijjah'),
12013abd6f3SGreg Roach            ];
121a25f0a04SGreg Roach        }
122a25f0a04SGreg Roach
1237bb2eb25SGreg Roach        return $translated_month_names[$month];
124a25f0a04SGreg Roach    }
125a25f0a04SGreg Roach
12676692c8bSGreg Roach    /**
12776692c8bSGreg Roach     * Full month name in genitive case.
12876692c8bSGreg Roach     *
1297bb2eb25SGreg Roach     * @param int  $month
13076692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
13176692c8bSGreg Roach     *
13276692c8bSGreg Roach     * @return string
13376692c8bSGreg Roach     */
1347bb2eb25SGreg Roach    protected function monthNameGenitiveCase(int $month, bool $leap_year): string
135c1010edaSGreg Roach    {
136a25f0a04SGreg Roach        static $translated_month_names;
137a25f0a04SGreg Roach
138a25f0a04SGreg Roach        if ($translated_month_names === null) {
13913abd6f3SGreg Roach            $translated_month_names = [
140a25f0a04SGreg Roach                0  => '',
141ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Muharram */
142bbb76c12SGreg Roach                1  => I18N::translateContext('GENITIVE', 'Muharram'),
143ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Safar */
144bbb76c12SGreg Roach                2  => I18N::translateContext('GENITIVE', 'Safar'),
145ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
146bbb76c12SGreg Roach                3  => I18N::translateContext('GENITIVE', 'Rabi’ al-awwal'),
147ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
148bbb76c12SGreg Roach                4  => I18N::translateContext('GENITIVE', 'Rabi’ al-thani'),
149ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
150bbb76c12SGreg Roach                5  => I18N::translateContext('GENITIVE', 'Jumada al-awwal'),
151ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
152bbb76c12SGreg Roach                6  => I18N::translateContext('GENITIVE', 'Jumada al-thani'),
153ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rajab */
154bbb76c12SGreg Roach                7  => I18N::translateContext('GENITIVE', 'Rajab'),
155ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
156bbb76c12SGreg Roach                8  => I18N::translateContext('GENITIVE', 'Sha’aban'),
157ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
158bbb76c12SGreg Roach                9  => I18N::translateContext('GENITIVE', 'Ramadan'),
159ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
160bbb76c12SGreg Roach                10 => I18N::translateContext('GENITIVE', 'Shawwal'),
161ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
162bbb76c12SGreg Roach                11 => I18N::translateContext('GENITIVE', 'Dhu al-Qi’dah'),
163ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
164bbb76c12SGreg Roach                12 => I18N::translateContext('GENITIVE', 'Dhu al-Hijjah'),
16513abd6f3SGreg Roach            ];
166a25f0a04SGreg Roach        }
167a25f0a04SGreg Roach
1687bb2eb25SGreg Roach        return $translated_month_names[$month];
169a25f0a04SGreg Roach    }
170a25f0a04SGreg Roach
17176692c8bSGreg Roach    /**
17276692c8bSGreg Roach     * Full month name in locative case.
17376692c8bSGreg Roach     *
1747bb2eb25SGreg Roach     * @param int  $month
17576692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
17676692c8bSGreg Roach     *
17776692c8bSGreg Roach     * @return string
17876692c8bSGreg Roach     */
1797bb2eb25SGreg Roach    protected function monthNameLocativeCase(int $month, bool $leap_year): string
180c1010edaSGreg Roach    {
181a25f0a04SGreg Roach        static $translated_month_names;
182a25f0a04SGreg Roach
183a25f0a04SGreg Roach        if ($translated_month_names === null) {
18413abd6f3SGreg Roach            $translated_month_names = [
185a25f0a04SGreg Roach                0  => '',
186ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Muharram */
187bbb76c12SGreg Roach                1  => I18N::translateContext('LOCATIVE', 'Muharram'),
188ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Safar */
189bbb76c12SGreg Roach                2  => I18N::translateContext('LOCATIVE', 'Safar'),
190ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
191bbb76c12SGreg Roach                3  => I18N::translateContext('LOCATIVE', 'Rabi’ al-awwal'),
192ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
193bbb76c12SGreg Roach                4  => I18N::translateContext('LOCATIVE', 'Rabi’ al-thani'),
194ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
195bbb76c12SGreg Roach                5  => I18N::translateContext('LOCATIVE', 'Jumada al-awwal'),
196ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
197bbb76c12SGreg Roach                6  => I18N::translateContext('LOCATIVE', 'Jumada al-thani'),
198ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rajab */
199bbb76c12SGreg Roach                7  => I18N::translateContext('LOCATIVE', 'Rajab'),
200ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
201bbb76c12SGreg Roach                8  => I18N::translateContext('LOCATIVE', 'Sha’aban'),
202ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
203bbb76c12SGreg Roach                9  => I18N::translateContext('LOCATIVE', 'Ramadan'),
204ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
205bbb76c12SGreg Roach                10 => I18N::translateContext('LOCATIVE', 'Shawwal'),
206ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
207bbb76c12SGreg Roach                11 => I18N::translateContext('LOCATIVE', 'Dhu al-Qi’dah'),
208ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
209bbb76c12SGreg Roach                12 => I18N::translateContext('LOCATIVE', 'Dhu al-Hijjah'),
21013abd6f3SGreg Roach            ];
211a25f0a04SGreg Roach        }
212a25f0a04SGreg Roach
2137bb2eb25SGreg Roach        return $translated_month_names[$month];
214a25f0a04SGreg Roach    }
215a25f0a04SGreg Roach
21676692c8bSGreg Roach    /**
21776692c8bSGreg Roach     * Full month name in instrumental case.
21876692c8bSGreg Roach     *
2197bb2eb25SGreg Roach     * @param int  $month
22076692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
22176692c8bSGreg Roach     *
22276692c8bSGreg Roach     * @return string
22376692c8bSGreg Roach     */
2247bb2eb25SGreg Roach    protected function monthNameInstrumentalCase(int $month, bool $leap_year): string
225c1010edaSGreg Roach    {
226a25f0a04SGreg Roach        static $translated_month_names;
227a25f0a04SGreg Roach
228a25f0a04SGreg Roach        if ($translated_month_names === null) {
22913abd6f3SGreg Roach            $translated_month_names = [
230a25f0a04SGreg Roach                0  => '',
231ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Muharram */
232bbb76c12SGreg Roach                1  => I18N::translateContext('INSTRUMENTAL', 'Muharram'),
233ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Safar */
234bbb76c12SGreg Roach                2  => I18N::translateContext('INSTRUMENTAL', 'Safar'),
235ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */
236bbb76c12SGreg Roach                3  => I18N::translateContext('INSTRUMENTAL', 'Rabi’ al-awwal'),
237ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */
238bbb76c12SGreg Roach                4  => I18N::translateContext('INSTRUMENTAL', 'Rabi’ al-thani'),
239ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */
240bbb76c12SGreg Roach                5  => I18N::translateContext('INSTRUMENTAL', 'Jumada al-awwal'),
241ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */
242bbb76c12SGreg Roach                6  => I18N::translateContext('INSTRUMENTAL', 'Jumada al-thani'),
243ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Rajab */
244bbb76c12SGreg Roach                7  => I18N::translateContext('INSTRUMENTAL', 'Rajab'),
245ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */
246bbb76c12SGreg Roach                8  => I18N::translateContext('INSTRUMENTAL', 'Sha’aban'),
247ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */
248bbb76c12SGreg Roach                9  => I18N::translateContext('INSTRUMENTAL', 'Ramadan'),
249ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Shawwal */
250bbb76c12SGreg Roach                10 => I18N::translateContext('INSTRUMENTAL', 'Shawwal'),
251ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */
252bbb76c12SGreg Roach                11 => I18N::translateContext('INSTRUMENTAL', 'Dhu al-Qi’dah'),
253ad3143ccSGreg Roach                /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */
254bbb76c12SGreg Roach                12 => I18N::translateContext('INSTRUMENTAL', 'Dhu al-Hijjah'),
25513abd6f3SGreg Roach            ];
256a25f0a04SGreg Roach        }
257a25f0a04SGreg Roach
2587bb2eb25SGreg Roach        return $translated_month_names[$month];
259a25f0a04SGreg Roach    }
260a25f0a04SGreg Roach
26176692c8bSGreg Roach    /**
26276692c8bSGreg Roach     * Abbreviated month name
26376692c8bSGreg Roach     *
2647bb2eb25SGreg Roach     * @param int  $month
26576692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
26676692c8bSGreg Roach     *
26776692c8bSGreg Roach     * @return string
26876692c8bSGreg Roach     */
2697bb2eb25SGreg Roach    protected function monthNameAbbreviated(int $month, bool $leap_year): string
270c1010edaSGreg Roach    {
2717bb2eb25SGreg Roach        return $this->monthNameNominativeCase($month, $leap_year);
272a25f0a04SGreg Roach    }
273a25f0a04SGreg Roach}
274