Internationalization
A deliberate bet against ICU: broad data and solid datetime, but no collation, plural rules or time zones.
0 Strong · 4 Solid · 4 Partial · 4 Emerging
Measured against: ICU/CLDR · Luxon · Babel · Folders: base/i18n(opens in a new tab) · base/culture(opens in a new tab) · base/datetime(opens in a new tab) · For programmers: this area's reference

Rethought from first principles
What Softanza kept from what works, and what it rethought, as the library wrote it down in its design documents and narrations.
The Softanza wayA locale says how a value is written down; a culture says how it will be read, and no meaning may be inferred from a locale code alone.
Kept from the best practice
- Standard identifiers: locales are created from IETF language tags such as ar-TN, and currencies are keyed by their ISO codes. source(opens in a new tab)
- ISO 8601 for data exchange and logs, and a 24-hour clock by default, for precision and international clarity. source(opens in a new tab)
- Unicode normalization in all four standard forms and script detection come from the shared Unicode library rather than home-made tables. source(opens in a new tab)
Rethought
- No ICU: the locale data the library actually answers is generated offline and committed with its source stamped, avoiding tens of megabytes of dependency. source(opens in a new tab)
- A locale formats; a culture interprets: a meaning such as red-for-loss is never derived from a locale code, since red means gain in some financial cultures. (planned) source(opens in a new tab)
- No facades: an operation honours the culture it was given or refuses, because ignoring a locale silently looks like success and returns wrong text. (planned) source(opens in a new tab)
- Time is modelled, not just measured: one timeline object holds events, spans and blocked zones, checks them on insertion and draws them, instead of stitched-together tools. source(opens in a new tab)
A deliberate bet against ICU: rather than vendor tens of MB of C++ and CLDR data, Softanza ships broad hand-tables (261 countries, 323 languages, 143 scripts, Qt-sourced), a solid engine-backed datetime core with rich Haro-side formatting, and a distinctive business/holiday calendar. That same choice leaves the CLDR crown jewels absent: no locale collation, no ICU MessageFormat or plural rules, no translation catalog, no locale-aware number/currency formatting, no timezone database (ToUTC is a no-op), and no non-Gregorian calendars.
What a crafter does with it, and what stands out
- Reference tables whose row coverage rivals CLDR (261 countries, 323 languages, 143 scripts)
- A business/holiday calendar with sprint and capacity planning that most i18n libraries lack
- An engine-backed datetime core with validated construction
- Natural-language epoch parsing (FromNaturalEpoch)
What is owed
- A timezone database (IANA/Olson zones, offset math, DST)
- Locale-aware number and currency formatting over the hint tables that already ship
- Fix the datetime / date / calendar / currency C22 test-runner collision (~450 assertions)
- Locale-aware collation, CLDR plural rules and a translation catalog
The Softanza way, run
What Softanza does differently in this area, shown by code taken from its narrations and guards, and run for this page.
A locale knows both its currency's ISO code and the sign people actually write, from one table the engine owns.
oFr = new stzLocale("fr_FR")
Then("the ISO code is the ISO code", oFr.CurrencyISOSymbol(), "EUR")
Then("...and the symbol is the euro sign", oFr.CurrencySymbol(), "€")THEN the ISO code is the ISO code [PASS] THEN ...and the symbol is the euro sign [PASS]
run on 2026-10-01 21:17 inside the library at commit 0e72e2e2c; taken from base/test/locale/02_currencysymbol_narrated.ring(opens in a new tab)
An Iranian locale starts its week on Saturday and names that day in Persian.
oFa = new stzLocale("fa_IR")
Then("the language itself resolves", oFa.LanguageName(), "persian")
Then("...and its first day is Saturday, as Iran counts it", oFa.NthDayOfWeek(1), "saturday")
Then("...named in Persian, not English", oFa.NativeNthDayOfWeek(1), "شنبه")THEN the language itself resolves [PASS] THEN ...and its first day is Saturday, as Iran counts it [PASS] THEN ...named in Persian, not English [PASS]
run on 2026-10-01 21:17 inside the library at commit 0e72e2e2c; taken from base/test/locale/01_languagename_narrated.ring(opens in a new tab)
A timeline refuses an event placed inside a blocked maintenance window, at the moment it is added.
oTimeline = new stzTimeLine("2024-01-01", "2024-12-31")
oTimeline.AddBlockedSpan("MAINTENANCE", "2024-06-15 09:00:00", "2024-06-15 17:00:00")
oTimeline.AddPoint("EVENT1", "2024-06-15 08:00:00") # OK
oTimeline.AddPoint("EVENT2", "2024-06-15 12:00:00") # Error: blockedPoint 'EVENT2' falls within a blocked span or blocked point
run on 2026-10-01 21:17 inside the library at commit 0e72e2e2c; taken from base/test/timeline/47_simple_blocked_maintenance_period.ring(opens in a new tab)
The articles of this area (1)
The lanes, one by one
Lanes and their notes are quoted as they were read at the source, on Read from the source on 2026-09-16.

