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 */ 16e7f56f2aSGreg Roachdeclare(strict_types=1); 17e7f56f2aSGreg Roach 1876692c8bSGreg Roachnamespace Fisharebest\Webtrees\Date; 19a25f0a04SGreg Roach 20a25f0a04SGreg Roachuse Fisharebest\ExtCalendar\JewishCalendar; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 22a25f0a04SGreg Roach 23a25f0a04SGreg Roach/** 2476692c8bSGreg Roach * Definitions for the Jewish calendar 25a25f0a04SGreg Roach */ 26*4a83f5d7SGreg Roachclass JewishDate extends AbstractCalendarDate 27c1010edaSGreg Roach{ 28*4a83f5d7SGreg Roach // GEDCOM calendar escape 29*4a83f5d7SGreg Roach const ESCAPE = '@#DHEBREW@'; 30*4a83f5d7SGreg Roach 3152348eb8SGreg Roach // Convert GEDCOM month names to month numbers 3252348eb8SGreg Roach const MONTH_ABBREVIATIONS = [ 33c1010edaSGreg Roach '' => 0, 34c1010edaSGreg Roach 'TSH' => 1, 35c1010edaSGreg Roach 'CSH' => 2, 36c1010edaSGreg Roach 'KSL' => 3, 37c1010edaSGreg Roach 'TVT' => 4, 38c1010edaSGreg Roach 'SHV' => 5, 39c1010edaSGreg Roach 'ADR' => 6, 40c1010edaSGreg Roach 'ADS' => 7, 41c1010edaSGreg Roach 'NSN' => 8, 42c1010edaSGreg Roach 'IYR' => 9, 43c1010edaSGreg Roach 'SVN' => 10, 44c1010edaSGreg Roach 'TMZ' => 11, 45c1010edaSGreg Roach 'AAV' => 12, 46c1010edaSGreg Roach 'ELL' => 13, 47c1010edaSGreg Roach ]; 48a25f0a04SGreg Roach 4976692c8bSGreg Roach /** 5076692c8bSGreg Roach * Create a date from either: 5176692c8bSGreg Roach * a Julian day number 5276692c8bSGreg Roach * day/month/year strings from a GEDCOM date 5376692c8bSGreg Roach * another CalendarDate object 5476692c8bSGreg Roach * 55*4a83f5d7SGreg Roach * @param array|int|AbstractCalendarDate $date 5676692c8bSGreg Roach */ 57c1010edaSGreg Roach public function __construct($date) 58c1010edaSGreg Roach { 5959f2f229SGreg Roach $this->calendar = new JewishCalendar(); 60a25f0a04SGreg Roach parent::__construct($date); 61a25f0a04SGreg Roach } 62a25f0a04SGreg Roach 6376692c8bSGreg Roach /** 6476692c8bSGreg Roach * Generate the %j format for a date. 6576692c8bSGreg Roach * 6676692c8bSGreg Roach * @return string 6776692c8bSGreg Roach */ 68fe11e66dSGreg Roach protected function formatDay(): string 69c1010edaSGreg Roach { 7017920f94SGreg Roach if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') { 71*4a83f5d7SGreg Roach return (new JewishCalendar())->numberToHebrewNumerals($this->day, true); 72a25f0a04SGreg Roach } 73b2ce94c6SRico Sonntag 74b2ce94c6SRico Sonntag return parent::formatDay(); 75a25f0a04SGreg Roach } 76a25f0a04SGreg Roach 7776692c8bSGreg Roach /** 7876692c8bSGreg Roach * Generate the %y format for a date. 7976692c8bSGreg Roach * 8076692c8bSGreg Roach * NOTE Short year is NOT a 2-digit year. It is for calendars such as hebrew 8176692c8bSGreg Roach * which have a 3-digit form of 4-digit years. 8276692c8bSGreg Roach * 8376692c8bSGreg Roach * @return string 8476692c8bSGreg Roach */ 85fe11e66dSGreg Roach protected function formatShortYear(): string 86c1010edaSGreg Roach { 8717920f94SGreg Roach if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') { 88*4a83f5d7SGreg Roach return (new JewishCalendar())->numberToHebrewNumerals($this->year, false); 89a25f0a04SGreg Roach } 90b2ce94c6SRico Sonntag 91b2ce94c6SRico Sonntag return parent::formatLongYear(); 92a25f0a04SGreg Roach } 93a25f0a04SGreg Roach 9476692c8bSGreg Roach /** 9576692c8bSGreg Roach * Generate the %Y format for a date. 9676692c8bSGreg Roach * 9776692c8bSGreg Roach * @return string 9876692c8bSGreg Roach */ 99fe11e66dSGreg Roach protected function formatLongYear(): string 100c1010edaSGreg Roach { 10117920f94SGreg Roach if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') { 102*4a83f5d7SGreg Roach return (new JewishCalendar())->numberToHebrewNumerals($this->year, true); 103a25f0a04SGreg Roach } 104b2ce94c6SRico Sonntag 105b2ce94c6SRico Sonntag return parent::formatLongYear(); 106a25f0a04SGreg Roach } 107a25f0a04SGreg Roach 10876692c8bSGreg Roach /** 10976692c8bSGreg Roach * Full month name in nominative case. 11076692c8bSGreg Roach * 11176692c8bSGreg Roach * @param int $month_number 11276692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 11376692c8bSGreg Roach * 11476692c8bSGreg Roach * @return string 11576692c8bSGreg Roach */ 116220febf9SGreg Roach protected function monthNameNominativeCase(int $month_number, bool $leap_year): string 117c1010edaSGreg Roach { 118a25f0a04SGreg Roach static $translated_month_names; 119a25f0a04SGreg Roach 120a25f0a04SGreg Roach if ($translated_month_names === null) { 12113abd6f3SGreg Roach $translated_month_names = [ 122a25f0a04SGreg Roach 0 => '', 123bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 124bbb76c12SGreg Roach 1 => I18N::translateContext('NOMINATIVE', 'Tishrei'), 125bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 126bbb76c12SGreg Roach 2 => I18N::translateContext('NOMINATIVE', 'Heshvan'), 127bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 128bbb76c12SGreg Roach 3 => I18N::translateContext('NOMINATIVE', 'Kislev'), 129bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 130bbb76c12SGreg Roach 4 => I18N::translateContext('NOMINATIVE', 'Tevet'), 131bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 132bbb76c12SGreg Roach 5 => I18N::translateContext('NOMINATIVE', 'Shevat'), 133bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 134bbb76c12SGreg Roach 6 => I18N::translateContext('NOMINATIVE', 'Adar I'), 135bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 136bbb76c12SGreg Roach 7 => I18N::translateContext('NOMINATIVE', 'Adar'), 137bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 138bbb76c12SGreg Roach -7 => I18N::translateContext('NOMINATIVE', 'Adar II'), 139bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 140bbb76c12SGreg Roach 8 => I18N::translateContext('NOMINATIVE', 'Nissan'), 141bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 142bbb76c12SGreg Roach 9 => I18N::translateContext('NOMINATIVE', 'Iyar'), 143bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 144bbb76c12SGreg Roach 10 => I18N::translateContext('NOMINATIVE', 'Sivan'), 145bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 146bbb76c12SGreg Roach 11 => I18N::translateContext('NOMINATIVE', 'Tamuz'), 147bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 148bbb76c12SGreg Roach 12 => I18N::translateContext('NOMINATIVE', 'Av'), 149bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 150bbb76c12SGreg Roach 13 => I18N::translateContext('NOMINATIVE', 'Elul'), 15113abd6f3SGreg Roach ]; 152a25f0a04SGreg Roach } 153a25f0a04SGreg Roach 154a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 155a25f0a04SGreg Roach return $translated_month_names[-7]; 156a25f0a04SGreg Roach } 157b2ce94c6SRico Sonntag 158b2ce94c6SRico Sonntag return $translated_month_names[$month_number]; 159a25f0a04SGreg Roach } 160a25f0a04SGreg Roach 16176692c8bSGreg Roach /** 16276692c8bSGreg Roach * Full month name in genitive case. 16376692c8bSGreg Roach * 16476692c8bSGreg Roach * @param int $month_number 16576692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 16676692c8bSGreg Roach * 16776692c8bSGreg Roach * @return string 16876692c8bSGreg Roach */ 169fe11e66dSGreg Roach protected function monthNameGenitiveCase(int $month_number, bool $leap_year): string 170c1010edaSGreg Roach { 171a25f0a04SGreg Roach static $translated_month_names; 172a25f0a04SGreg Roach 173a25f0a04SGreg Roach if ($translated_month_names === null) { 17413abd6f3SGreg Roach $translated_month_names = [ 175a25f0a04SGreg Roach 0 => '', 176bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 177bbb76c12SGreg Roach 1 => I18N::translateContext('GENITIVE', 'Tishrei'), 178bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 179bbb76c12SGreg Roach 2 => I18N::translateContext('GENITIVE', 'Heshvan'), 180bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 181bbb76c12SGreg Roach 3 => I18N::translateContext('GENITIVE', 'Kislev'), 182bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 183bbb76c12SGreg Roach 4 => I18N::translateContext('GENITIVE', 'Tevet'), 184bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 185bbb76c12SGreg Roach 5 => I18N::translateContext('GENITIVE', 'Shevat'), 186bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 187bbb76c12SGreg Roach 6 => I18N::translateContext('GENITIVE', 'Adar I'), 188bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 189bbb76c12SGreg Roach 7 => I18N::translateContext('GENITIVE', 'Adar'), 190bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 191bbb76c12SGreg Roach -7 => I18N::translateContext('GENITIVE', 'Adar II'), 192bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 193bbb76c12SGreg Roach 8 => I18N::translateContext('GENITIVE', 'Nissan'), 194bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 195bbb76c12SGreg Roach 9 => I18N::translateContext('GENITIVE', 'Iyar'), 196bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 197bbb76c12SGreg Roach 10 => I18N::translateContext('GENITIVE', 'Sivan'), 198bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 199bbb76c12SGreg Roach 11 => I18N::translateContext('GENITIVE', 'Tamuz'), 200bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 201bbb76c12SGreg Roach 12 => I18N::translateContext('GENITIVE', 'Av'), 202bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 203bbb76c12SGreg Roach 13 => I18N::translateContext('GENITIVE', 'Elul'), 20413abd6f3SGreg Roach ]; 205a25f0a04SGreg Roach } 206a25f0a04SGreg Roach 207a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 208a25f0a04SGreg Roach return $translated_month_names[-7]; 209a25f0a04SGreg Roach } 210b2ce94c6SRico Sonntag 211b2ce94c6SRico Sonntag return $translated_month_names[$month_number]; 212a25f0a04SGreg Roach } 213a25f0a04SGreg Roach 21476692c8bSGreg Roach /** 21576692c8bSGreg Roach * Full month name in locative case. 21676692c8bSGreg Roach * 21776692c8bSGreg Roach * @param int $month_number 21876692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 21976692c8bSGreg Roach * 22076692c8bSGreg Roach * @return string 22176692c8bSGreg Roach */ 222fe11e66dSGreg Roach protected function monthNameLocativeCase(int $month_number, bool $leap_year): string 223c1010edaSGreg Roach { 224a25f0a04SGreg Roach static $translated_month_names; 225a25f0a04SGreg Roach 226a25f0a04SGreg Roach if ($translated_month_names === null) { 22713abd6f3SGreg Roach $translated_month_names = [ 228a25f0a04SGreg Roach 0 => '', 229bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 230bbb76c12SGreg Roach 1 => I18N::translateContext('LOCATIVE', 'Tishrei'), 231bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 232bbb76c12SGreg Roach 2 => I18N::translateContext('LOCATIVE', 'Heshvan'), 233bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 234bbb76c12SGreg Roach 3 => I18N::translateContext('LOCATIVE', 'Kislev'), 235bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 236bbb76c12SGreg Roach 4 => I18N::translateContext('LOCATIVE', 'Tevet'), 237bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 238bbb76c12SGreg Roach 5 => I18N::translateContext('LOCATIVE', 'Shevat'), 239bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 240bbb76c12SGreg Roach 6 => I18N::translateContext('LOCATIVE', 'Adar I'), 241bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 242bbb76c12SGreg Roach 7 => I18N::translateContext('LOCATIVE', 'Adar'), 243bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 244bbb76c12SGreg Roach -7 => I18N::translateContext('LOCATIVE', 'Adar II'), 245bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 246bbb76c12SGreg Roach 8 => I18N::translateContext('LOCATIVE', 'Nissan'), 247bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 248bbb76c12SGreg Roach 9 => I18N::translateContext('LOCATIVE', 'Iyar'), 249bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 250bbb76c12SGreg Roach 10 => I18N::translateContext('LOCATIVE', 'Sivan'), 251bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 252bbb76c12SGreg Roach 11 => I18N::translateContext('LOCATIVE', 'Tamuz'), 253bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 254bbb76c12SGreg Roach 12 => I18N::translateContext('LOCATIVE', 'Av'), 255bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 256bbb76c12SGreg Roach 13 => I18N::translateContext('LOCATIVE', 'Elul'), 25713abd6f3SGreg Roach ]; 258a25f0a04SGreg Roach } 259a25f0a04SGreg Roach 260a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 261a25f0a04SGreg Roach return $translated_month_names[-7]; 262a25f0a04SGreg Roach } 263b2ce94c6SRico Sonntag 264b2ce94c6SRico Sonntag return $translated_month_names[$month_number]; 265a25f0a04SGreg Roach } 266a25f0a04SGreg Roach 26776692c8bSGreg Roach /** 26876692c8bSGreg Roach * Full month name in instrumental case. 26976692c8bSGreg Roach * 27076692c8bSGreg Roach * @param int $month_number 27176692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 27276692c8bSGreg Roach * 27376692c8bSGreg Roach * @return string 27476692c8bSGreg Roach */ 275fe11e66dSGreg Roach protected function monthNameInstrumentalCase(int $month_number, bool $leap_year): string 276c1010edaSGreg Roach { 277a25f0a04SGreg Roach static $translated_month_names; 278a25f0a04SGreg Roach 279a25f0a04SGreg Roach if ($translated_month_names === null) { 28013abd6f3SGreg Roach $translated_month_names = [ 281a25f0a04SGreg Roach 0 => '', 282bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 283bbb76c12SGreg Roach 1 => I18N::translateContext('INSTRUMENTAL', 'Tishrei'), 284bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 285bbb76c12SGreg Roach 2 => I18N::translateContext('INSTRUMENTAL', 'Heshvan'), 286bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 287bbb76c12SGreg Roach 3 => I18N::translateContext('INSTRUMENTAL', 'Kislev'), 288bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 289bbb76c12SGreg Roach 4 => I18N::translateContext('INSTRUMENTAL', 'Tevet'), 290bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 291bbb76c12SGreg Roach 5 => I18N::translateContext('INSTRUMENTAL', 'Shevat'), 292bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 293bbb76c12SGreg Roach 6 => I18N::translateContext('INSTRUMENTAL', 'Adar I'), 294bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 295bbb76c12SGreg Roach 7 => I18N::translateContext('INSTRUMENTAL', 'Adar'), 296bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 297bbb76c12SGreg Roach -7 => I18N::translateContext('INSTRUMENTAL', 'Adar II'), 298bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 299bbb76c12SGreg Roach 8 => I18N::translateContext('INSTRUMENTAL', 'Nissan'), 300bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 301bbb76c12SGreg Roach 9 => I18N::translateContext('INSTRUMENTAL', 'Iyar'), 302bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 303bbb76c12SGreg Roach 10 => I18N::translateContext('INSTRUMENTAL', 'Sivan'), 304bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 305bbb76c12SGreg Roach 11 => I18N::translateContext('INSTRUMENTAL', 'Tamuz'), 306bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 307bbb76c12SGreg Roach 12 => I18N::translateContext('INSTRUMENTAL', 'Av'), 308bbb76c12SGreg Roach /* I18N: a month in the Jewish calendar */ 309bbb76c12SGreg Roach 13 => I18N::translateContext('INSTRUMENTAL', 'Elul'), 31013abd6f3SGreg Roach ]; 311a25f0a04SGreg Roach } 312a25f0a04SGreg Roach 313a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 314a25f0a04SGreg Roach return $translated_month_names[-7]; 315a25f0a04SGreg Roach } 316b2ce94c6SRico Sonntag 317b2ce94c6SRico Sonntag return $translated_month_names[$month_number]; 318a25f0a04SGreg Roach } 319a25f0a04SGreg Roach 32076692c8bSGreg Roach /** 32176692c8bSGreg Roach * Abbreviated month name 32276692c8bSGreg Roach * 32376692c8bSGreg Roach * @param int $month_number 32476692c8bSGreg Roach * @param bool $leap_year Some calendars use leap months 32576692c8bSGreg Roach * 32676692c8bSGreg Roach * @return string 32776692c8bSGreg Roach */ 328fe11e66dSGreg Roach protected function monthNameAbbreviated(int $month_number, bool $leap_year): string 329c1010edaSGreg Roach { 33040c81a71SGreg Roach return $this->monthNameNominativeCase($month_number, $leap_year); 331a25f0a04SGreg Roach } 332a25f0a04SGreg Roach 33376692c8bSGreg Roach /** 33476692c8bSGreg Roach * Which months follows this one? Calendars with leap-months should provide their own implementation. 33576692c8bSGreg Roach * 336e2052359SGreg Roach * @return int[] 33776692c8bSGreg Roach */ 338fe11e66dSGreg Roach protected function nextMonth(): array 339c1010edaSGreg Roach { 340*4a83f5d7SGreg Roach if ($this->month == 6 && !$this->isLeapYear()) { 341c1010edaSGreg Roach return [ 342*4a83f5d7SGreg Roach $this->year, 343c1010edaSGreg Roach 8, 344c1010edaSGreg Roach ]; 345b2ce94c6SRico Sonntag } 346b2ce94c6SRico Sonntag 347c1010edaSGreg Roach return [ 348*4a83f5d7SGreg Roach $this->year + ($this->month == 13 ? 1 : 0), 349*4a83f5d7SGreg Roach ($this->month % 13) + 1, 350c1010edaSGreg Roach ]; 351a25f0a04SGreg Roach } 352a25f0a04SGreg Roach} 353