1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2017 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16namespace Fisharebest\Webtrees\Date; 17 18use Fisharebest\ExtCalendar\JewishCalendar; 19use Fisharebest\Webtrees\I18N; 20 21/** 22 * Definitions for the Jewish calendar 23 */ 24class JewishDate extends CalendarDate { 25 /** @var int[] Convert GEDCOM month names to month numbers */ 26 public static $MONTH_ABBREV = ['' => 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]; 27 28 /** 29 * Create a date from either: 30 * a Julian day number 31 * day/month/year strings from a GEDCOM date 32 * another CalendarDate object 33 * 34 * @param array|int|CalendarDate $date 35 */ 36 public function __construct($date) { 37 $this->calendar = new JewishCalendar; 38 parent::__construct($date); 39 } 40 41 /** 42 * Generate the %j format for a date. 43 * 44 * @return string 45 */ 46 protected function formatDay() { 47 if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') { 48 return $this->calendar->numberToHebrewNumerals($this->d, true); 49 } else { 50 return $this->d; 51 } 52 } 53 54 /** 55 * Generate the %y format for a date. 56 * 57 * NOTE Short year is NOT a 2-digit year. It is for calendars such as hebrew 58 * which have a 3-digit form of 4-digit years. 59 * 60 * @return string 61 */ 62 protected function formatShortYear() { 63 if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') { 64 return $this->calendar->numberToHebrewNumerals($this->y, false); 65 } else { 66 return $this->y; 67 } 68 } 69 70 /** 71 * Generate the %Y format for a date. 72 * 73 * @return string 74 */ 75 protected function formatLongYear() { 76 if (WT_LOCALE === 'he' || WT_LOCALE === 'yi') { 77 return $this->calendar->numberToHebrewNumerals($this->y, true); 78 } else { 79 return $this->y; 80 } 81 } 82 83 /** 84 * Full month name in nominative case. 85 * 86 * @param int $month_number 87 * @param bool $leap_year Some calendars use leap months 88 * 89 * @return string 90 */ 91 public static function monthNameNominativeCase($month_number, $leap_year) { 92 static $translated_month_names; 93 94 if ($translated_month_names === null) { 95 $translated_month_names = [ 96 0 => '', 97 1 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Tishrei'), 98 2 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Heshvan'), 99 3 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Kislev'), 100 4 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Tevet'), 101 5 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Shevat'), 102 6 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Adar I'), 103 7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Adar'), 104 -7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Adar II'), 105 8 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Nissan'), 106 9 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Iyar'), 107 10 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Sivan'), 108 11 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Tamuz'), 109 12 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Av'), 110 13 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('NOMINATIVE', 'Elul'), 111 ]; 112 } 113 114 if ($month_number === 7 && $leap_year) { 115 return $translated_month_names[-7]; 116 } else { 117 return $translated_month_names[$month_number]; 118 } 119 } 120 121 /** 122 * Full month name in genitive case. 123 * 124 * @param int $month_number 125 * @param bool $leap_year Some calendars use leap months 126 * 127 * @return string 128 */ 129 protected function monthNameGenitiveCase($month_number, $leap_year) { 130 static $translated_month_names; 131 132 if ($translated_month_names === null) { 133 $translated_month_names = [ 134 0 => '', 135 1 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Tishrei'), 136 2 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Heshvan'), 137 3 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Kislev'), 138 4 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Tevet'), 139 5 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Shevat'), 140 6 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Adar I'), 141 7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Adar'), 142 -7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Adar II'), 143 8 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Nissan'), 144 9 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Iyar'), 145 10 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Sivan'), 146 11 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Tamuz'), 147 12 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Av'), 148 13 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('GENITIVE', 'Elul'), 149 ]; 150 } 151 152 if ($month_number === 7 && $leap_year) { 153 return $translated_month_names[-7]; 154 } else { 155 return $translated_month_names[$month_number]; 156 } 157 } 158 159 /** 160 * Full month name in locative case. 161 * 162 * @param int $month_number 163 * @param bool $leap_year Some calendars use leap months 164 * 165 * @return string 166 */ 167 protected function monthNameLocativeCase($month_number, $leap_year) { 168 static $translated_month_names; 169 170 if ($translated_month_names === null) { 171 $translated_month_names = [ 172 0 => '', 173 1 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Tishrei'), 174 2 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Heshvan'), 175 3 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Kislev'), 176 4 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Tevet'), 177 5 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Shevat'), 178 6 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Adar I'), 179 7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Adar'), 180 -7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Adar II'), 181 8 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Nissan'), 182 9 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Iyar'), 183 10 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Sivan'), 184 11 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Tamuz'), 185 12 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Av'), 186 13 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('LOCATIVE', 'Elul'), 187 ]; 188 } 189 190 if ($month_number === 7 && $leap_year) { 191 return $translated_month_names[-7]; 192 } else { 193 return $translated_month_names[$month_number]; 194 } 195 } 196 197 /** 198 * Full month name in instrumental case. 199 * 200 * @param int $month_number 201 * @param bool $leap_year Some calendars use leap months 202 * 203 * @return string 204 */ 205 protected function monthNameInstrumentalCase($month_number, $leap_year) { 206 static $translated_month_names; 207 208 if ($translated_month_names === null) { 209 $translated_month_names = [ 210 0 => '', 211 1 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Tishrei'), 212 2 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Heshvan'), 213 3 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Kislev'), 214 4 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Tevet'), 215 5 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Shevat'), 216 6 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Adar I'), 217 7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Adar'), 218 -7 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Adar II'), 219 8 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Nissan'), 220 9 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Iyar'), 221 10 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Sivan'), 222 11 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Tamuz'), 223 12 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Av'), 224 13 => /* I18N: a month in the Jewish calendar */ I18N::translateContext('INSTRUMENTAL', 'Elul'), 225 ]; 226 } 227 228 if ($month_number === 7 && $leap_year) { 229 return $translated_month_names[-7]; 230 } else { 231 return $translated_month_names[$month_number]; 232 } 233 } 234 235 /** 236 * Abbreviated month name 237 * 238 * @param int $month_number 239 * @param bool $leap_year Some calendars use leap months 240 * 241 * @return string 242 */ 243 protected function monthNameAbbreviated($month_number, $leap_year) { 244 return self::monthNameNominativeCase($month_number, $leap_year); 245 } 246 247 /** 248 * Which months follows this one? Calendars with leap-months should provide their own implementation. 249 * 250 * @return int[] 251 */ 252 protected function nextMonth() { 253 if ($this->m == 6 && !$this->isLeapYear()) { 254 return [$this->y, 8]; 255 } else { 256 return [$this->y + ($this->m == 13 ? 1 : 0), ($this->m % 13) + 1]; 257 } 258 } 259} 260