1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2018 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\FrenchCalendar; 19use Fisharebest\Webtrees\I18N; 20 21/** 22 * Definitions for the French Republican calendar 23 */ 24class FrenchDate extends CalendarDate 25{ 26 /** @var int[] Convert GEDCOM month names to month numbers */ 27 public static $MONTH_ABBREV = [ 28 '' => 0, 29 'VEND' => 1, 30 'BRUM' => 2, 31 'FRIM' => 3, 32 'NIVO' => 4, 33 'PLUV' => 5, 34 'VENT' => 6, 35 'GERM' => 7, 36 'FLOR' => 8, 37 'PRAI' => 9, 38 'MESS' => 10, 39 'THER' => 11, 40 'FRUC' => 12, 41 'COMP' => 13, 42 ]; 43 44 /** 45 * Create a date from either: 46 * a Julian day number 47 * day/month/year strings from a GEDCOM date 48 * another CalendarDate object 49 * 50 * @param array|int|CalendarDate $date 51 */ 52 public function __construct($date) 53 { 54 $this->calendar = new FrenchCalendar(); 55 parent::__construct($date); 56 } 57 58 /** 59 * Full month name in nominative case. 60 * 61 * @param int $month_number 62 * @param bool $leap_year Some calendars use leap months 63 * 64 * @return string 65 */ 66 protected function monthNameNominativeCase(int $month_number, bool $leap_year): string 67 { 68 static $translated_month_names; 69 70 if ($translated_month_names === null) { 71 $translated_month_names = [ 72 0 => '', 73 /* I18N: a month in the French republican calendar */ 74 1 => I18N::translateContext('NOMINATIVE', 'Vendemiaire'), 75 /* I18N: a month in the French republican calendar */ 76 2 => I18N::translateContext('NOMINATIVE', 'Brumaire'), 77 /* I18N: a month in the French republican calendar */ 78 3 => I18N::translateContext('NOMINATIVE', 'Frimaire'), 79 /* I18N: a month in the French republican calendar */ 80 4 => I18N::translateContext('NOMINATIVE', 'Nivose'), 81 /* I18N: a month in the French republican calendar */ 82 5 => I18N::translateContext('NOMINATIVE', 'Pluviose'), 83 /* I18N: a month in the French republican calendar */ 84 6 => I18N::translateContext('NOMINATIVE', 'Ventose'), 85 /* I18N: a month in the French republican calendar */ 86 /* I18N: a month in the French republican calendar */ 87 7 => I18N::translateContext('NOMINATIVE', 'Germinal'), 88 /* I18N: a month in the French republican calendar */ 89 8 => I18N::translateContext('NOMINATIVE', 'Floreal'), 90 /* I18N: a month in the French republican calendar */ 91 9 => I18N::translateContext('NOMINATIVE', 'Prairial'), 92 /* I18N: a month in the French republican calendar */ 93 10 => I18N::translateContext('NOMINATIVE', 'Messidor'), 94 /* I18N: a month in the French republican calendar */ 95 11 => I18N::translateContext('NOMINATIVE', 'Thermidor'), 96 /* I18N: a month in the French republican calendar */ 97 12 => I18N::translateContext('NOMINATIVE', 'Fructidor'), 98 /* I18N: a month in the French republican calendar */ 99 13 => I18N::translateContext('NOMINATIVE', 'jours complementaires'), 100 ]; 101 } 102 103 return $translated_month_names[$month_number]; 104 } 105 106 /** 107 * Full month name in genitive case. 108 * 109 * @param int $month_number 110 * @param bool $leap_year Some calendars use leap months 111 * 112 * @return string 113 */ 114 protected function monthNameGenitiveCase(int $month_number, bool $leap_year): string 115 { 116 static $translated_month_names; 117 118 if ($translated_month_names === null) { 119 $translated_month_names = [ 120 0 => '', 121 /* I18N: a month in the French republican calendar */ 122 1 => I18N::translateContext('GENITIVE', 'Vendemiaire'), 123 /* I18N: a month in the French republican calendar */ 124 2 => I18N::translateContext('GENITIVE', 'Brumaire'), 125 /* I18N: a month in the French republican calendar */ 126 3 => I18N::translateContext('GENITIVE', 'Frimaire'), 127 /* I18N: a month in the French republican calendar */ 128 4 => I18N::translateContext('GENITIVE', 'Nivose'), 129 /* I18N: a month in the French republican calendar */ 130 5 => I18N::translateContext('GENITIVE', 'Pluviose'), 131 /* I18N: a month in the French republican calendar */ 132 6 => I18N::translateContext('GENITIVE', 'Ventose'), 133 /* I18N: a month in the French republican calendar */ 134 7 => I18N::translateContext('GENITIVE', 'Germinal'), 135 /* I18N: a month in the French republican calendar */ 136 8 => I18N::translateContext('GENITIVE', 'Floreal'), 137 /* I18N: a month in the French republican calendar */ 138 9 => I18N::translateContext('GENITIVE', 'Prairial'), 139 /* I18N: a month in the French republican calendar */ 140 10 => I18N::translateContext('GENITIVE', 'Messidor'), 141 /* I18N: a month in the French republican calendar */ 142 11 => I18N::translateContext('GENITIVE', 'Thermidor'), 143 /* I18N: a month in the French republican calendar */ 144 12 => I18N::translateContext('GENITIVE', 'Fructidor'), 145 /* I18N: a month in the French republican calendar */ 146 13 => I18N::translateContext('GENITIVE', 'jours complementaires'), 147 ]; 148 } 149 150 return $translated_month_names[$month_number]; 151 } 152 153 /** 154 * Full month name in locative case. 155 * 156 * @param int $month_number 157 * @param bool $leap_year Some calendars use leap months 158 * 159 * @return string 160 */ 161 protected function monthNameLocativeCase(int $month_number, bool $leap_year): string 162 { 163 static $translated_month_names; 164 165 if ($translated_month_names === null) { 166 $translated_month_names = [ 167 0 => '', 168 /* I18N: a month in the French republican calendar */ 169 1 => I18N::translateContext('LOCATIVE', 'Vendemiaire'), 170 /* I18N: a month in the French republican calendar */ 171 2 => I18N::translateContext('LOCATIVE', 'Brumaire'), 172 /* I18N: a month in the French republican calendar */ 173 3 => I18N::translateContext('LOCATIVE', 'Frimaire'), 174 /* I18N: a month in the French republican calendar */ 175 4 => I18N::translateContext('LOCATIVE', 'Nivose'), 176 /* I18N: a month in the French republican calendar */ 177 5 => I18N::translateContext('LOCATIVE', 'Pluviose'), 178 /* I18N: a month in the French republican calendar */ 179 6 => I18N::translateContext('LOCATIVE', 'Ventose'), 180 /* I18N: a month in the French republican calendar */ 181 7 => I18N::translateContext('LOCATIVE', 'Germinal'), 182 /* I18N: a month in the French republican calendar */ 183 8 => I18N::translateContext('LOCATIVE', 'Floreal'), 184 /* I18N: a month in the French republican calendar */ 185 9 => I18N::translateContext('LOCATIVE', 'Prairial'), 186 /* I18N: a month in the French republican calendar */ 187 10 => I18N::translateContext('LOCATIVE', 'Messidor'), 188 /* I18N: a month in the French republican calendar */ 189 11 => I18N::translateContext('LOCATIVE', 'Thermidor'), 190 /* I18N: a month in the French republican calendar */ 191 12 => I18N::translateContext('LOCATIVE', 'Fructidor'), 192 /* I18N: a month in the French republican calendar */ 193 13 => I18N::translateContext('LOCATIVE', 'jours complementaires'), 194 ]; 195 } 196 197 return $translated_month_names[$month_number]; 198 } 199 200 /** 201 * Full month name in instrumental case. 202 * 203 * @param int $month_number 204 * @param bool $leap_year Some calendars use leap months 205 * 206 * @return string 207 */ 208 protected function monthNameInstrumentalCase(int $month_number, bool $leap_year): string 209 { 210 static $translated_month_names; 211 212 if ($translated_month_names === null) { 213 $translated_month_names = [ 214 0 => '', 215 /* I18N: a month in the French republican calendar */ 216 1 => I18N::translateContext('INSTRUMENTAL', 'Vendemiaire'), 217 /* I18N: a month in the French republican calendar */ 218 2 => I18N::translateContext('INSTRUMENTAL', 'Brumaire'), 219 /* I18N: a month in the French republican calendar */ 220 3 => I18N::translateContext('INSTRUMENTAL', 'Frimaire'), 221 /* I18N: a month in the French republican calendar */ 222 4 => I18N::translateContext('INSTRUMENTAL', 'Nivose'), 223 /* I18N: a month in the French republican calendar */ 224 5 => I18N::translateContext('INSTRUMENTAL', 'Pluviose'), 225 /* I18N: a month in the French republican calendar */ 226 6 => I18N::translateContext('INSTRUMENTAL', 'Ventose'), 227 /* I18N: a month in the French republican calendar */ 228 7 => I18N::translateContext('INSTRUMENTAL', 'Germinal'), 229 /* I18N: a month in the French republican calendar */ 230 8 => I18N::translateContext('INSTRUMENTAL', 'Floreal'), 231 /* I18N: a month in the French republican calendar */ 232 9 => I18N::translateContext('INSTRUMENTAL', 'Prairial'), 233 /* I18N: a month in the French republican calendar */ 234 10 => I18N::translateContext('INSTRUMENTAL', 'Messidor'), 235 /* I18N: a month in the French republican calendar */ 236 11 => I18N::translateContext('INSTRUMENTAL', 'Thermidor'), 237 /* I18N: a month in the French republican calendar */ 238 12 => I18N::translateContext('INSTRUMENTAL', 'Fructidor'), 239 /* I18N: a month in the French republican calendar */ 240 13 => I18N::translateContext('INSTRUMENTAL', 'jours complementaires'), 241 ]; 242 } 243 244 return $translated_month_names[$month_number]; 245 } 246 247 /** 248 * Abbreviated month name 249 * 250 * @param int $month_number 251 * @param bool $leap_year Some calendars use leap months 252 * 253 * @return string 254 */ 255 protected function monthNameAbbreviated(int $month_number, bool $leap_year): string 256 { 257 return self::monthNameNominativeCase($month_number, $leap_year); 258 } 259 260 /** 261 * Full day of th eweek 262 * 263 * @param int $day_number 264 * 265 * @return string 266 */ 267 public function dayNames(int $day_number): string 268 { 269 static $translated_day_names; 270 271 if ($translated_day_names === null) { 272 $translated_day_names = [ 273 /* I18N: The first day in the French republican calendar */ 274 0 => I18N::translate('Primidi'), 275 /* I18N: The second day in the French republican calendar */ 276 1 => I18N::translate('Duodi'), 277 /* I18N: The third day in the French republican calendar */ 278 2 => I18N::translate('Tridi'), 279 /* I18N: The fourth day in the French republican calendar */ 280 3 => I18N::translate('Quartidi'), 281 /* I18N: The fifth day in the French republican calendar */ 282 4 => I18N::translate('Quintidi'), 283 /* I18N: The sixth day in the French republican calendar */ 284 5 => I18N::translate('Sextidi'), 285 /* I18N: The seventh day in the French republican calendar */ 286 6 => I18N::translate('Septidi'), 287 /* I18N: The eighth day in the French republican calendar */ 288 7 => I18N::translate('Octidi'), 289 /* I18N: The ninth day in the French republican calendar */ 290 8 => I18N::translate('Nonidi'), 291 /* I18N: The tenth day in the French republican calendar */ 292 9 => I18N::translate('Decidi'), 293 ]; 294 } 295 296 return $translated_day_names[$day_number]; 297 } 298 299 /** 300 * Abbreviated day of the week 301 * 302 * @param int $day_number 303 * 304 * @return string 305 */ 306 protected function dayNamesAbbreviated(int $day_number): string 307 { 308 return $this->dayNames($day_number); 309 } 310 311 /** 312 * Generate the %Y format for a date. 313 * 314 * @return string 315 */ 316 protected function formatLongYear(): string 317 { 318 return $this->numberToRomanNumerals($this->y); 319 } 320} 321