xref: /webtrees/app/Date/JewishDate.php (revision 220febf96a8c962107632f2cb1da280ff17fa093)
1a25f0a04SGreg Roach<?php
2a25f0a04SGreg Roach/**
3a25f0a04SGreg Roach * webtrees: online genealogy
41062a142SGreg Roach * Copyright (C) 2018 webtrees development team
5a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
6a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
7a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
8a25f0a04SGreg Roach * (at your option) any later version.
9a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
10a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
11a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12a25f0a04SGreg Roach * GNU General Public License for more details.
13a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
14a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
15a25f0a04SGreg Roach */
1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Date;
17a25f0a04SGreg Roach
18a25f0a04SGreg Roachuse Fisharebest\ExtCalendar\JewishCalendar;
190e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
20a25f0a04SGreg Roach
21a25f0a04SGreg Roach/**
2276692c8bSGreg Roach * Definitions for the Jewish calendar
23a25f0a04SGreg Roach */
24c1010edaSGreg Roachclass JewishDate extends CalendarDate
25c1010edaSGreg Roach{
26e2052359SGreg Roach    /** @var int[] Convert GEDCOM month names to month numbers */
27c1010edaSGreg Roach    public static $MONTH_ABBREV = [
28c1010edaSGreg Roach        ''    => 0,
29c1010edaSGreg Roach        'TSH' => 1,
30c1010edaSGreg Roach        'CSH' => 2,
31c1010edaSGreg Roach        'KSL' => 3,
32c1010edaSGreg Roach        'TVT' => 4,
33c1010edaSGreg Roach        'SHV' => 5,
34c1010edaSGreg Roach        'ADR' => 6,
35c1010edaSGreg Roach        'ADS' => 7,
36c1010edaSGreg Roach        'NSN' => 8,
37c1010edaSGreg Roach        'IYR' => 9,
38c1010edaSGreg Roach        'SVN' => 10,
39c1010edaSGreg Roach        'TMZ' => 11,
40c1010edaSGreg Roach        'AAV' => 12,
41c1010edaSGreg Roach        'ELL' => 13,
42c1010edaSGreg Roach    ];
43a25f0a04SGreg Roach
4476692c8bSGreg Roach    /**
4576692c8bSGreg Roach     * Create a date from either:
4676692c8bSGreg Roach     * a Julian day number
4776692c8bSGreg Roach     * day/month/year strings from a GEDCOM date
4876692c8bSGreg Roach     * another CalendarDate object
4976692c8bSGreg Roach     *
5076692c8bSGreg Roach     * @param array|int|CalendarDate $date
5176692c8bSGreg Roach     */
52c1010edaSGreg Roach    public function __construct($date)
53c1010edaSGreg Roach    {
5459f2f229SGreg Roach        $this->calendar = new JewishCalendar();
55a25f0a04SGreg Roach        parent::__construct($date);
56a25f0a04SGreg Roach    }
57a25f0a04SGreg Roach
5876692c8bSGreg Roach    /**
5976692c8bSGreg Roach     * Generate the %j format for a date.
6076692c8bSGreg Roach     *
6176692c8bSGreg Roach     * @return string
6276692c8bSGreg Roach     */
63fe11e66dSGreg Roach    protected function formatDay(): string
64c1010edaSGreg Roach    {
6517920f94SGreg Roach        if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') {
6659f2f229SGreg Roach            return (new JewishCalendar())->numberToHebrewNumerals($this->d, true);
67a25f0a04SGreg Roach        } else {
68fe11e66dSGreg Roach            return parent::formatDay();
69a25f0a04SGreg Roach        }
70a25f0a04SGreg Roach    }
71a25f0a04SGreg Roach
7276692c8bSGreg Roach    /**
7376692c8bSGreg Roach     * Generate the %y format for a date.
7476692c8bSGreg Roach     *
7576692c8bSGreg Roach     * NOTE Short year is NOT a 2-digit year. It is for calendars such as hebrew
7676692c8bSGreg Roach     * which have a 3-digit form of 4-digit years.
7776692c8bSGreg Roach     *
7876692c8bSGreg Roach     * @return string
7976692c8bSGreg Roach     */
80fe11e66dSGreg Roach    protected function formatShortYear(): string
81c1010edaSGreg Roach    {
8217920f94SGreg Roach        if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') {
8359f2f229SGreg Roach            return (new JewishCalendar())->numberToHebrewNumerals($this->y, false);
84a25f0a04SGreg Roach        } else {
85fe11e66dSGreg Roach            return parent::formatLongYear();
86a25f0a04SGreg Roach        }
87a25f0a04SGreg Roach    }
88a25f0a04SGreg Roach
8976692c8bSGreg Roach    /**
9076692c8bSGreg Roach     * Generate the %Y format for a date.
9176692c8bSGreg Roach     *
9276692c8bSGreg Roach     * @return string
9376692c8bSGreg Roach     */
94fe11e66dSGreg Roach    protected function formatLongYear(): string
95c1010edaSGreg Roach    {
9617920f94SGreg Roach        if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') {
9759f2f229SGreg Roach            return (new JewishCalendar())->numberToHebrewNumerals($this->y, true);
98a25f0a04SGreg Roach        } else {
99fe11e66dSGreg Roach            return parent::formatLongYear();
100a25f0a04SGreg Roach        }
101a25f0a04SGreg Roach    }
102a25f0a04SGreg Roach
10376692c8bSGreg Roach    /**
10476692c8bSGreg Roach     * Full month name in nominative case.
10576692c8bSGreg Roach     *
10676692c8bSGreg Roach     * @param int  $month_number
10776692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
10876692c8bSGreg Roach     *
10976692c8bSGreg Roach     * @return string
11076692c8bSGreg Roach     */
111*220febf9SGreg Roach    protected function monthNameNominativeCase(int $month_number, bool $leap_year): string
112c1010edaSGreg Roach    {
113a25f0a04SGreg Roach        static $translated_month_names;
114a25f0a04SGreg Roach
115a25f0a04SGreg Roach        if ($translated_month_names === null) {
11613abd6f3SGreg Roach            $translated_month_names = [
117a25f0a04SGreg Roach                0  => '',
118bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
119bbb76c12SGreg Roach                1  => I18N::translateContext('NOMINATIVE', 'Tishrei'),
120bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
121bbb76c12SGreg Roach                2  => I18N::translateContext('NOMINATIVE', 'Heshvan'),
122bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
123bbb76c12SGreg Roach                3  => I18N::translateContext('NOMINATIVE', 'Kislev'),
124bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
125bbb76c12SGreg Roach                4  => I18N::translateContext('NOMINATIVE', 'Tevet'),
126bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
127bbb76c12SGreg Roach                5  => I18N::translateContext('NOMINATIVE', 'Shevat'),
128bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
129bbb76c12SGreg Roach                6  => I18N::translateContext('NOMINATIVE', 'Adar I'),
130bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
131bbb76c12SGreg Roach                7  => I18N::translateContext('NOMINATIVE', 'Adar'),
132bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
133bbb76c12SGreg Roach                -7 => I18N::translateContext('NOMINATIVE', 'Adar II'),
134bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
135bbb76c12SGreg Roach                8  => I18N::translateContext('NOMINATIVE', 'Nissan'),
136bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
137bbb76c12SGreg Roach                9  => I18N::translateContext('NOMINATIVE', 'Iyar'),
138bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
139bbb76c12SGreg Roach                10 => I18N::translateContext('NOMINATIVE', 'Sivan'),
140bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
141bbb76c12SGreg Roach                11 => I18N::translateContext('NOMINATIVE', 'Tamuz'),
142bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
143bbb76c12SGreg Roach                12 => I18N::translateContext('NOMINATIVE', 'Av'),
144bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
145bbb76c12SGreg Roach                13 => I18N::translateContext('NOMINATIVE', 'Elul'),
14613abd6f3SGreg Roach            ];
147a25f0a04SGreg Roach        }
148a25f0a04SGreg Roach
149a25f0a04SGreg Roach        if ($month_number === 7 && $leap_year) {
150a25f0a04SGreg Roach            return $translated_month_names[-7];
151a25f0a04SGreg Roach        } else {
152a25f0a04SGreg Roach            return $translated_month_names[$month_number];
153a25f0a04SGreg Roach        }
154a25f0a04SGreg Roach    }
155a25f0a04SGreg Roach
15676692c8bSGreg Roach    /**
15776692c8bSGreg Roach     * Full month name in genitive case.
15876692c8bSGreg Roach     *
15976692c8bSGreg Roach     * @param int  $month_number
16076692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
16176692c8bSGreg Roach     *
16276692c8bSGreg Roach     * @return string
16376692c8bSGreg Roach     */
164fe11e66dSGreg Roach    protected function monthNameGenitiveCase(int $month_number, bool $leap_year): string
165c1010edaSGreg Roach    {
166a25f0a04SGreg Roach        static $translated_month_names;
167a25f0a04SGreg Roach
168a25f0a04SGreg Roach        if ($translated_month_names === null) {
16913abd6f3SGreg Roach            $translated_month_names = [
170a25f0a04SGreg Roach                0  => '',
171bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
172bbb76c12SGreg Roach                1  => I18N::translateContext('GENITIVE', 'Tishrei'),
173bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
174bbb76c12SGreg Roach                2  => I18N::translateContext('GENITIVE', 'Heshvan'),
175bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
176bbb76c12SGreg Roach                3  => I18N::translateContext('GENITIVE', 'Kislev'),
177bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
178bbb76c12SGreg Roach                4  => I18N::translateContext('GENITIVE', 'Tevet'),
179bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
180bbb76c12SGreg Roach                5  => I18N::translateContext('GENITIVE', 'Shevat'),
181bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
182bbb76c12SGreg Roach                6  => I18N::translateContext('GENITIVE', 'Adar I'),
183bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
184bbb76c12SGreg Roach                7  => I18N::translateContext('GENITIVE', 'Adar'),
185bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
186bbb76c12SGreg Roach                -7 => I18N::translateContext('GENITIVE', 'Adar II'),
187bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
188bbb76c12SGreg Roach                8  => I18N::translateContext('GENITIVE', 'Nissan'),
189bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
190bbb76c12SGreg Roach                9  => I18N::translateContext('GENITIVE', 'Iyar'),
191bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
192bbb76c12SGreg Roach                10 => I18N::translateContext('GENITIVE', 'Sivan'),
193bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
194bbb76c12SGreg Roach                11 => I18N::translateContext('GENITIVE', 'Tamuz'),
195bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
196bbb76c12SGreg Roach                12 => I18N::translateContext('GENITIVE', 'Av'),
197bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
198bbb76c12SGreg Roach                13 => I18N::translateContext('GENITIVE', 'Elul'),
19913abd6f3SGreg Roach            ];
200a25f0a04SGreg Roach        }
201a25f0a04SGreg Roach
202a25f0a04SGreg Roach        if ($month_number === 7 && $leap_year) {
203a25f0a04SGreg Roach            return $translated_month_names[-7];
204a25f0a04SGreg Roach        } else {
205a25f0a04SGreg Roach            return $translated_month_names[$month_number];
206a25f0a04SGreg Roach        }
207a25f0a04SGreg Roach    }
208a25f0a04SGreg Roach
20976692c8bSGreg Roach    /**
21076692c8bSGreg Roach     * Full month name in locative case.
21176692c8bSGreg Roach     *
21276692c8bSGreg Roach     * @param int  $month_number
21376692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
21476692c8bSGreg Roach     *
21576692c8bSGreg Roach     * @return string
21676692c8bSGreg Roach     */
217fe11e66dSGreg Roach    protected function monthNameLocativeCase(int $month_number, bool $leap_year): string
218c1010edaSGreg Roach    {
219a25f0a04SGreg Roach        static $translated_month_names;
220a25f0a04SGreg Roach
221a25f0a04SGreg Roach        if ($translated_month_names === null) {
22213abd6f3SGreg Roach            $translated_month_names = [
223a25f0a04SGreg Roach                0  => '',
224bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
225bbb76c12SGreg Roach                1  => I18N::translateContext('LOCATIVE', 'Tishrei'),
226bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
227bbb76c12SGreg Roach                2  => I18N::translateContext('LOCATIVE', 'Heshvan'),
228bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
229bbb76c12SGreg Roach                3  => I18N::translateContext('LOCATIVE', 'Kislev'),
230bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
231bbb76c12SGreg Roach                4  => I18N::translateContext('LOCATIVE', 'Tevet'),
232bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
233bbb76c12SGreg Roach                5  => I18N::translateContext('LOCATIVE', 'Shevat'),
234bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
235bbb76c12SGreg Roach                6  => I18N::translateContext('LOCATIVE', 'Adar I'),
236bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
237bbb76c12SGreg Roach                7  => I18N::translateContext('LOCATIVE', 'Adar'),
238bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
239bbb76c12SGreg Roach                -7 => I18N::translateContext('LOCATIVE', 'Adar II'),
240bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
241bbb76c12SGreg Roach                8  => I18N::translateContext('LOCATIVE', 'Nissan'),
242bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
243bbb76c12SGreg Roach                9  => I18N::translateContext('LOCATIVE', 'Iyar'),
244bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
245bbb76c12SGreg Roach                10 => I18N::translateContext('LOCATIVE', 'Sivan'),
246bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
247bbb76c12SGreg Roach                11 => I18N::translateContext('LOCATIVE', 'Tamuz'),
248bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
249bbb76c12SGreg Roach                12 => I18N::translateContext('LOCATIVE', 'Av'),
250bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
251bbb76c12SGreg Roach                13 => I18N::translateContext('LOCATIVE', 'Elul'),
25213abd6f3SGreg Roach            ];
253a25f0a04SGreg Roach        }
254a25f0a04SGreg Roach
255a25f0a04SGreg Roach        if ($month_number === 7 && $leap_year) {
256a25f0a04SGreg Roach            return $translated_month_names[-7];
257a25f0a04SGreg Roach        } else {
258a25f0a04SGreg Roach            return $translated_month_names[$month_number];
259a25f0a04SGreg Roach        }
260a25f0a04SGreg Roach    }
261a25f0a04SGreg Roach
26276692c8bSGreg Roach    /**
26376692c8bSGreg Roach     * Full month name in instrumental case.
26476692c8bSGreg Roach     *
26576692c8bSGreg Roach     * @param int  $month_number
26676692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
26776692c8bSGreg Roach     *
26876692c8bSGreg Roach     * @return string
26976692c8bSGreg Roach     */
270fe11e66dSGreg Roach    protected function monthNameInstrumentalCase(int $month_number, bool $leap_year): string
271c1010edaSGreg Roach    {
272a25f0a04SGreg Roach        static $translated_month_names;
273a25f0a04SGreg Roach
274a25f0a04SGreg Roach        if ($translated_month_names === null) {
27513abd6f3SGreg Roach            $translated_month_names = [
276a25f0a04SGreg Roach                0  => '',
277bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
278bbb76c12SGreg Roach                1  => I18N::translateContext('INSTRUMENTAL', 'Tishrei'),
279bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
280bbb76c12SGreg Roach                2  => I18N::translateContext('INSTRUMENTAL', 'Heshvan'),
281bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
282bbb76c12SGreg Roach                3  => I18N::translateContext('INSTRUMENTAL', 'Kislev'),
283bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
284bbb76c12SGreg Roach                4  => I18N::translateContext('INSTRUMENTAL', 'Tevet'),
285bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
286bbb76c12SGreg Roach                5  => I18N::translateContext('INSTRUMENTAL', 'Shevat'),
287bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
288bbb76c12SGreg Roach                6  => I18N::translateContext('INSTRUMENTAL', 'Adar I'),
289bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
290bbb76c12SGreg Roach                7  => I18N::translateContext('INSTRUMENTAL', 'Adar'),
291bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
292bbb76c12SGreg Roach                -7 => I18N::translateContext('INSTRUMENTAL', 'Adar II'),
293bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
294bbb76c12SGreg Roach                8  => I18N::translateContext('INSTRUMENTAL', 'Nissan'),
295bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
296bbb76c12SGreg Roach                9  => I18N::translateContext('INSTRUMENTAL', 'Iyar'),
297bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
298bbb76c12SGreg Roach                10 => I18N::translateContext('INSTRUMENTAL', 'Sivan'),
299bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
300bbb76c12SGreg Roach                11 => I18N::translateContext('INSTRUMENTAL', 'Tamuz'),
301bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
302bbb76c12SGreg Roach                12 => I18N::translateContext('INSTRUMENTAL', 'Av'),
303bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
304bbb76c12SGreg Roach                13 => I18N::translateContext('INSTRUMENTAL', 'Elul'),
30513abd6f3SGreg Roach            ];
306a25f0a04SGreg Roach        }
307a25f0a04SGreg Roach
308a25f0a04SGreg Roach        if ($month_number === 7 && $leap_year) {
309a25f0a04SGreg Roach            return $translated_month_names[-7];
310a25f0a04SGreg Roach        } else {
311a25f0a04SGreg Roach            return $translated_month_names[$month_number];
312a25f0a04SGreg Roach        }
313a25f0a04SGreg Roach    }
314a25f0a04SGreg Roach
31576692c8bSGreg Roach    /**
31676692c8bSGreg Roach     * Abbreviated month name
31776692c8bSGreg Roach     *
31876692c8bSGreg Roach     * @param int  $month_number
31976692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
32076692c8bSGreg Roach     *
32176692c8bSGreg Roach     * @return string
32276692c8bSGreg Roach     */
323fe11e66dSGreg Roach    protected function monthNameAbbreviated(int $month_number, bool $leap_year): string
324c1010edaSGreg Roach    {
325a25f0a04SGreg Roach        return self::monthNameNominativeCase($month_number, $leap_year);
326a25f0a04SGreg Roach    }
327a25f0a04SGreg Roach
32876692c8bSGreg Roach    /**
32976692c8bSGreg Roach     * Which months follows this one? Calendars with leap-months should provide their own implementation.
33076692c8bSGreg Roach     *
331e2052359SGreg Roach     * @return int[]
33276692c8bSGreg Roach     */
333fe11e66dSGreg Roach    protected function nextMonth(): array
334c1010edaSGreg Roach    {
335a25f0a04SGreg Roach        if ($this->m == 6 && !$this->isLeapYear()) {
336c1010edaSGreg Roach            return [
337c1010edaSGreg Roach                $this->y,
338c1010edaSGreg Roach                8,
339c1010edaSGreg Roach            ];
340a25f0a04SGreg Roach        } else {
341c1010edaSGreg Roach            return [
342c1010edaSGreg Roach                $this->y + ($this->m == 13 ? 1 : 0),
343c1010edaSGreg Roach                ($this->m % 13) + 1,
344c1010edaSGreg Roach            ];
345a25f0a04SGreg Roach        }
346a25f0a04SGreg Roach    }
347a25f0a04SGreg Roach}
348