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