{"id":32151502,"url":"https://github.com/kylehughes/romannumeralkit","last_synced_at":"2026-02-19T07:01:40.969Z","repository":{"id":62452980,"uuid":"130310207","full_name":"kylehughes/RomanNumeralKit","owner":"kylehughes","description":"First-class Roman numeral support for Swift.","archived":false,"fork":false,"pushed_at":"2021-06-25T02:19:16.000Z","size":213,"stargazers_count":32,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"mainline","last_synced_at":"2026-01-31T08:22:59.977Z","etag":null,"topics":["arithmetic","cocoapods","ios","macos","math","roman-numeral","roman-numerals","swift","swiftpm","tvos","watchos"],"latest_commit_sha":null,"homepage":"http://romannumeralkit.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kylehughes.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-20T04:46:43.000Z","updated_at":"2025-10-29T19:15:17.000Z","dependencies_parsed_at":"2022-11-01T23:46:26.506Z","dependency_job_id":null,"html_url":"https://github.com/kylehughes/RomanNumeralKit","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/kylehughes/RomanNumeralKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FRomanNumeralKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FRomanNumeralKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FRomanNumeralKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FRomanNumeralKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kylehughes","download_url":"https://codeload.github.com/kylehughes/RomanNumeralKit/tar.gz/refs/heads/mainline","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FRomanNumeralKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29605799,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T06:47:36.664Z","status":"ssl_error","status_checked_at":"2026-02-19T06:45:47.551Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arithmetic","cocoapods","ios","macos","math","roman-numeral","roman-numerals","swift","swiftpm","tvos","watchos"],"created_at":"2025-10-21T10:46:44.771Z","updated_at":"2026-02-19T07:01:40.964Z","avatar_url":"https://github.com/kylehughes.png","language":"Swift","readme":"# RomanNumeralKit\n\n[![CocoaPods Version](https://img.shields.io/cocoapods/v/RomanNumeralKit.svg)]()\n[![Languages](https://img.shields.io/badge/languages-Swift-orange.svg)]()\n[![Platform](https://img.shields.io/cocoapods/p/RomanNumeralKit.svg)]()\n\n[![Build Status](https://travis-ci.org/kylehughes/RomanNumeralKit.svg?branch=mainline)](https://travis-ci.org/kylehughes/RomanNumeralKit)\n[![codecov](https://codecov.io/gh/kylehughes/RomanNumeralKit/branch/mainline/graph/badge.svg)](https://codecov.io/gh/kylehughes/RomanNumeralKit)\n\nFirst-class Roman numeral support for Swift.\n\n*When in Rome, code as the Romans code.*\n\n## Introduction\n\nMeaningful usage of this framework requires understanding what Roman numerals are. Background information can be found [on Wikipedia](https://en.wikipedia.org/wiki/Roman_numerals).\n\n### Features\n\n- [x] Constants provided for all 3,999 standard Roman numerals.\n- [x] Support for subtractive and additive notations.\n- [x] Arithmetic using Roman-numeral-oriented algorithms - no integer calculations!\n- [x] Conversions to-and-from popular types (e.g. `String`, `Int`).\n- [x] Extensions for real-world usage (e.g. copyright text).\n- [x] Conformance to all applicable numeric protocols.\n\n### Limitations\n\n#### Fixed Numerical Range\n\nStandard Roman numerals as we understand them were limited to values from 1 to 3,999. There is no concept of 0. Modern scholars have proposed extensions of the numeric system to support values greater than 3,999 but we do not recognize any of these extensions and decry the proposers to be heretics.\n\nMost programs do not deal with numbers higher than 3,999, and the world won't exist past the year 3,999 in the Gregorian calendar, so there is no need to worry.\n\n#### iPhone Model Names\n\nRomanNumeralKit does not support conversions to-and-from recent iPhone model names such as \"Xs\".\n\n## Requirements\n\n- iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+\n- Xcode 10.2+\n- Swift 5+\n\n## Installation\n\n### CocoaPods\n\nAdd RomanNumeralKit to your `Podfile`:\n\n```ruby\npod 'RomanNumeralKit', '~\u003e 1.0.0`\n```\n\nPlease visit the [CocoaPods website](https://cocoapods.org/) for general CocoaPods usage and installation instructions.\n\n### Swift Package Manager\n\nAdd RomanNumeralKit to the `dependencies` value of your `Package.swift`:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/kylehughes/RomanNumeralKit.git\", from: \"1.0.0\")\n]\n```\n\n## Usage\n\nImport `RomanNumeralKit` at the top of the Swift file you want to use it in.\n\n```swift\nimport RomanNumeralKit\n```\n\n### Constants\n\nConstants are provided for all valid Roman numerals, from 1 to 3,999. You should never need to use an initializer\nunless you are doing conversions from other types.\n\nAll constants can be accessed directly by their using their uppercase Unicode characters.\n\n```swift\nprint(MMCDIX)           // Prints \"MMCDIX\"\nprint(MMCDIX.symbols)   // Prints \"[M, M, C, D, I, X]\"\n\nXCTAssertEqual(MMCDIX, RomanNumeral(.M, .M, .C, .D, .I, .X))    // True\n```\n\n### Conversions\n\nWe provide convenient mechanisms to convert `RomanNumeral`s to-and-from popular types.\n\nIt should be noted that these are true conversions: the backing values of `RomanNumeral` instances are groups of tally\nmarks. We do not hold `Int`references because it would not be in the spirit of the framework.\n\n#### Constructors\n\nConstructors are provided to convert `Int`s and `String`s to `RomanNumeral`s.\n\n```swift\nprint(RomanNumeral(from: 2409))     // Prints \"MMCDIX\"\nprint(RomanNumeral(from: \"MMCDIX\")) // Prints \"MMCDIX\"\n```\n\nWe also support conversions from `Int` and `String` literals when the `RomanNumeral` type can be inferred.\n\n```swift\nlet numeralFromInt: RomanNumeral = 2409\nlet numeralFromString: RomanNumeral = \"MMCDIX\"\n\nprint(numeralFromInt)       // Prints \"MMCDIX\"\nprint(numeralFromString)    // Prints \"MMCDIX\"\n```\n\n#### Properties\n\nInstance-level properties are provided to convert `RomanNumeral`s into `Int` and `String` values.\n\n```swift\nprint(MMCDIX.intValue)      // Prints \"2409\"\nprint(MMCDIX.stringValue)   // Prints \"MMCDIX\"\n```\n\nWe also provide various `*Convertible` protocols to allow types to return different `RomanNumeral` and\n`RomanNumeralSymbol` representations of themselves.\n\n### Arithmetic\n\nAddition, subtraction, and multiplication operations are supported (and required) thanks to our conformance to the\n`Numeric` protocol. We use algorithms that allow us to directly manipulate the Roman numeral symbols as opposed to\ndoing conversions to-and-from `Int`s.\n\n```swift\nXCTAssertEqual(MD + CMIX, MMCDIX)   // True\nXCTAssertEqual(MMM - DXCI, MMCDIX)  // True\nXCTAssertEqual(XI * CCXIX, MMCDIX)  // True\n```\n\n#### Performance\n\nOur committment to authenticity does have implications.\n\nThe following table compares the performance `Int` arithmetic operations to Roman numeral arithmetic operations on a \nnew MacBook Pro.\n\n| Operation (100x) | `Int`       | `RomanNumeral` | % Slower       |\n| ---------------- | ----------: | -------------: | -------------: |\n| Addition         | 0.00000127s |         0.151s | 11,889,663.78% |\n| Subtraction      | 0.00000151s |        0.0761s |  5,992,025.98% |\n| Multiplication   | 0.00000204s |        0.0575s |  4,527,459.06% |\n\nIt should be noted that this is much faster than any person from Ancient Rome could do arithmetic. Who can take issue\nwith progress?\n\n### Copyright Text\n\nThe most useful feature we provide is automatic formatting of Copyright text.\n\n```swift\nprint(MDCCLXXVI.copyrightText)  // Prints \"Copyright © MDCCLXXVI\"\n```\n\n### Additive Notation\n\nThe default notation for this framework is subtractive notation - that is what instances of `RomanNumeral`s represent.\nWe provide the `AdditiveRomanNumeral` struct for initialization of numerals using additive notation. We also support\nconversions between the notations.\n\nBoth notations implement the `RomanNumeralProtocol` protocol and support the same general interface.\n\n```swift\nlet additiveNumeral = AdditiveNotation(.M, .M, .C, .C, .C, .C, .V, .I, .I, .I, .I)\n\nprint(additiveNumeral)              // Prints \"MMCCCCVIIII\"\nprint(additiveNumeral.intValue)     // Prints \"2409\"\n\nXCTAssertEqual(additiveRomanNumeral.romanNumeral, MMCDIX)           // True\nXCTAssertEqual(MMCDIX.additiveRomanNumeral, additiveRomanNumeral)   // True\n```\n\n### Extensions\n\nWe provide a variety of extensions on existing Swift types to make common operations easier.\n\n#### `Calendar` \u0026 `DateComponent` Extensions\n\n`Calendar` objects, and the `DateComponents` they produce, are able to convert years into `RomanNumeral`s.\n\n```swift\nif let currentYear = Calendar.current.currentYearAsRomanNumeral {\n    print(currentYear)                  // Prints \"MMXIX\"\n    print(currentYear.intValue)         // Prints \"2019\"\n    print(currentYear.copyrightText)    // Prints \"Copyright © MMXIX\"\n}\n\nif let americasBirthYear = Calendar.current.yearAsRomanNumeral(fromDate: americasBirthDate) {\n    print(americasBirthYear)                // Prints \"MDCCLXXVI\"\n    print(americasBirthYear.intValue)       // Prints \"1776\"\n    print(americasBirthYear.copyrightText)  // Prints \"Copyright © MDCCLXXVI\"\n}\n```\n\n#### `Int` \u0026 `String` Extensions\n\nWe conform `Int` and `String` to the `*RomanNumeralConvertible` protocols to complete the ouroboros with these\nfoundational types.\n\n```swift\nprint(2409.romanNumeral)                    // Prints \"MMCDIX\"\nprint(2409.additiveRomanNumeral)            // Prints \"MMCCCCVIIII\"\nprint(\"MMCDIX\".romanNumeral)                // Prints \"MMCDIX\"\nprint(\"MMCCCCVIIII\".additiveRomanNumeral)   // Prints \"MMCCCCVIIII\"\n```\n\n## Authors\n\nKyle Hughes\n\n[![my twitter][social_twitter_image]][social_twitter_url]\n\n[social_twitter_image]: https://img.shields.io/badge/Twitter-@KyleHughes-blue.svg\n[social_twitter_url]: https://www.twitter.com/KyleHughes\n\n## Contributions\n\n`RomanNumeralKit` is not accepting source contributions at this time.\n\n## License\n\n`RomanNumeralKit` is available under the MIT License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylehughes%2Fromannumeralkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkylehughes%2Fromannumeralkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylehughes%2Fromannumeralkit/lists"}