{"id":29220188,"url":"https://github.com/erickguan/ffi-icu","last_synced_at":"2025-07-03T02:38:08.709Z","repository":{"id":901769,"uuid":"657870","full_name":"erickguan/ffi-icu","owner":"erickguan","description":"FFI wrappers for ICU. MRI extension with the dynamic C library.","archived":false,"fork":false,"pushed_at":"2024-07-08T22:39:14.000Z","size":308,"stargazers_count":37,"open_issues_count":4,"forks_count":22,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-11T16:16:22.388Z","etag":null,"topics":["cldr","i18n","ruby","unicode"],"latest_commit_sha":null,"homepage":"https://github.com/erickguan/ffi-icu","language":"Ruby","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/erickguan.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2010-05-09T17:42:00.000Z","updated_at":"2025-05-03T05:33:42.000Z","dependencies_parsed_at":"2023-07-05T19:02:18.218Z","dependency_job_id":"1b5934f4-d8f0-4dc4-a4eb-3893f972a014","html_url":"https://github.com/erickguan/ffi-icu","commit_stats":null,"previous_names":["jarib/ffi-icu"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/erickguan/ffi-icu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erickguan%2Fffi-icu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erickguan%2Fffi-icu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erickguan%2Fffi-icu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erickguan%2Fffi-icu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erickguan","download_url":"https://codeload.github.com/erickguan/ffi-icu/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erickguan%2Fffi-icu/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263248816,"owners_count":23437096,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cldr","i18n","ruby","unicode"],"created_at":"2025-07-03T02:38:08.026Z","updated_at":"2025-07-03T02:38:08.687Z","avatar_url":"https://github.com/erickguan.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ffi-icu\n\nFFI wrappers for [International Components for Unicode (ICU)][icu].\nICU provides comprehensive localization and security features.\nMajority personal computing devices, server operating systems and web browsers use ICU.\nICU builds on top of Unicode's Common Locale Data Repository (CLDR).\n\n## Gem\n\n[Rubygem](http://rubygems.org/gems/ffi-icu \"ffi-icu\")\n\n```\ngem install ffi-icu\n```\n\n## Dependencies\n\nICU.\n\nIf you get messages that the library or functions are not found, you can set some environment variables to tell ffi-icu where to find it, e.g.:\n\n```sh\n$ export FFI_ICU_LIB=\"icui18n.so\"\n$ export FFI_ICU_VERSION_SUFFIX=\"_3_8\"\n$ ruby -r ffi-icu program.rb\n```\n\n# Features\n\n## Character Encoding Detection\n\nExamples:\n\n```ruby\nmatch = ICU::CharDet.detect(str)\nmatch.name       # =\u003e \"UTF-8\"\nmatch.confidence # =\u003e 80\n```\n\nor\n\n```ruby\ndetector = ICU::CharDet::Detector.new\ndetector.detect(str) =\u003e #\u003cstruct ICU::CharDet::Detector::Match ...\u003e\n```\n\n* speed\n\n## Locale Sensitive Collation\n\nExamples:\n\n```ruby\nICU::Collation.collate(\"nb\", %w[å æ ø]) == %w[æ ø å] #=\u003e true\n```\n\nor\n\n```ruby\ncollator = ICU::Collation::Collator.new(\"nb\")\ncollator.compare(\"a\", \"b\")  #=\u003e -1\ncollator.greater?(\"z\", \"a\") #=\u003e true\ncollator.collate(%w[å æ ø]) #=\u003e [\"æ\", \"ø\", \"å\"]\n```\n\n## Text Boundary Analysis\n\nExamples:\n\n```ruby\niterator = ICU::BreakIterator.new(:word, \"en_US\")\niterator.text = \"This is a sentence.\"\niterator.to_a  #=\u003e [0, 4, 5, 7, 8, 9, 10, 18, 19]\n```\n\n## Number/Currency Formatting\n\nExamples:\n\n```ruby\n# class method interface\nICU::NumberFormatting.format_number(\"en\", 1_000) #=\u003e \"1,000\"\nICU::NumberFormatting.format_number(\"de-DE\", 1234.56) #=\u003e \"1.234,56\"\nICU::NumberFormatting.format_currency(\"en\", 123.45, 'USD') #=\u003e \"$123.45\"\nICU::NumberFormatting.format_percent(\"en\", 0.53, 'USD') #=\u003e \"53%\"\nICU::NumberFormatting.spell(\"en_US\", 1_000) #=\u003e \"one thousand\"\n\n# reusable formatting objects\nnumf = ICU::NumberFormatting.create('fr-CA')\nnumf.format(1000) #=\u003e \"1 000\"\n\ncurf = ICU::NumberFormatting.create('en-US', :currency)\ncurf.format(1234.56, 'USD') #=\u003e \"$1,234.56\"\n```\n\n## Time Formatting/Parsing\n\nExamples:\n\n```ruby\n# class method interface\nf = ICU::TimeFormatting.format(Time.mktime(2015, 11, 12, 15, 21, 16), {:locale =\u003e 'cs_CZ', :zone =\u003e 'Europe/Prague', :date =\u003e :short, :time =\u003e :short})\nf #=\u003e \"12.11.15 15:21\"\n\n# reusable formatting objects\nformatter = ICU::TimeFormatting.create(:locale =\u003e 'cs_CZ', :zone =\u003e 'Europe/Prague', :date =\u003e :long, :time =\u003e :none)\nformatter.format(Time.now)  #=\u003e \"25. února 2015\"\n```\n\n```ruby\n# reusable formatting objects\nformatter = ICU::TimeFormatting.create(:locale =\u003e 'cs_CZ', :zone =\u003e 'Europe/Prague', :date =\u003e :long, :time =\u003e :none)\nformatter.parse(\"25. února 2015\") #=\u003e Wed Feb 25 00:00:00 +0100 2015\n```\n\nFor skeleton formatting, visit the [Unicode date field symbol table](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table) page to help find the pattern characters to use.\n\n```ruby\nformatter = ICU::TimeFormatting.create(:locale =\u003e 'cs_CZ', :date =\u003e :pattern, :time =\u003e :pattern, :skeleton =\u003e 'MMMMY')\nformatter.format(Time.now)  #=\u003e \"únor 2015\"\n\nformatter = ICU::TimeFormatting.create(:locale =\u003e 'cs_CZ', :date =\u003e :pattern, :time =\u003e :pattern, :skeleton =\u003e 'Y')\nformatter.format(Time.now)  #=\u003e \"2015\"\n```\n\n## Duration Formatting\n\n```ruby\n# What the various styles look like\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :long)\nformatter.format({hours: 8, minutes: 40, seconds: 35})  #=\u003e \"8 hours, 40 minutes, 35 seconds\"\n\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :short)\nformatter.format({hours: 8, minutes: 40, seconds: 35})  #=\u003e \"8 hrs, 40 mins, 35 secs\"\n\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :narrow)\nformatter.format({hours: 8, minutes: 40, seconds: 35})  #=\u003e \"8h 40min. 35s.\"\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :digital)\nformatter.format({hours: 8, minutes: 40, seconds: 35})  #=\u003e \"8:40:35\"\n\n# How digital \u0026 non-digital formats deal with units \u003e hours\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :narrow)\nformatter.format({days: 2, hours: 8, minutes: 40, seconds: 35})  #=\u003e \"2d 8h 40min. 35s.\"\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :digital)\nformatter.format({days: 2, hours: 8, minutes: 40, seconds: 35})  #=\u003e \"2d 8:40:35\"\n\n# Missing or zero parts are omitted\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :long)\nformatter.format({days: 2, minutes: 40, seconds:0})  #=\u003e \"2 days, 40 minutes\"\n\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :digital)\nformatter.format({hours: 2, minutes: 40})  #=\u003e \"2:40\"\n\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :digital)\nformatter.format({minutes: 40, seconds: 7})  #=\u003e \"40:07\"\n\n# Sub-second parts are folded into seconds for digital display\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :digital)\nformatter.format({hours: 5, minutes: 7, seconds: 23, milliseconds: 98, microseconds: 997})  #=\u003e \"5:07:23.098997\"\n\n# Zero-extension of sub-second parts in digital style\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :digital)\nformatter.format({hours: 5, minutes: 7, seconds: 23, milliseconds: 400})  #=\u003e \"5:07:23.400\"\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :digital)\nformatter.format({hours: 5, minutes: 7, seconds: 23, milliseconds: 400, microseconds: 700})  #=\u003e \"5:07:23.400700\"\n\n# All fractional parts except the last are truncated\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'en-AU', style: :long)\nformatter.format({days: 2, hours: 7.3, minutes: 40.9, seconds:0.43})  #=\u003e \"2 days, 7 hours, 40 minutes, 0.43 seconds\"\n\n# With RU locale\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'ru', style: :long)\nformatter.format({hours: 1, minutes: 2, seconds: 3})  #=\u003e \"1 час 2 минуты 3 секунды\"\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'ru', style: :long)\nformatter.format({hours: 10, minutes: 20, seconds: 30})  #=\u003e \"10 часов 20 минут 30 секунд\"\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'ru', style: :narrow)\nformatter.format({hours: 1, minutes: 2, seconds: 3})  #=\u003e \"1 ч 2 мин 3 с\"\nformatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'ru', style: :narrow)\nformatter.format({hours: 10, minutes: 20, seconds: 30})  #=\u003e \"10 ч 20 мин 30 с\"\n```\n\n## Transliteration\n\nExample:\n\n```ruby\nICU::Transliteration.transliterate('Traditional-Simplified', '沈從文') # =\u003e \"沈从文\"\n```\n\n## Locale\n\nExamples:\n\n```ruby\nlocale = ICU::Locale.new('en-US')\nlocale.display_country('en-US') #=\u003e \"United States\"\nlocale.display_language('es') #=\u003e \"inglés\"\nlocale.display_name('es') #=\u003e \"inglés (Estados Unidos)\"\nlocale.display_name_with_context('en-US', [:length_short]) #=\u003e \"English (US)\"\nlocale.display_name_with_context('en-US', [:length_long])  #=\u003e \"English (United States)\"\n```\n\n[icu]: https://github.com/unicode-org/icu\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferickguan%2Fffi-icu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferickguan%2Fffi-icu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferickguan%2Fffi-icu/lists"}