1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2023 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Date; 21 22use Fisharebest\ExtCalendar\ArabicCalendar; 23use Fisharebest\Webtrees\I18N; 24 25/** 26 * Definitions for Hijri dates. 27 * 28 * Note that these are "theoretical" dates. 29 * "True" dates are based on local lunar observations, and can be a +/- one day. 30 */ 31class HijriDate extends AbstractCalendarDate 32{ 33 // GEDCOM calendar escape 34 public const string ESCAPE = '@#DHIJRI@'; 35 36 // Convert GEDCOM month names to month numbers 37 protected const array MONTH_TO_NUMBER = [ 38 'MUHAR' => 1, 39 'SAFAR' => 2, 40 'RABIA' => 3, 41 'RABIT' => 4, 42 'JUMAA' => 5, 43 'JUMAT' => 6, 44 'RAJAB' => 7, 45 'SHAAB' => 8, 46 'RAMAD' => 9, 47 'SHAWW' => 10, 48 'DHUAQ' => 11, 49 'DHUAH' => 12, 50 ]; 51 52 protected const array NUMBER_TO_MONTH = [ 53 1 => 'MUHAR', 54 2 => 'SAFAR', 55 3 => 'RABIA', 56 4 => 'RABIT', 57 5 => 'JUMAA', 58 6 => 'JUMAT', 59 7 => 'RAJAB', 60 8 => 'SHAAB', 61 9 => 'RAMAD', 62 10 => 'SHAWW', 63 11 => 'DHUAQ', 64 12 => 'DHUAH', 65 ]; 66 67 /** 68 * Create a date from either: 69 * a Julian day number 70 * day/month/year strings from a GEDCOM date 71 * another CalendarDate object 72 * 73 * @param array<string>|int|AbstractCalendarDate $date 74 */ 75 public function __construct($date) 76 { 77 $this->calendar = new ArabicCalendar(); 78 parent::__construct($date); 79 } 80 81 /** 82 * Full month name in nominative case. 83 * 84 * @param int $month 85 * @param bool $leap_year Some calendars use leap months 86 * 87 * @return string 88 */ 89 protected function monthNameNominativeCase(int $month, bool $leap_year): string 90 { 91 static $translated_month_names; 92 93 if ($translated_month_names === null) { 94 $translated_month_names = [ 95 0 => '', 96 /* I18N: https://en.wikipedia.org/wiki/Muharram */ 97 1 => I18N::translateContext('NOMINATIVE', 'Muharram'), 98 /* I18N: https://en.wikipedia.org/wiki/Safar */ 99 2 => I18N::translateContext('NOMINATIVE', 'Safar'), 100 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */ 101 3 => I18N::translateContext('NOMINATIVE', 'Rabi’ al-awwal'), 102 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */ 103 4 => I18N::translateContext('NOMINATIVE', 'Rabi’ al-thani'), 104 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */ 105 5 => I18N::translateContext('NOMINATIVE', 'Jumada al-awwal'), 106 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */ 107 6 => I18N::translateContext('NOMINATIVE', 'Jumada al-thani'), 108 /* I18N: https://en.wikipedia.org/wiki/Rajab */ 109 7 => I18N::translateContext('NOMINATIVE', 'Rajab'), 110 /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */ 111 8 => I18N::translateContext('NOMINATIVE', 'Sha’aban'), 112 /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */ 113 9 => I18N::translateContext('NOMINATIVE', 'Ramadan'), 114 /* I18N: https://en.wikipedia.org/wiki/Shawwal */ 115 10 => I18N::translateContext('NOMINATIVE', 'Shawwal'), 116 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */ 117 11 => I18N::translateContext('NOMINATIVE', 'Dhu al-Qi’dah'), 118 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */ 119 12 => I18N::translateContext('NOMINATIVE', 'Dhu al-Hijjah'), 120 ]; 121 } 122 123 return $translated_month_names[$month]; 124 } 125 126 /** 127 * Full month name in genitive case. 128 * 129 * @param int $month 130 * @param bool $leap_year Some calendars use leap months 131 * 132 * @return string 133 */ 134 protected function monthNameGenitiveCase(int $month, bool $leap_year): string 135 { 136 static $translated_month_names; 137 138 if ($translated_month_names === null) { 139 $translated_month_names = [ 140 0 => '', 141 /* I18N: https://en.wikipedia.org/wiki/Muharram */ 142 1 => I18N::translateContext('GENITIVE', 'Muharram'), 143 /* I18N: https://en.wikipedia.org/wiki/Safar */ 144 2 => I18N::translateContext('GENITIVE', 'Safar'), 145 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */ 146 3 => I18N::translateContext('GENITIVE', 'Rabi’ al-awwal'), 147 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */ 148 4 => I18N::translateContext('GENITIVE', 'Rabi’ al-thani'), 149 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */ 150 5 => I18N::translateContext('GENITIVE', 'Jumada al-awwal'), 151 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */ 152 6 => I18N::translateContext('GENITIVE', 'Jumada al-thani'), 153 /* I18N: https://en.wikipedia.org/wiki/Rajab */ 154 7 => I18N::translateContext('GENITIVE', 'Rajab'), 155 /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */ 156 8 => I18N::translateContext('GENITIVE', 'Sha’aban'), 157 /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */ 158 9 => I18N::translateContext('GENITIVE', 'Ramadan'), 159 /* I18N: https://en.wikipedia.org/wiki/Shawwal */ 160 10 => I18N::translateContext('GENITIVE', 'Shawwal'), 161 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */ 162 11 => I18N::translateContext('GENITIVE', 'Dhu al-Qi’dah'), 163 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */ 164 12 => I18N::translateContext('GENITIVE', 'Dhu al-Hijjah'), 165 ]; 166 } 167 168 return $translated_month_names[$month]; 169 } 170 171 /** 172 * Full month name in locative case. 173 * 174 * @param int $month 175 * @param bool $leap_year Some calendars use leap months 176 * 177 * @return string 178 */ 179 protected function monthNameLocativeCase(int $month, bool $leap_year): string 180 { 181 static $translated_month_names; 182 183 if ($translated_month_names === null) { 184 $translated_month_names = [ 185 0 => '', 186 /* I18N: https://en.wikipedia.org/wiki/Muharram */ 187 1 => I18N::translateContext('LOCATIVE', 'Muharram'), 188 /* I18N: https://en.wikipedia.org/wiki/Safar */ 189 2 => I18N::translateContext('LOCATIVE', 'Safar'), 190 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */ 191 3 => I18N::translateContext('LOCATIVE', 'Rabi’ al-awwal'), 192 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */ 193 4 => I18N::translateContext('LOCATIVE', 'Rabi’ al-thani'), 194 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */ 195 5 => I18N::translateContext('LOCATIVE', 'Jumada al-awwal'), 196 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */ 197 6 => I18N::translateContext('LOCATIVE', 'Jumada al-thani'), 198 /* I18N: https://en.wikipedia.org/wiki/Rajab */ 199 7 => I18N::translateContext('LOCATIVE', 'Rajab'), 200 /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */ 201 8 => I18N::translateContext('LOCATIVE', 'Sha’aban'), 202 /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */ 203 9 => I18N::translateContext('LOCATIVE', 'Ramadan'), 204 /* I18N: https://en.wikipedia.org/wiki/Shawwal */ 205 10 => I18N::translateContext('LOCATIVE', 'Shawwal'), 206 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */ 207 11 => I18N::translateContext('LOCATIVE', 'Dhu al-Qi’dah'), 208 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */ 209 12 => I18N::translateContext('LOCATIVE', 'Dhu al-Hijjah'), 210 ]; 211 } 212 213 return $translated_month_names[$month]; 214 } 215 216 /** 217 * Full month name in instrumental case. 218 * 219 * @param int $month 220 * @param bool $leap_year Some calendars use leap months 221 * 222 * @return string 223 */ 224 protected function monthNameInstrumentalCase(int $month, bool $leap_year): string 225 { 226 static $translated_month_names; 227 228 if ($translated_month_names === null) { 229 $translated_month_names = [ 230 0 => '', 231 /* I18N: https://en.wikipedia.org/wiki/Muharram */ 232 1 => I18N::translateContext('INSTRUMENTAL', 'Muharram'), 233 /* I18N: https://en.wikipedia.org/wiki/Safar */ 234 2 => I18N::translateContext('INSTRUMENTAL', 'Safar'), 235 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-awwal */ 236 3 => I18N::translateContext('INSTRUMENTAL', 'Rabi’ al-awwal'), 237 /* I18N: https://en.wikipedia.org/wiki/Rabi%27_al-thani */ 238 4 => I18N::translateContext('INSTRUMENTAL', 'Rabi’ al-thani'), 239 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-awwal */ 240 5 => I18N::translateContext('INSTRUMENTAL', 'Jumada al-awwal'), 241 /* I18N: https://en.wikipedia.org/wiki/Jumada_al-thani */ 242 6 => I18N::translateContext('INSTRUMENTAL', 'Jumada al-thani'), 243 /* I18N: https://en.wikipedia.org/wiki/Rajab */ 244 7 => I18N::translateContext('INSTRUMENTAL', 'Rajab'), 245 /* I18N: https://en.wikipedia.org/wiki/Sha%27aban */ 246 8 => I18N::translateContext('INSTRUMENTAL', 'Sha’aban'), 247 /* I18N: https://en.wikipedia.org/wiki/Ramadan_%28calendar_month%29 */ 248 9 => I18N::translateContext('INSTRUMENTAL', 'Ramadan'), 249 /* I18N: https://en.wikipedia.org/wiki/Shawwal */ 250 10 => I18N::translateContext('INSTRUMENTAL', 'Shawwal'), 251 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Qi%27dah */ 252 11 => I18N::translateContext('INSTRUMENTAL', 'Dhu al-Qi’dah'), 253 /* I18N: https://en.wikipedia.org/wiki/Dhu_al-Hijjah */ 254 12 => I18N::translateContext('INSTRUMENTAL', 'Dhu al-Hijjah'), 255 ]; 256 } 257 258 return $translated_month_names[$month]; 259 } 260 261 /** 262 * Abbreviated month name 263 * 264 * @param int $month 265 * @param bool $leap_year Some calendars use leap months 266 * 267 * @return string 268 */ 269 protected function monthNameAbbreviated(int $month, bool $leap_year): string 270 { 271 return $this->monthNameNominativeCase($month, $leap_year); 272 } 273} 274