Getting started¶
Requirements¶
- Node 20+ (Node 22+ for
duration(), which usesIntl.DurationFormat). - A modern browser works too — everything is built on the standard
IntlAPI.
- Java 11+. ICU4J
(
com.ibm.icu:icu4j) is pulled in transitively — it bundles its own ICU data, so there is no system library to install.
- PHP 8.4+ with the
intlextension (php -m | grep intl).
- Python 3.9+ and the system ICU development libraries (e.g.
libicu-devon Debian/Ubuntu,icu4con macOS). PyICU is installed as a dependency.
Install¶
<dependency>
<groupId>com.miloun</groupId>
<artifactId>cosmo</artifactId>
<version>0.1.0</version>
</dependency>
Gradle: implementation("com.miloun:cosmo:0.1.0").
Package name vs namespace
For a smooth v2 → v3 upgrade the Composer package keeps its long-standing
name salarmehr/cosmopolitan; only the namespace rebrands to
Miloun\Cosmo. Existing users bump the constraint to ^3.0 and run a
Salarmehr\Cosmopolitan → Miloun\Cosmo find/replace.
Quick start¶
Construct with a locale (and optional time zone / calendar / currency modifiers), then call methods on it.
import com.miloun.cosmo.Cosmo;
import com.miloun.cosmo.Modifiers;
// Modifiers(calendar, currency, timeZone) — any field may be null.
Cosmo c = new Cosmo("en_AU", new Modifiers(null, null, "Australia/Sydney"));
c.country(); // "Australia"
c.money(1234.5); // "$1,234.50" (currency inferred from region)
c.number(1234567.89); // "1,234,567.89"
c.flag(); // "🇦🇺"
use Miloun\Cosmo\Cosmo;
$c = new Cosmo('en_AU', ['timeZone' => 'Australia/Sydney']);
$c->country(); // "Australia"
$c->money(1234.5); // "$1,234.50" (currency inferred from region)
$c->number(1234567.89); // "1,234,567.89"
$c->flag(); // "🇦🇺"
PHP 8.4 lets you call a method directly on new Cosmo(...) without wrapping
parentheses, or use the cosmo() helper: cosmo('en_AU')->country().
Locale format
Underscore locales (en_AU) and BCP-47 tags (en-AU), including Unicode
extensions like fa-IR-u-nu-latn-ca-buddhist, are all accepted. JavaScript
prefers the hyphenated form; PHP, Python, and Java accept either.
Constructing without a string¶
Both factory helpers exist in every port (snake_case in Python; typed
Subtags/Modifiers value classes in Java):
Negotiating against your own locales
Python and Java can pick the best of your supported locales for a user (CLDR language distance, not prefix matching) — see Negotiation & names.
Ready for the details? Head to the Guide.