1*a25f0a04SGreg Roach<?php 2*a25f0a04SGreg Roachnamespace Webtrees; 3*a25f0a04SGreg Roach 4*a25f0a04SGreg Roach/** 5*a25f0a04SGreg Roach * webtrees: online genealogy 6*a25f0a04SGreg Roach * Copyright (C) 2015 webtrees development team 7*a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify 8*a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by 9*a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or 10*a25f0a04SGreg Roach * (at your option) any later version. 11*a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful, 12*a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*a25f0a04SGreg Roach * GNU General Public License for more details. 15*a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License 16*a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 17*a25f0a04SGreg Roach */ 18*a25f0a04SGreg Roach 19*a25f0a04SGreg Roachuse Fisharebest\ExtCalendar\JewishCalendar; 20*a25f0a04SGreg Roach 21*a25f0a04SGreg Roach/** 22*a25f0a04SGreg Roach * Class JewishDate - Definitions for the Jewish calendar 23*a25f0a04SGreg Roach */ 24*a25f0a04SGreg Roachclass JewishDate extends CalendarDate { 25*a25f0a04SGreg Roach const CALENDAR_ESCAPE = '@#DHEBREW@'; 26*a25f0a04SGreg Roach const MONTHS_IN_YEAR = 13; 27*a25f0a04SGreg Roach const CAL_START_JD = 347998; // 01 TSH 0001 = @#JULIAN@ 7 OCT 3761B.C. 28*a25f0a04SGreg Roach const GERSHAYIM = '״'; 29*a25f0a04SGreg Roach const GERSH = '׳'; 30*a25f0a04SGreg Roach const ALAFIM = 'אלפים'; 31*a25f0a04SGreg Roach 32*a25f0a04SGreg Roach /** {@inheritdoc} */ 33*a25f0a04SGreg Roach public static $MONTH_ABBREV = array('' => 0, 'TSH' => 1, 'CSH' => 2, 'KSL' => 3, 'TVT' => 4, 'SHV' => 5, 'ADR' => 6, 'ADS' => 7, 'NSN' => 8, 'IYR' => 9, 'SVN' => 10, 'TMZ' => 11, 'AAV' => 12, 'ELL' => 13); 34*a25f0a04SGreg Roach 35*a25f0a04SGreg Roach /** {@inheritdoc} */ 36*a25f0a04SGreg Roach public function __construct($date) { 37*a25f0a04SGreg Roach $this->calendar = new JewishCalendar; 38*a25f0a04SGreg Roach parent::__construct($date); 39*a25f0a04SGreg Roach } 40*a25f0a04SGreg Roach 41*a25f0a04SGreg Roach /** {@inheritdoc} */ 42*a25f0a04SGreg Roach public static function calendarName() { 43*a25f0a04SGreg Roach return /* I18N: The Hebrew/Jewish calendar */ 44*a25f0a04SGreg Roach I18N::translate('Jewish'); 45*a25f0a04SGreg Roach } 46*a25f0a04SGreg Roach 47*a25f0a04SGreg Roach /** {@inheritdoc} */ 48*a25f0a04SGreg Roach function formatDayZeros() { 49*a25f0a04SGreg Roach if (WT_LOCALE == 'he') { 50*a25f0a04SGreg Roach return $this->numberToHebrewNumerals($this->d); 51*a25f0a04SGreg Roach } else { 52*a25f0a04SGreg Roach return $this->d; 53*a25f0a04SGreg Roach } 54*a25f0a04SGreg Roach } 55*a25f0a04SGreg Roach 56*a25f0a04SGreg Roach /** {@inheritdoc} */ 57*a25f0a04SGreg Roach function formatDay() { 58*a25f0a04SGreg Roach if (WT_LOCALE == 'he') { 59*a25f0a04SGreg Roach return $this->numberToHebrewNumerals($this->d); 60*a25f0a04SGreg Roach } else { 61*a25f0a04SGreg Roach return $this->d; 62*a25f0a04SGreg Roach } 63*a25f0a04SGreg Roach } 64*a25f0a04SGreg Roach 65*a25f0a04SGreg Roach /** {@inheritdoc} */ 66*a25f0a04SGreg Roach function formatShortYear() { 67*a25f0a04SGreg Roach if (WT_LOCALE == 'he') { 68*a25f0a04SGreg Roach return $this->numberToHebrewNumerals($this->y % 1000); 69*a25f0a04SGreg Roach } else { 70*a25f0a04SGreg Roach return $this->y; 71*a25f0a04SGreg Roach } 72*a25f0a04SGreg Roach } 73*a25f0a04SGreg Roach 74*a25f0a04SGreg Roach /** {@inheritdoc} */ 75*a25f0a04SGreg Roach function formatLongYear() { 76*a25f0a04SGreg Roach if (WT_LOCALE == 'he') { 77*a25f0a04SGreg Roach return $this->numberToHebrewNumerals($this->y); 78*a25f0a04SGreg Roach } else { 79*a25f0a04SGreg Roach return $this->y; 80*a25f0a04SGreg Roach } 81*a25f0a04SGreg Roach } 82*a25f0a04SGreg Roach 83*a25f0a04SGreg Roach /** {@inheritdoc} */ 84*a25f0a04SGreg Roach public static function monthNameNominativeCase($month_number, $leap_year) { 85*a25f0a04SGreg Roach static $translated_month_names; 86*a25f0a04SGreg Roach 87*a25f0a04SGreg Roach if ($translated_month_names === null) { 88*a25f0a04SGreg Roach $translated_month_names = array( 89*a25f0a04SGreg Roach 0 => '', 90*a25f0a04SGreg Roach 1 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Tishrei'), 91*a25f0a04SGreg Roach 2 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Heshvan'), 92*a25f0a04SGreg Roach 3 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Kislev'), 93*a25f0a04SGreg Roach 4 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Tevet'), 94*a25f0a04SGreg Roach 5 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Shevat'), 95*a25f0a04SGreg Roach 6 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Adar I'), 96*a25f0a04SGreg Roach 7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Adar'), 97*a25f0a04SGreg Roach -7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Adar II'), 98*a25f0a04SGreg Roach 8 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Nissan'), 99*a25f0a04SGreg Roach 9 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Iyar'), 100*a25f0a04SGreg Roach 10 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Sivan'), 101*a25f0a04SGreg Roach 11 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Tamuz'), 102*a25f0a04SGreg Roach 12 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Av'), 103*a25f0a04SGreg Roach 13 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('NOMINATIVE', 'Elul'), 104*a25f0a04SGreg Roach ); 105*a25f0a04SGreg Roach } 106*a25f0a04SGreg Roach 107*a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 108*a25f0a04SGreg Roach return $translated_month_names[-7]; 109*a25f0a04SGreg Roach } else { 110*a25f0a04SGreg Roach return $translated_month_names[$month_number]; 111*a25f0a04SGreg Roach } 112*a25f0a04SGreg Roach } 113*a25f0a04SGreg Roach 114*a25f0a04SGreg Roach /** {@inheritdoc} */ 115*a25f0a04SGreg Roach static function monthNameGenitiveCase($month_number, $leap_year) { 116*a25f0a04SGreg Roach static $translated_month_names; 117*a25f0a04SGreg Roach 118*a25f0a04SGreg Roach if ($translated_month_names === null) { 119*a25f0a04SGreg Roach $translated_month_names = array( 120*a25f0a04SGreg Roach 0 => '', 121*a25f0a04SGreg Roach 1 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Tishrei'), 122*a25f0a04SGreg Roach 2 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Heshvan'), 123*a25f0a04SGreg Roach 3 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Kislev'), 124*a25f0a04SGreg Roach 4 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Tevet'), 125*a25f0a04SGreg Roach 5 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Shevat'), 126*a25f0a04SGreg Roach 6 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Adar I'), 127*a25f0a04SGreg Roach 7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Adar'), 128*a25f0a04SGreg Roach -7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Adar II'), 129*a25f0a04SGreg Roach 8 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Nissan'), 130*a25f0a04SGreg Roach 9 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Iyar'), 131*a25f0a04SGreg Roach 10 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Sivan'), 132*a25f0a04SGreg Roach 11 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Tamuz'), 133*a25f0a04SGreg Roach 12 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Av'), 134*a25f0a04SGreg Roach 13 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('GENITIVE', 'Elul'), 135*a25f0a04SGreg Roach ); 136*a25f0a04SGreg Roach } 137*a25f0a04SGreg Roach 138*a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 139*a25f0a04SGreg Roach return $translated_month_names[-7]; 140*a25f0a04SGreg Roach } else { 141*a25f0a04SGreg Roach return $translated_month_names[$month_number]; 142*a25f0a04SGreg Roach } 143*a25f0a04SGreg Roach } 144*a25f0a04SGreg Roach 145*a25f0a04SGreg Roach /** {@inheritdoc} */ 146*a25f0a04SGreg Roach protected static function monthNameLocativeCase($month_number, $leap_year) { 147*a25f0a04SGreg Roach static $translated_month_names; 148*a25f0a04SGreg Roach 149*a25f0a04SGreg Roach if ($translated_month_names === null) { 150*a25f0a04SGreg Roach $translated_month_names = array( 151*a25f0a04SGreg Roach 0 => '', 152*a25f0a04SGreg Roach 1 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Tishrei'), 153*a25f0a04SGreg Roach 2 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Heshvan'), 154*a25f0a04SGreg Roach 3 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Kislev'), 155*a25f0a04SGreg Roach 4 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Tevet'), 156*a25f0a04SGreg Roach 5 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Shevat'), 157*a25f0a04SGreg Roach 6 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Adar I'), 158*a25f0a04SGreg Roach 7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Adar'), 159*a25f0a04SGreg Roach -7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Adar II'), 160*a25f0a04SGreg Roach 8 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Nissan'), 161*a25f0a04SGreg Roach 9 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Iyar'), 162*a25f0a04SGreg Roach 10 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Sivan'), 163*a25f0a04SGreg Roach 11 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Tamuz'), 164*a25f0a04SGreg Roach 12 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Av'), 165*a25f0a04SGreg Roach 13 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('LOCATIVE', 'Elul'), 166*a25f0a04SGreg Roach ); 167*a25f0a04SGreg Roach } 168*a25f0a04SGreg Roach 169*a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 170*a25f0a04SGreg Roach return $translated_month_names[-7]; 171*a25f0a04SGreg Roach } else { 172*a25f0a04SGreg Roach return $translated_month_names[$month_number]; 173*a25f0a04SGreg Roach } 174*a25f0a04SGreg Roach } 175*a25f0a04SGreg Roach 176*a25f0a04SGreg Roach /** {@inheritdoc} */ 177*a25f0a04SGreg Roach protected static function monthNameInstrumentalCase($month_number, $leap_year) { 178*a25f0a04SGreg Roach static $translated_month_names; 179*a25f0a04SGreg Roach 180*a25f0a04SGreg Roach if ($translated_month_names === null) { 181*a25f0a04SGreg Roach $translated_month_names = array( 182*a25f0a04SGreg Roach 0 => '', 183*a25f0a04SGreg Roach 1 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Tishrei'), 184*a25f0a04SGreg Roach 2 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Heshvan'), 185*a25f0a04SGreg Roach 3 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Kislev'), 186*a25f0a04SGreg Roach 4 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Tevet'), 187*a25f0a04SGreg Roach 5 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Shevat'), 188*a25f0a04SGreg Roach 6 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Adar I'), 189*a25f0a04SGreg Roach 7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Adar'), 190*a25f0a04SGreg Roach -7 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Adar II'), 191*a25f0a04SGreg Roach 8 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Nissan'), 192*a25f0a04SGreg Roach 9 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Iyar'), 193*a25f0a04SGreg Roach 10 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Sivan'), 194*a25f0a04SGreg Roach 11 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Tamuz'), 195*a25f0a04SGreg Roach 12 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Av'), 196*a25f0a04SGreg Roach 13 => /* I18N: a month in the Jewish calendar */ I18N::translate_c('INSTRUMENTAL', 'Elul'), 197*a25f0a04SGreg Roach ); 198*a25f0a04SGreg Roach } 199*a25f0a04SGreg Roach 200*a25f0a04SGreg Roach if ($month_number === 7 && $leap_year) { 201*a25f0a04SGreg Roach return $translated_month_names[-7]; 202*a25f0a04SGreg Roach } else { 203*a25f0a04SGreg Roach return $translated_month_names[$month_number]; 204*a25f0a04SGreg Roach } 205*a25f0a04SGreg Roach } 206*a25f0a04SGreg Roach 207*a25f0a04SGreg Roach /** {@inheritdoc} */ 208*a25f0a04SGreg Roach protected static function monthNameAbbreviated($month_number, $leap_year) { 209*a25f0a04SGreg Roach return self::monthNameNominativeCase($month_number, $leap_year); 210*a25f0a04SGreg Roach } 211*a25f0a04SGreg Roach 212*a25f0a04SGreg Roach /** {@inheritdoc} */ 213*a25f0a04SGreg Roach protected function nextMonth() { 214*a25f0a04SGreg Roach if ($this->m == 6 && !$this->isLeapYear()) { 215*a25f0a04SGreg Roach return array($this->y, 8); 216*a25f0a04SGreg Roach } else { 217*a25f0a04SGreg Roach return array($this->y + ($this->m == 13 ? 1 : 0), ($this->m % 13) + 1); 218*a25f0a04SGreg Roach } 219*a25f0a04SGreg Roach } 220*a25f0a04SGreg Roach 221*a25f0a04SGreg Roach /** 222*a25f0a04SGreg Roach * Convert a decimal number to hebrew - like roman numerals, but with extra punctuation and special rules. 223*a25f0a04SGreg Roach * 224*a25f0a04SGreg Roach * @param integer $num 225*a25f0a04SGreg Roach * 226*a25f0a04SGreg Roach * @return string 227*a25f0a04SGreg Roach */ 228*a25f0a04SGreg Roach protected static function numberToHebrewNumerals($num) { 229*a25f0a04SGreg Roach $DISPLAY_JEWISH_THOUSANDS = false; 230*a25f0a04SGreg Roach 231*a25f0a04SGreg Roach static $jHundreds = array("", "ק", "ר", "ש", "ת", "תק", "תר", "תש", "תת", "תתק"); 232*a25f0a04SGreg Roach static $jTens = array("", "י", "כ", "ל", "מ", "נ", "ס", "ע", "פ", "צ"); 233*a25f0a04SGreg Roach static $jTenEnds = array("", "י", "ך", "ל", "ם", "ן", "ס", "ע", "ף", "ץ"); 234*a25f0a04SGreg Roach static $tavTaz = array("ט״ו", "ט״ז"); 235*a25f0a04SGreg Roach static $jOnes = array("", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט"); 236*a25f0a04SGreg Roach 237*a25f0a04SGreg Roach $shortYear = $num % 1000; //discard thousands 238*a25f0a04SGreg Roach //next check for all possible single Hebrew digit years 239*a25f0a04SGreg Roach $singleDigitYear = ($shortYear < 11 || ($shortYear < 100 && $shortYear % 10 == 0) || ($shortYear <= 400 && $shortYear % 100 == 0)); 240*a25f0a04SGreg Roach $thousands = (int) ($num / 1000); //get # thousands 241*a25f0a04SGreg Roach $sb = ""; 242*a25f0a04SGreg Roach //append thousands to String 243*a25f0a04SGreg Roach if ($num % 1000 == 0) { 244*a25f0a04SGreg Roach // in year is 5000, 4000 etc 245*a25f0a04SGreg Roach $sb .= $jOnes[$thousands]; 246*a25f0a04SGreg Roach $sb .= self::GERSH; 247*a25f0a04SGreg Roach $sb .= " "; 248*a25f0a04SGreg Roach $sb .= self::ALAFIM; //add # of thousands plus word thousand (overide alafim boolean) 249*a25f0a04SGreg Roach } elseif ($DISPLAY_JEWISH_THOUSANDS) { 250*a25f0a04SGreg Roach // if alafim boolean display thousands 251*a25f0a04SGreg Roach $sb .= $jOnes[$thousands]; 252*a25f0a04SGreg Roach $sb .= self::GERSH; //append thousands quote 253*a25f0a04SGreg Roach $sb .= " "; 254*a25f0a04SGreg Roach } 255*a25f0a04SGreg Roach $num = $num % 1000; //remove 1000s 256*a25f0a04SGreg Roach $hundreds = (int) ($num / 100); // # of hundreds 257*a25f0a04SGreg Roach $sb .= $jHundreds[$hundreds]; //add hundreds to String 258*a25f0a04SGreg Roach $num = $num % 100; //remove 100s 259*a25f0a04SGreg Roach if ($num == 15) { 260*a25f0a04SGreg Roach $sb .= $tavTaz[0]; 261*a25f0a04SGreg Roach } else if ($num == 16) { 262*a25f0a04SGreg Roach $sb .= $tavTaz[1]; 263*a25f0a04SGreg Roach } else { 264*a25f0a04SGreg Roach $tens = (int) ($num / 10); 265*a25f0a04SGreg Roach if ($num % 10 == 0) { 266*a25f0a04SGreg Roach if ($singleDigitYear == false) { 267*a25f0a04SGreg Roach $sb .= $jTenEnds[$tens]; // use end letters so that for example 5750 will end with an end nun 268*a25f0a04SGreg Roach } else { 269*a25f0a04SGreg Roach $sb .= $jTens[$tens]; // use standard letters so that for example 5050 will end with a regular nun 270*a25f0a04SGreg Roach } 271*a25f0a04SGreg Roach } else { 272*a25f0a04SGreg Roach $sb .= $jTens[$tens]; 273*a25f0a04SGreg Roach $num = $num % 10; 274*a25f0a04SGreg Roach $sb .= $jOnes[$num]; 275*a25f0a04SGreg Roach } 276*a25f0a04SGreg Roach } 277*a25f0a04SGreg Roach if ($singleDigitYear == true) { 278*a25f0a04SGreg Roach // Append single quote 279*a25f0a04SGreg Roach $sb .= self::GERSH; 280*a25f0a04SGreg Roach } else { 281*a25f0a04SGreg Roach // Append double quote before last digit 282*a25f0a04SGreg Roach $pos1 = strlen($sb) - 2; 283*a25f0a04SGreg Roach $sb = substr($sb, 0, $pos1) . self::GERSHAYIM . substr($sb, $pos1); 284*a25f0a04SGreg Roach // Replace double gershayim with single instance 285*a25f0a04SGreg Roach $sb = str_replace(self::GERSHAYIM . self::GERSHAYIM, self::GERSHAYIM, $sb); 286*a25f0a04SGreg Roach } 287*a25f0a04SGreg Roach 288*a25f0a04SGreg Roach return $sb; 289*a25f0a04SGreg Roach } 290*a25f0a04SGreg Roach} 291