PHPackages                             dickdonohue/roman-numeral - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. dickdonohue/roman-numeral

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

dickdonohue/roman-numeral
=========================

A simple, strict, canonical Roman numeral validator and converter.

v1.0.1(5mo ago)10MITPHPPHP ^8.2

Since Dec 13Pushed 5mo agoCompare

[ Source](https://github.com/dickdonohue/RomanNumeral)[ Packagist](https://packagist.org/packages/dickdonohue/roman-numeral)[ Docs](https://github.com/dickdonohue/RomanNumeral)[ RSS](/packages/dickdonohue-roman-numeral/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (1)Versions (2)Used By (0)

RomanNumeral
============

[](#romannumeral)

[![Latest Stable Version](https://camo.githubusercontent.com/1de7dc110fe24e1492e2bab17a800d6d0944734869251678060cad11687655ec/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6469636b646f6e6f6875652f726f6d616e2d6e756d6572616c2e737667)](https://packagist.org/packages/dickdonohue/roman-numeral)[![PHP Version Require](https://camo.githubusercontent.com/c38adff7e3baa115ffcdd290bf1c89aa9d4043cdcc329bb986634d3c84b7239e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6469636b646f6e6f6875652f726f6d616e2d6e756d6572616c2e737667)](https://packagist.org/packages/dickdonohue/roman-numeral)

A simple, strict, canonical Roman numeral validator and converter.

This library supports **modern, canonical Roman numerals only** and provides clear validation diagnostics when input is invalid and/or non-canonical.

This library intentionally rejects non-canonical forms to prevent subtle logical errors and ambiguous interpretations.

It is designed to be:

- accurate
- easy to understand
- easy to use
- well-documented
- safe for reuse in other projects

The public class interface is stable and fully covered by PHPUnit tests.

---

Features
--------

[](#features)

- Convert integers to canonical Roman numerals
- Validate Roman numeral strings
- Reject non-canonical forms (e.g. `VIIII`, `IL`, `IXC`)
- Enforce modern Roman numeral rules
- Provide detailed validation errors with positional metadata
- No dependencies
- No objects to instantiate (you can use just static methods/functions)
- PHP 8.2+

---

Installation
------------

[](#installation)

Install via Composer:

```
composer require dickdonohue/roman-numeral
```

After installation, a CLI tool is available at `vendor/bin/roman-numeral`.

Usage
-----

[](#usage)

### Integer to Roman numeral

[](#integer-to-roman-numeral)

```
use RomanNumeral\RomanNumeral;

echo RomanNumeral::intToRoman(944);
// CMXLIV
```

### Validating a Roman numeral

[](#validating-a-roman-numeral)

```
use RomanNumeral\RomanNumeral;

$result = RomanNumeral::validate('XIV');
/*
[
  'valid'  => true,
  'value'  => 14,
  'errors' => null
]
*/
```

### Handling non-canonical input

[](#handling-non-canonical-input)

```
$result = RomanNumeral::validate('VIIII');

/* $result is a keyed array
[
  'valid'  => false,
  'value'  => null,
  'errors' => [
    [
      'message'  => 'Non-canonical Roman numeral. Canonical form is IX.',
      'position' => 0,
      'symbol'   => null
    ]
  ]
]
*/
```

Canonical rules enforced
------------------------

[](#canonical-rules-enforced)

- Allowed symbols: I V X L C D M
- Repeats:
    - I, X, C, M may repeat up to three times
    - V, L, D may not repeat
- Allowed subtractive pairs:
    - IV, IX, XL, XC, CD, CM
- Only one symbol may be subtracted at a time
- Symbols **must** appear in descending value order
- Maximum supported value is 3999 (MMMCMXCIX)

Testing
-------

[](#testing)

Run the test suite:

```
composer test
```

Run tests with readable output:

```
composer test:testdox
```

Miscellaneous
-------------

[](#miscellaneous)

When I was a child, we had a clock in our kitchen with Roman Numerals. As a child, I really did not like it. But this was my first experience with representing numbers as something other than Arabic (decimal) numbers! That happens all the time when writing programs. It makes me wonder if this early-childhood experience actually helped lead me to becoming a successful computer programmer.

Recently, I became aware of copyright issues for the makers of the classic, stop-motion Christmas show, "Rudolf the Red-Nosed Reindeer" because they listed the year of copyright incorrectly using Roman numerals. The copyright year is shown as "MCLXIV". Unfortunately, that equates to 1164. That invalidated their copyright. *(Fortunately, they had **correctly** filed copyrights to songs, characters, and other aspects of the show.)* The correct Roman numeral should have been "MCMLXIV" (1964). I thought to myself, if only they had a nice, little library that they could have used to validate their roman numeral!

So that prompted me to create this little project as my first semi-useful project published on GitHub.

This project was developed with assistance from [ChatGPT](https://chatgpt.com).

**Fun fact**: The longest *valid, canonical* Roman numeral string will never be more than 9 characters long. The longest string is for the value 3888 (MMMDCCCLXXXVIII).

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance73

Regular maintenance activity

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

150d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e60bd7efe3869123705d212bc99d45823d13babde5c4e8421e1f0e2c6a662f63?d=identicon)[DickDonohue](/maintainers/DickDonohue)

---

Top Contributors

[![dickdonohue](https://avatars.githubusercontent.com/u/15901042?v=4)](https://github.com/dickdonohue "dickdonohue (8 commits)")

---

Tags

validatorconverterroman-numeral

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/dickdonohue-roman-numeral/health.svg)

```
[![Health](https://phpackages.com/badges/dickdonohue-roman-numeral/health.svg)](https://phpackages.com/packages/dickdonohue-roman-numeral)
```

###  Alternatives

[respect/validation

The most awesome validation engine ever created for PHP

5.9k37.4M383](/packages/respect-validation)[seld/jsonlint

JSON Linter

1.3k217.8M205](/packages/seld-jsonlint)[composer/spdx-licenses

SPDX licenses list and validation library.

1.4k184.2M25](/packages/composer-spdx-licenses)[opis/json-schema

Json Schema Validator for PHP

64236.9M186](/packages/opis-json-schema)[intervention/validation

Additional validation rules for the Laravel framework

6826.7M8](/packages/intervention-validation)[laminas/laminas-validator

Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria

15544.9M188](/packages/laminas-laminas-validator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
