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\Services; 21 22use function str_starts_with; 23use function strlen; 24use function substr; 25 26/** 27 * Convert to and from Roman Numerals 28 */ 29class RomanNumeralsService 30{ 31 // Convert numbers to/from roman numerals 32 private const array ROMAN_NUMERALS = [ 33 1000 => 'M', 34 900 => 'CM', 35 500 => 'D', 36 400 => 'CD', 37 100 => 'C', 38 90 => 'XC', 39 50 => 'L', 40 40 => 'XL', 41 10 => 'X', 42 9 => 'IX', 43 5 => 'V', 44 4 => 'IV', 45 1 => 'I', 46 ]; 47 48 /** 49 * Convert a decimal number to roman numerals 50 * 51 * @param int $number 52 * 53 * @return string 54 */ 55 public function numberToRomanNumerals(int $number): string 56 { 57 if ($number < 1) { 58 // Cannot convert zero/negative numbers 59 return (string) $number; 60 } 61 $roman = ''; 62 foreach (self::ROMAN_NUMERALS as $key => $value) { 63 while ($number >= $key) { 64 $roman .= $value; 65 $number -= $key; 66 } 67 } 68 69 return $roman; 70 } 71 72 /** 73 * Convert a roman numeral to decimal 74 * 75 * @param string $roman 76 * 77 * @return int 78 */ 79 public function romanNumeralsToNumber(string $roman): int 80 { 81 $num = 0; 82 foreach (self::ROMAN_NUMERALS as $key => $value) { 83 while (str_starts_with($roman, $value)) { 84 $num += $key; 85 $roman = substr($roman, strlen($value)); 86 } 87 } 88 89 return $num; 90 } 91} 92