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\JewishCalendar; 230e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 24a25f0a04SGreg Roach 25a25f0a04SGreg Roach/** 2676692c8bSGreg Roach * Definitions for the Jewish calendar 27a25f0a04SGreg Roach */ 284a83f5d7SGreg Roachclass JewishDate extends AbstractCalendarDate 29c1010edaSGreg Roach{ 304a83f5d7SGreg Roach // GEDCOM calendar escape 3116d6367aSGreg Roach public const ESCAPE = '@#DHEBREW@'; 324a83f5d7SGreg Roach 3352348eb8SGreg Roach // Convert GEDCOM month names to month numbers 34d8809d62SGreg Roach protected const MONTH_TO_NUMBER = [ 35c1010edaSGreg Roach 'TSH' => 1, 36c1010edaSGreg Roach 'CSH' => 2, 37c1010edaSGreg Roach 'KSL' => 3, 38c1010edaSGreg Roach 'TVT' => 4, 39c1010edaSGreg Roach 'SHV' => 5, 40c1010edaSGreg Roach 'ADR' => 6, 41c1010edaSGreg Roach 'ADS' => 7, 42c1010edaSGreg Roach 'NSN' => 8, 43c1010edaSGreg Roach 'IYR' => 9, 44c1010edaSGreg Roach 'SVN' => 10, 45c1010edaSGreg Roach 'TMZ' => 11, 46c1010edaSGreg Roach 'AAV' => 12, 47c1010edaSGreg Roach 'ELL' => 13, 48c1010edaSGreg Roach ]; 49a25f0a04SGreg Roach 50d8809d62SGreg Roach protected const NUMBER_TO_MONTH = [ 51d8809d62SGreg Roach 1 => 'TSH', 52d8809d62SGreg Roach 2 => 'CSH', 53d8809d62SGreg Roach 3 => 'KSL', 54d8809d62SGreg Roach 4 => 'TVT', 55d8809d62SGreg Roach 5 => 'SHV', 56d8809d62SGreg Roach 6 => 'ADR', 57d8809d62SGreg Roach 7 => 'ADS', 58d8809d62SGreg Roach 8 => 'NSN', 59d8809d62SGreg Roach 9 => 'IYR', 60d8809d62SGreg Roach 10 => 'SVN', 61d8809d62SGreg Roach 11 => 'TMZ', 62d8809d62SGreg Roach 12 => 'AAV', 63d8809d62SGreg Roach 13 => 'ELL', 64d8809d62SGreg Roach ]; 65d8809d62SGreg Roach 6676692c8bSGreg Roach /** 6776692c8bSGreg Roach * Create a date from either: 6876692c8bSGreg Roach * a Julian day number 6976692c8bSGreg Roach * day/month/year strings from a GEDCOM date 7076692c8bSGreg Roach * another CalendarDate object 7176692c8bSGreg Roach * 72f4c767fdSGreg Roach * @param array<string>|int|AbstractCalendarDate $date 7376692c8bSGreg Roach */ 74c1010edaSGreg Roach public function __construct($date) 75c1010edaSGreg Roach { 7659f2f229SGreg Roach $this->calendar = new JewishCalendar(); 77a25f0a04SGreg Roach parent::__construct($date); 78a25f0a04SGreg Roach } 79a25f0a04SGreg Roach 8076692c8bSGreg Roach /** 8176692c8bSGreg Roach * Generate the %j format for a date. 8276692c8bSGreg Roach * 8376692c8bSGreg Roach * @return string 8476692c8bSGreg Roach */ 85fe11e66dSGreg Roach protected function formatDay(): string 86c1010edaSGreg Roach { 8765cf5706SGreg Roach if (I18N::locale()->script()->code() === 'Hebr') { 884a83f5d7SGreg Roach return (new JewishCalendar())->numberToHebrewNumerals($this->day, true); 89a25f0a04SGreg Roach } 90b2ce94c6SRico Sonntag 91b2ce94c6SRico Sonntag return parent::formatDay(); 92a25f0a04SGreg Roach } 93a25f0a04SGreg Roach 9476692c8bSGreg Roach /** 9576692c8bSGreg Roach * Generate the %y format for a date. 9676692c8bSGreg Roach * 9776692c8bSGreg Roach * NOTE Short year is NOT a 2-digit year. It is for calendars such as hebrew 9876692c8bSGreg Roach * which have a 3-digit form of 4-digit years. 9976692c8bSGreg Roach * 10076692c8bSGreg Roach * @return string 10176692c8bSGreg Roach */ 102fe11e66dSGreg Roach protected function formatShortYear(): string 103c1010edaSGreg Roach { 10465cf5706SGreg Roach if (I18N::locale()->script()->code() === 'Hebr') { 1054a83f5d7SGreg Roach return (new JewishCalendar())->numberToHebrewNumerals($this->year, false); 106a25f0a04SGreg Roach } 107b2ce94c6SRico Sonntag 108b2ce94c6SRico Sonntag return parent::formatLongYear(); 109a25f0a04SGreg Roach } 110a25f0a04SGreg Roach 11176692c8bSGreg Roach /** 11276692c8bSGreg Roach * Generate the %Y format for a date. 11376692c8bSGreg Roach * 11476692c8bSGreg Roach * @return string 11576692c8bSGreg Roach */ 116fe11e66dSGreg Roach protected function formatLongYear(): string 117c1010edaSGreg Roach { 11865cf5706SGreg Roach if (I18N::locale()->script()->code() === 'Hebr') { 1194a83f5d7SGreg Roach return (new JewishCalendar())->numberToHebrewNumerals($this->year, true); 120a25f0a04SGreg Roach } 121b2ce94c6SRico Sonntag 122b2ce94c6SRico Sonntag return parent::formatLongYear(); 123a25f0a04SGreg Roach } 124a25f0a04SGreg Roach 12576692c8bSGreg Roach /** 12676692c8bSGreg Roach * Full month name in nominative case. 12776692c8bSGreg Roach * 1287bb2eb25SGreg Roach * @param int $month 12976692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 13076692c8bSGreg Roach * 13176692c8bSGreg Roach * @return string 13276692c8bSGreg Roach */ 1337bb2eb25SGreg Roach protected function monthNameNominativeCase(int $month, bool $leap_year): string 134c1010edaSGreg Roach { 135a25f0a04SGreg Roach static $translated_month_names; 136a25f0a04SGreg Roach 137a25f0a04SGreg Roach if ($translated_month_names === null) { 13813abd6f3SGreg Roach $translated_month_names = [ 139a25f0a04SGreg Roach 0 => '', 140bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 141bbb76c12SGreg Roach 1 => I18N::translateContext('NOMINATIVE', 'Tishrei'), 142bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 143bbb76c12SGreg Roach 2 => I18N::translateContext('NOMINATIVE', 'Heshvan'), 144bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 145bbb76c12SGreg Roach 3 => I18N::translateContext('NOMINATIVE', 'Kislev'), 146bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 147bbb76c12SGreg Roach 4 => I18N::translateContext('NOMINATIVE', 'Tevet'), 148bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 149bbb76c12SGreg Roach 5 => I18N::translateContext('NOMINATIVE', 'Shevat'), 150bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 151bbb76c12SGreg Roach 6 => I18N::translateContext('NOMINATIVE', 'Adar I'), 152bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 153bbb76c12SGreg Roach 7 => I18N::translateContext('NOMINATIVE', 'Adar'), 154bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 155bbb76c12SGreg Roach 8 => I18N::translateContext('NOMINATIVE', 'Nissan'), 156bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 157bbb76c12SGreg Roach 9 => I18N::translateContext('NOMINATIVE', 'Iyar'), 158bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 159bbb76c12SGreg Roach 10 => I18N::translateContext('NOMINATIVE', 'Sivan'), 160bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 161bbb76c12SGreg Roach 11 => I18N::translateContext('NOMINATIVE', 'Tamuz'), 162bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 163bbb76c12SGreg Roach 12 => I18N::translateContext('NOMINATIVE', 'Av'), 164bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 165bbb76c12SGreg Roach 13 => I18N::translateContext('NOMINATIVE', 'Elul'), 16613abd6f3SGreg Roach ]; 167a25f0a04SGreg Roach } 168a25f0a04SGreg Roach 1697bb2eb25SGreg Roach if ($month === 7 && $leap_year) { 1700e2e57bdSGreg Roach /* I18N: a month in the Jewish calendar */ 1710e2e57bdSGreg Roach return I18N::translateContext('NOMINATIVE', 'Adar II'); 172a25f0a04SGreg Roach } 173b2ce94c6SRico Sonntag 1747bb2eb25SGreg Roach return $translated_month_names[$month]; 175a25f0a04SGreg Roach } 176a25f0a04SGreg Roach 17776692c8bSGreg Roach /** 17876692c8bSGreg Roach * Full month name in genitive case. 17976692c8bSGreg Roach * 1807bb2eb25SGreg Roach * @param int $month 18176692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 18276692c8bSGreg Roach * 18376692c8bSGreg Roach * @return string 18476692c8bSGreg Roach */ 1857bb2eb25SGreg Roach protected function monthNameGenitiveCase(int $month, bool $leap_year): string 186c1010edaSGreg Roach { 187a25f0a04SGreg Roach static $translated_month_names; 188a25f0a04SGreg Roach 189a25f0a04SGreg Roach if ($translated_month_names === null) { 19013abd6f3SGreg Roach $translated_month_names = [ 191a25f0a04SGreg Roach 0 => '', 192bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 193bbb76c12SGreg Roach 1 => I18N::translateContext('GENITIVE', 'Tishrei'), 194bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 195bbb76c12SGreg Roach 2 => I18N::translateContext('GENITIVE', 'Heshvan'), 196bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 197bbb76c12SGreg Roach 3 => I18N::translateContext('GENITIVE', 'Kislev'), 198bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 199bbb76c12SGreg Roach 4 => I18N::translateContext('GENITIVE', 'Tevet'), 200bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 201bbb76c12SGreg Roach 5 => I18N::translateContext('GENITIVE', 'Shevat'), 202bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 203bbb76c12SGreg Roach 6 => I18N::translateContext('GENITIVE', 'Adar I'), 204bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 205bbb76c12SGreg Roach 7 => I18N::translateContext('GENITIVE', 'Adar'), 206bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 207bbb76c12SGreg Roach 8 => I18N::translateContext('GENITIVE', 'Nissan'), 208bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 209bbb76c12SGreg Roach 9 => I18N::translateContext('GENITIVE', 'Iyar'), 210bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 211bbb76c12SGreg Roach 10 => I18N::translateContext('GENITIVE', 'Sivan'), 212bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 213bbb76c12SGreg Roach 11 => I18N::translateContext('GENITIVE', 'Tamuz'), 214bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 215bbb76c12SGreg Roach 12 => I18N::translateContext('GENITIVE', 'Av'), 216bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 217bbb76c12SGreg Roach 13 => I18N::translateContext('GENITIVE', 'Elul'), 21813abd6f3SGreg Roach ]; 219a25f0a04SGreg Roach } 220a25f0a04SGreg Roach 2217bb2eb25SGreg Roach if ($month === 7 && $leap_year) { 2220e2e57bdSGreg Roach /* I18N: a month in the Jewish calendar */ 2230e2e57bdSGreg Roach return I18N::translateContext('GENITIVE', 'Adar II'); 224a25f0a04SGreg Roach } 225b2ce94c6SRico Sonntag 2267bb2eb25SGreg Roach return $translated_month_names[$month]; 227a25f0a04SGreg Roach } 228a25f0a04SGreg Roach 22976692c8bSGreg Roach /** 23076692c8bSGreg Roach * Full month name in locative case. 23176692c8bSGreg Roach * 2327bb2eb25SGreg Roach * @param int $month 23376692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 23476692c8bSGreg Roach * 23576692c8bSGreg Roach * @return string 23676692c8bSGreg Roach */ 2377bb2eb25SGreg Roach protected function monthNameLocativeCase(int $month, bool $leap_year): string 238c1010edaSGreg Roach { 239a25f0a04SGreg Roach static $translated_month_names; 240a25f0a04SGreg Roach 241a25f0a04SGreg Roach if ($translated_month_names === null) { 24213abd6f3SGreg Roach $translated_month_names = [ 243a25f0a04SGreg Roach 0 => '', 244bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 245bbb76c12SGreg Roach 1 => I18N::translateContext('LOCATIVE', 'Tishrei'), 246bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 247bbb76c12SGreg Roach 2 => I18N::translateContext('LOCATIVE', 'Heshvan'), 248bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 249bbb76c12SGreg Roach 3 => I18N::translateContext('LOCATIVE', 'Kislev'), 250bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 251bbb76c12SGreg Roach 4 => I18N::translateContext('LOCATIVE', 'Tevet'), 252bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 253bbb76c12SGreg Roach 5 => I18N::translateContext('LOCATIVE', 'Shevat'), 254bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 255bbb76c12SGreg Roach 6 => I18N::translateContext('LOCATIVE', 'Adar I'), 256bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 257bbb76c12SGreg Roach 7 => I18N::translateContext('LOCATIVE', 'Adar'), 258bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 259bbb76c12SGreg Roach 8 => I18N::translateContext('LOCATIVE', 'Nissan'), 260bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 261bbb76c12SGreg Roach 9 => I18N::translateContext('LOCATIVE', 'Iyar'), 262bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 263bbb76c12SGreg Roach 10 => I18N::translateContext('LOCATIVE', 'Sivan'), 264bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 265bbb76c12SGreg Roach 11 => I18N::translateContext('LOCATIVE', 'Tamuz'), 266bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 267bbb76c12SGreg Roach 12 => I18N::translateContext('LOCATIVE', 'Av'), 268bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 269bbb76c12SGreg Roach 13 => I18N::translateContext('LOCATIVE', 'Elul'), 27013abd6f3SGreg Roach ]; 271a25f0a04SGreg Roach } 272a25f0a04SGreg Roach 2737bb2eb25SGreg Roach if ($month === 7 && $leap_year) { 2740e2e57bdSGreg Roach /* I18N: a month in the Jewish calendar */ 27549e00872SGreg Roach return I18N::translateContext('LOCATIVE', 'Adar II'); 276a25f0a04SGreg Roach } 277b2ce94c6SRico Sonntag 2787bb2eb25SGreg Roach return $translated_month_names[$month]; 279a25f0a04SGreg Roach } 280a25f0a04SGreg Roach 28176692c8bSGreg Roach /** 28276692c8bSGreg Roach * Full month name in instrumental case. 28376692c8bSGreg Roach * 2847bb2eb25SGreg Roach * @param int $month 28576692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 28676692c8bSGreg Roach * 28776692c8bSGreg Roach * @return string 28876692c8bSGreg Roach */ 2897bb2eb25SGreg Roach protected function monthNameInstrumentalCase(int $month, bool $leap_year): string 290c1010edaSGreg Roach { 291a25f0a04SGreg Roach static $translated_month_names; 292a25f0a04SGreg Roach 293a25f0a04SGreg Roach if ($translated_month_names === null) { 29413abd6f3SGreg Roach $translated_month_names = [ 295a25f0a04SGreg Roach 0 => '', 296bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 297bbb76c12SGreg Roach 1 => I18N::translateContext('INSTRUMENTAL', 'Tishrei'), 298bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 299bbb76c12SGreg Roach 2 => I18N::translateContext('INSTRUMENTAL', 'Heshvan'), 300bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 301bbb76c12SGreg Roach 3 => I18N::translateContext('INSTRUMENTAL', 'Kislev'), 302bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 303bbb76c12SGreg Roach 4 => I18N::translateContext('INSTRUMENTAL', 'Tevet'), 304bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 305bbb76c12SGreg Roach 5 => I18N::translateContext('INSTRUMENTAL', 'Shevat'), 306bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 307bbb76c12SGreg Roach 6 => I18N::translateContext('INSTRUMENTAL', 'Adar I'), 308bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 309bbb76c12SGreg Roach 7 => I18N::translateContext('INSTRUMENTAL', 'Adar'), 310bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 311bbb76c12SGreg Roach 8 => I18N::translateContext('INSTRUMENTAL', 'Nissan'), 312bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 313bbb76c12SGreg Roach 9 => I18N::translateContext('INSTRUMENTAL', 'Iyar'), 314bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 315bbb76c12SGreg Roach 10 => I18N::translateContext('INSTRUMENTAL', 'Sivan'), 316bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 317bbb76c12SGreg Roach 11 => I18N::translateContext('INSTRUMENTAL', 'Tamuz'), 318bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 319bbb76c12SGreg Roach 12 => I18N::translateContext('INSTRUMENTAL', 'Av'), 320bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 321bbb76c12SGreg Roach 13 => I18N::translateContext('INSTRUMENTAL', 'Elul'), 32213abd6f3SGreg Roach ]; 323a25f0a04SGreg Roach } 324a25f0a04SGreg Roach 3257bb2eb25SGreg Roach if ($month === 7 && $leap_year) { 3260e2e57bdSGreg Roach /* I18N: a month in the Jewish calendar */ 3270e2e57bdSGreg Roach return I18N::translateContext('INSTRUMENTAL', 'Adar II'); 328a25f0a04SGreg Roach } 329b2ce94c6SRico Sonntag 3307bb2eb25SGreg Roach return $translated_month_names[$month]; 331a25f0a04SGreg Roach } 332a25f0a04SGreg Roach 33376692c8bSGreg Roach /** 33476692c8bSGreg Roach * Abbreviated month name 33576692c8bSGreg Roach * 3367bb2eb25SGreg Roach * @param int $month 33776692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 33876692c8bSGreg Roach * 33976692c8bSGreg Roach * @return string 34076692c8bSGreg Roach */ 3417bb2eb25SGreg Roach protected function monthNameAbbreviated(int $month, bool $leap_year): string 342c1010edaSGreg Roach { 3437bb2eb25SGreg Roach return $this->monthNameNominativeCase($month, $leap_year); 344a25f0a04SGreg Roach } 345a25f0a04SGreg Roach 34676692c8bSGreg Roach /** 34776692c8bSGreg Roach * Which months follows this one? Calendars with leap-months should provide their own implementation. 34876692c8bSGreg Roach * 34909482a55SGreg Roach * @return array<int> 35076692c8bSGreg Roach */ 351fe11e66dSGreg Roach protected function nextMonth(): array 352c1010edaSGreg Roach { 353e364afe4SGreg Roach if ($this->month === 6 && !$this->isLeapYear()) { 354c1010edaSGreg Roach return [ 3554a83f5d7SGreg Roach $this->year, 356c1010edaSGreg Roach 8, 357c1010edaSGreg Roach ]; 358b2ce94c6SRico Sonntag } 359b2ce94c6SRico Sonntag 360c1010edaSGreg Roach return [ 361e364afe4SGreg Roach $this->year + ($this->month === 13 ? 1 : 0), 3620e2e57bdSGreg Roach $this->month % 13 + 1, 363c1010edaSGreg Roach ]; 364a25f0a04SGreg Roach } 365a25f0a04SGreg Roach} 366