14ba350e3SGreg Roach<?php 23976b470SGreg Roach 34ba350e3SGreg Roach/** 44ba350e3SGreg Roach * webtrees: online genealogy 5*d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 64ba350e3SGreg Roach * This program is free software: you can redistribute it and/or modify 74ba350e3SGreg Roach * it under the terms of the GNU General Public License as published by 84ba350e3SGreg Roach * the Free Software Foundation, either version 3 of the License, or 94ba350e3SGreg Roach * (at your option) any later version. 104ba350e3SGreg Roach * This program is distributed in the hope that it will be useful, 114ba350e3SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 124ba350e3SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 134ba350e3SGreg Roach * GNU General Public License for more details. 144ba350e3SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 164ba350e3SGreg Roach */ 17fcfa147eSGreg Roach 184ba350e3SGreg Roachdeclare(strict_types=1); 194ba350e3SGreg Roach 204ba350e3SGreg Roachnamespace Fisharebest\Webtrees\Services; 214ba350e3SGreg Roach 22dec352c1SGreg Roachuse function str_starts_with; 23dec352c1SGreg Roachuse function strlen; 24dec352c1SGreg Roachuse function substr; 25dec352c1SGreg Roach 264ba350e3SGreg Roach/** 274ba350e3SGreg Roach * Convert to and from Roman Numerals 284ba350e3SGreg Roach */ 294ba350e3SGreg Roachclass RomanNumeralsService 304ba350e3SGreg Roach{ 314ba350e3SGreg Roach // Convert numbers to/from roman numerals 3216d6367aSGreg Roach private const ROMAN_NUMERALS = [ 334ba350e3SGreg Roach 1000 => 'M', 344ba350e3SGreg Roach 900 => 'CM', 354ba350e3SGreg Roach 500 => 'D', 364ba350e3SGreg Roach 400 => 'CD', 374ba350e3SGreg Roach 100 => 'C', 384ba350e3SGreg Roach 90 => 'XC', 394ba350e3SGreg Roach 50 => 'L', 404ba350e3SGreg Roach 40 => 'XL', 414ba350e3SGreg Roach 10 => 'X', 424ba350e3SGreg Roach 9 => 'IX', 434ba350e3SGreg Roach 5 => 'V', 444ba350e3SGreg Roach 4 => 'IV', 454ba350e3SGreg Roach 1 => 'I', 464ba350e3SGreg Roach ]; 474ba350e3SGreg Roach 484ba350e3SGreg Roach /** 494ba350e3SGreg Roach * Convert a decimal number to roman numerals 504ba350e3SGreg Roach * 514ba350e3SGreg Roach * @param int $number 524ba350e3SGreg Roach * 534ba350e3SGreg Roach * @return string 544ba350e3SGreg Roach */ 554ba350e3SGreg Roach public function numberToRomanNumerals(int $number): string 564ba350e3SGreg Roach { 574ba350e3SGreg Roach if ($number < 1) { 584ba350e3SGreg Roach // Cannot convert zero/negative numbers 594ba350e3SGreg Roach return (string) $number; 604ba350e3SGreg Roach } 614ba350e3SGreg Roach $roman = ''; 624ba350e3SGreg Roach foreach (self::ROMAN_NUMERALS as $key => $value) { 634ba350e3SGreg Roach while ($number >= $key) { 644ba350e3SGreg Roach $roman .= $value; 654ba350e3SGreg Roach $number -= $key; 664ba350e3SGreg Roach } 674ba350e3SGreg Roach } 684ba350e3SGreg Roach 694ba350e3SGreg Roach return $roman; 704ba350e3SGreg Roach } 714ba350e3SGreg Roach 724ba350e3SGreg Roach /** 734ba350e3SGreg Roach * Convert a roman numeral to decimal 744ba350e3SGreg Roach * 754ba350e3SGreg Roach * @param string $roman 764ba350e3SGreg Roach * 774ba350e3SGreg Roach * @return int 784ba350e3SGreg Roach */ 794ba350e3SGreg Roach public function romanNumeralsToNumber(string $roman): int 804ba350e3SGreg Roach { 814ba350e3SGreg Roach $num = 0; 824ba350e3SGreg Roach foreach (self::ROMAN_NUMERALS as $key => $value) { 83dec352c1SGreg Roach while (str_starts_with($roman, $value)) { 844ba350e3SGreg Roach $num += $key; 854ba350e3SGreg Roach $roman = substr($roman, strlen($value)); 864ba350e3SGreg Roach } 874ba350e3SGreg Roach } 884ba350e3SGreg Roach 894ba350e3SGreg Roach return $num; 904ba350e3SGreg Roach } 914ba350e3SGreg Roach} 92