aughtone-format
3.0.3indexedEnhances date, time, and string formatting with flexible styles and localization, aiming to improve existing string formatting functions. Offers basic, medium, and long format options.
Enhances date, time, and string formatting with flexible styles and localization, aiming to improve existing string formatting functions. Offers basic, medium, and long format options.
Aught One Format is a suite of Kotlin Multiplatform libraries designed to provide consistent, localized formatting for Dates, Times, Numbers, and other human-readable metrics across all platforms.
:datetime): DayOfWeek.displayName(width, locale) and Month.displayName(width, locale) (with a TextWidth { Full, Abbreviated } enum) expose the locale's day and month names — "Monday"/"Mon", "lundi", "mars" — without formatting a whole date.:datetime): TimeZone.displayName(instant, width, locale) gives the zone's daylight-aware specific name ("Eastern Standard Time" / "EST").:readable): List<String>.formatReadableList(locale, type) — "Monday, Wednesday, and Friday" / "lundi, mercredi et vendredi" — from CLDR list patterns, ~55 locales.iu) weekday names: idiomatic Inuktut day-words from the Inuktut Tusaalanga glossary, replacing the previous machine-generated phrases.ImageFormat.WEBP removed (breaking) (:viewable): it produced real WebP only on Android. Raster export is PNG or JPEG; cross-platform WebP is planned to return.:viewable): it previously returned empty bytes.aughtone-types 4.1.0, Compose Multiplatform 1.12.1.Aughtone Format 3.1.0 focuses on relative-time expressiveness and completing localization coverage:
This project follows a specialized 5-sector documentation hierarchy.
The library provides deep grammatical parity and full BCP 47 subtag fallback (e.g., en-ZA → en) for 59 supported language and region combinations:
For localized display names (time-zone names, and similar large translation sets) the library favours coverage over consistency. Byte-identical output on every platform was the original goal — the property bundled tables give — but it was judged not worth its cost. The new priority is that every reader sees text in their own language, even where the exact wording differs slightly across platforms and OS versions.
Why not simply bundle every translation? A complete localized dataset — every name in every supported language — is a large matrix (hundreds of KB even gzipped) and, unlike the library's own types, it cannot be dead-code-eliminated: a table reached by the reader's display language keeps every entry live. Bundling it in common code puts that weight on every target, including the browser and mobile, where the platform's runtime already holds the same CLDR data. So instead:
Intl is complete and bundling would only duplicate it.The trade is explicit: this delivers coverage, not consistency — four platform CLDR versions will word things a little differently and drift over time. Where consistency matters more than size (a desktop-only consumer), the bundled tables remain the option.
:datetime)val now = Clock.System.now()
// Format with styles (Short, Medium, Long, Full)
println(now.format(DateTimeStyle.Short, locale = Locale("en-US"))) // "4/23/26, 4:15 PM"
println(now.format(DateTimeStyle.Short, locale = Locale("en-CA"))) // "2026-04-23, 4:15 p.m."
:readable)Access the Governance Skills for specialized development rules.
:identifiers module: display formatters for canonical identifiers — MAC, UUID, IBAN, card/PAN, IPv4/IPv6/network, domain (Punycode decode), and phone (E.164 → national/international/RFC 3966). Each renders an already-canonical value in an alternative notation via String.formatX(notation).aughtone-types 4.0.0 (breaking): types is re-exported by the formatting modules, so its 4.0.0 API is part of this library's surface. Notably GeoBoundingBox is no longer a GeoGeometry, so rendering a bounding box as a path/SVG/WKT geometry has been removed from :viewable and :toolbox.LocalTime Relative Time: New RelativeDirection { Past, Present, Future, Nearest } enum and a direction parameter on LocalTime.formatReadableRelative resolve the ambiguity of a date-less clock time across midnight (modelled on ICU's Direction). The default is now Nearest (shortest distance on a 24-hour clock) — a behaviour change from the previous linear same-day math; pass RelativeDirection.Present for the old behaviour.LocalTime: A new LocalTime.formatReadableRelative(now: Instant, timeZone, …) overload resolves the time to a concrete occurrence relative to a dated anchor, so it can render day labels like "Yesterday"/"Today"/"Tomorrow".LocalDate relative formatting gains a "Shortly" label — the future mirror of "Recently" — for near-future dates within the nowThreshold window.az, eu, hy, ka, kk, lt, lv, sq, uz, iu), and Persian money symbol placement were silently falling back to English or formatting incorrectly — all now fixed, with a coverage-guard test preventing this class of regression.:datetime: Advanced formatting for kotlinx-datetime types with multi-locale support.:readable: Human-friendly formatting for metrics (abbreviations), ordinals, and data sizes.:identifiers: Display formatters for canonical identifiers — render a normalized MAC, UUID, IBAN, card number, IPv4/IPv6, domain, or phone number in an alternative notation.:viewable: Platform-agnostic vector graphics representation, styling, and path conversion (GeoJSON, SVG, WKT).:viewable-compose: Jetpack / Compose Multiplatform integration for rendering viewable vector graphics (Painters, ImageVectors).:toolbox: Shared utilities and common formatting primitives.LocalTime handling across midnight.| Family | Languages & Regions |
|---|
| Germanic | Afrikaans (af-ZA), Dutch (nl-NL), English (en-US), South African English (en-ZA), German (de-DE), Swiss German (de-CH), Danish (da-DK), Norwegian Bokmål (nb-NO), Norwegian Nynorsk (nn-NO), Swedish (sv-SE), Icelandic (is-IS) |
| Romance | French (fr-FR), Swiss French (fr-CH), Spanish (es-ES), Italian (it-IT), Swiss Italian (it-CH), Portuguese (pt-PT), Catalan (ca-ES), Galician (gl-ES), Romanian (ro-RO) |
| Slavic & Baltic | Russian (ru-RU), Ukrainian (uk-UA), Belarusian (be-BY), Polish (pl-PL), Czech (cs-CZ), Slovak (sk-SK), Bulgarian (bg-BG), Croatian (hr-HR), Serbian (sr-RS), Macedonian (mk-MK), Slovenian (sl-SI), Lithuanian (lt-LT), Latvian (lv-LV) |
| East & SE Asian | Japanese (ja-JP), Chinese (zh-CN), Traditional Chinese (zh-TW), Korean (ko-KR), Thai (th-TH), Vietnamese (vi-VN), Indonesian (id-ID), Malay (ms-MY) |
| South & Central Asian | Hindi (hi-IN), Armenian (hy-AM), Georgian (ka-GE), Kazakh (kk-KZ), Uzbek (uz-UZ) |
| Middle Eastern & African | Arabic (ar-EG), Hebrew (he-IL), Persian (fa-IR), Turkish (tr-TR), Azerbaijani (az-AZ), Swahili (sw-KE) |
| Other & Finno-Ugric | Finnish (fi-FI), Estonian (et-EE), Hungarian (hu-HU), Greek (el-GR), Basque (eu-ES), Albanian (sq-AL), Inuktitut (iu-CA) |
// Ordinals
println(123L.formatReadableOrdinal(Locale("en-US"))) // "123rd"
println(123L.formatReadableOrdinal(Locale("fr-FR"))) // "123e"
// Durations
println(1.5.hours.formatReadable(Locale("en-US"))) // "1.5 hours"
println(1.5.hours.formatReadable(Locale("es-ES"))) // "1,5 horas"
// Relative Time
println(instant.formatReadableRelative(locale = Locale("en-US"))) // "3 minutes ago"
println(instant.formatReadableRelative(locale = Locale("de-DE"))) // "vor 3 Minuten"
// Relative Time — direction-aware LocalTime (disambiguates a clock time across midnight)
val alarm = LocalTime(1, 0)
println(alarm.formatReadableRelative(now = LocalTime(23, 0), direction = RelativeDirection.Future)) // "in 2 hours"
// Data Sizes
println(1048576L.formatReadableDataSize()) // "1.0 MiB"
Surfaced from shared tags and platforms — no rankings paid for.