Locale-correct output
Dates, numbers, plurals, addresses and names as a locale actually writes them, and why a model that gets the language right still gets the format wrong.
A model that writes fluent German will still write 3/4/2026 and 1,234.56 in the middle of it. That is not a language failure and no amount of prompting for “better German” fixes it, because the two things are learned from different evidence. Fluency comes from an enormous amount of German prose. Format comes from whatever numeric and date strings happened to appear in training data, which is dominated by English-language sources, code, logs and spreadsheets — none of which are German.
These pages are about that gap. Each one takes a formatting convention that a locale actually uses, shows what the convention is and where it diverges from the default a model reaches for, and then says which part of the job belongs to the model and which part belongs to a formatting library that has the table. The general answer is that the model should produce values and a renderer should produce strings; the useful part is knowing exactly where the seam is for each kind of value, because for names and honorifics it is not where you would guess.
Reordering Extracted Text From a Multi-Column Arabic Document
Why a two-column Arabic PDF extracts as interleaved half-sentences, and how to recover the real reading order from the glyph positions.
10 min read
Why Vector Search Ranks a Mistranslated Chunk Above the Correct One
An embedding scores topical and stylistic proximity, not truth, which is why a smooth mistranslation outranks an accurate awkward one.
9 min read
Formatting Numbers in the Indian Lakh-Crore System
The Indian grouping rule is three digits then twos, not threes all the way, and that single difference is where generated output goes wrong.
8 min read
Why AI Output Uses the Wrong Numerals for Arabic Text
Two different digit sets are both called Arabic, three if you count the Persian variant, and asking for the wrong one is why the digits come back Western.
9 min read
Fixing Date Format Confusion Between DD/MM and MM/DD in AI Output
Why an ambiguous numeric date is the most expensive locale bug in generated text, what ISO 8601 fixes, and the twelve days a year it does not.
9 min read
Where the Currency Symbol Goes in Different Locales
Symbol position, spacing and negative-value convention are per-locale data in CLDR, not a rule of thumb about Europe and America.
8 min read
Formatting an Address Correctly for a Given Country
Three worked postal formats — US, Japan, Germany — showing the field order a model defaults to and where each country actually diverges.
9 min read
Why AI Gets Name Order Wrong in Family-Name-First Cultures
The failure is not that models put the family name last, it is that they helpfully reorder a name that was already correct.
9 min read
Getting 24-Hour or 12-Hour Time Right in AI-Generated Text by Locale
Which locales prefer which clock is published data in CLDR, and models default to the US 12-hour form regardless of the language they are writing.
8 min read
Getting the Decimal Comma or Point Right by Locale in AI Output
The characteristic bug is half-right output — the decimal mark swapped to a comma while the thousands separator stays a comma too.
8 min read
Validating Postal Code Formats Across Countries
A sourced reference for postal code patterns in a labelled set of countries, including the ones that have no postal code system at all.
9 min read
Using the Correct Honorific and Title in AI-Generated Text
An honorific encodes a relationship, not politeness, and dropping it in translation deletes information the source sentence carried.
9 min read
Getting Metric or Imperial Units Right in AI Output by Locale
Why generated text arrives in the wrong measurement system for its reader, which locales are actually affected, and the exact conversion factors to use.
9 min read
Why AI Calendars Default to the Wrong Start of Week
The first day of the week is locale data, not a constant, and generated calendar code almost always hard-codes it.
8 min read
Formatting Phone Numbers Correctly by Country
There are two correct formats for every phone number — one to store and one to show — and AI output routinely produces a third that is neither.
9 min read
Using the Japanese Era Calendar in AI-Generated Dates
How gengo years map to Gregorian ones, why the first year of an era is not written 1, and what breaks when an era ends.
8 min read
Formatting Negative Numbers Correctly by Locale
Minus sign, parentheses or a trailing sign — which one is correct is decided by CLDR locale data and by whether the document is an accounting statement.
8 min read
Why AI-Generated Forms Break on Two-Character Surnames
The minimum-length rule that models add to every name field rejects millions of real surnames, and the character-class rule rejects millions more.
9 min read
Formatting Large Numbers for a Chinese-Reading Audience
Chinese groups digits in ten-thousands and hundred-millions, which means there is no word for million and no natural place for a Western thousands separator.
8 min read
Why AI-Generated Business Cards Get the Layout Backwards
A Japanese or Korean business card puts the organisation above the person, uses both sides for two languages, and is not the size a Western template assumes.
8 min read
Formatting a Salutation Correctly Across Languages
Whether a salutation takes a comma, a colon or no punctuation is a language rule, and in German it also decides whether the next word is capitalised.
8 min read
Why AI Gets the Week Number Wrong Across Locales
ISO 8601 and the US convention define week 1 differently, so around New Year the same date sits in two different weeks of two different years.
9 min read
Formatting Fiscal Year Dates Correctly by Country
Fiscal years start in different months in different countries, and the label FY2026 is named for the ending year in some of them and the starting year in others.
9 min read
Why an AI-Generated Table Sorts Accented Names Incorrectly
A default string sort orders by code point, which puts every accented name after Z, and even a correct locale sort gives different answers in Swedish and German.
9 min read
Why Language Detection Fails on Code-Switched Text
Detectors score a whole string at once, so a sentence containing two languages returns whichever one supplied more characters — and no signal that anything was mixed.
9 min read
Setting a Confidence Threshold for Automatic Language Detection
How to pick the score below which you stop trusting a language detector, using your own labelled strings rather than a number from a blog post.
10 min read
Telling Closely Related Languages Apart Automatically
Why character-level detectors collapse on language pairs that share most of their orthography, and which features actually separate them.
9 min read
Detecting the Dominant Language in a Mixed-Script Document
A block-by-block detection pass for documents that switch script mid-page, using the Unicode Script property to partition before any classifier runs.
10 min read
What to Do When Automatic Language Detection Is Wrong
A ranked ladder of signals to use when detection confidence is low but a response still has to go out, and the rule for when to ask the user.
9 min read
NFC and NFKC Normalization: What Actually Differs
Canonical normalization preserves the text and compatibility normalization deliberately destroys distinctions — which is why one belongs in storage and the other in search keys.
9 min read
Why Vietnamese Diacritics Break Search Matching
Two identical-looking Vietnamese strings can hold different code points because the language stacks two marks on one vowel — here is the byte-level reason and the fix.
9 min read
The Turkish Dotted and Dotless I Problem in AI Text
Turkish has four I letters and default case conversion knows about two, which corrupts Turkish text and breaks protocol comparisons on Turkish machines.
9 min read
Normalizing German Umlauts and Eszett for Search
German search has to match Müller, Mueller and Muller, and the ß-to-ss expansion that makes it work changes the string's length.
10 min read
Stripping French Accents for Search Without Losing Meaning
Accent-insensitive French search merges real word pairs like où and ou, so folding belongs in the recall layer and never in the ranking layer.
10 min read
Handling the Spanish Ñ in Text Processing Pipelines
Ñ is a letter of the Spanish alphabet, not an N with a decoration, and pipelines that treat it as a variant produce wrong sort order and embarrassing search results.
9 min read
Handling Nordic Characters Å Ä Ö Correctly in AI Output
In Swedish, å ä ö are the last three letters of the alphabet and sort after z — the same code points that German sorts next to a, which is why locale-less sorting is always wrong for somebody.
10 min read
Building Diacritic-Insensitive Search Without Breaking Precision
A decomposition-and-strip fold that makes cafe match café, plus the languages where stripping marks changes which word you asked for.
9 min read
Combining Characters and Precomposed Characters: What Actually Differs
Why two strings that render identically compare unequal, worked through one character at the byte level.
8 min read
Normalizing Accented Names for Database Matching
How to fold accented names into a matching key without merging two families whose surnames differ only by a diacritic.
9 min read
Why Polish Diacritics Break Naive String Sorting
Why ł, ż and ś end up after z in a code-point sort, and the three places you have to change to get Polish order back.
8 min read
Why AI-Generated Filenames Break on Accented Characters
A file written with an accented name on one operating system cannot be opened by the same name on another, and the reason is which normalisation form reached the disk.
9 min read
Normalizing Right-to-Left Text Before Search Indexing
A pipeline for Arabic and Hebrew that strips diacritics, unifies letter variants and removes bidi controls before a single token is indexed.
10 min read
Why Emoji Skin Tone Modifiers Break Text Comparison
A toned emoji contains the untoned one as a prefix, so equality fails and substring matching succeeds — and normalisation does not fix either.
8 min read
Normalizing Curly and Straight Quotation Marks Across Languages
Why a single find-and-replace on quotation marks is wrong in German, French and any language where U+2019 is a letter.
9 min read
Why Korean Text Comparison Fails Without NFC Normalization
One Hangul syllable is either one code point or three jamo, and the arithmetic that connects them explains every Korean equality bug.
9 min read
Arabic Dual and Plural Noun Forms in AI-Generated Text
Arabic counts in singular, dual and three kinds of plural, and the rules invert above ten in a way generated text routinely gets wrong.
9 min read
Russian Noun Case Agreement in AI-Generated Text
The specific error where an adjective stays in the nominative while its noun is inflected, traced through all six cases of one phrase.
9 min read
How ICU MessageFormat Plural Rules Work
The six CLDR plural categories, what each one means in a language that uses it, and the four things about them that are not obvious.
10 min read
Other topics
- LLM fundamentals & architecture
- Tokens, tokenization & context windows
- Prompt engineering
- Reasoning models & test-time compute
- Multimodal AI: vision, audio, video
- RAG & retrieval
- Embeddings & vector search
- AI agents & tool use
- Structured output & function calling
- Fine-tuning & post-training
- Local inference errors, string by string
- Running local models day to day
- Testing code that calls an LLM
- Snapshot and property testing for model output
- Regression suites for prompts
- Eval gates in CI
- Flaky tests against a model
- Determinism and the cost of testing
- Contract and streaming tests
- Testing tool calls and retrieval
- Inference, serving & latency
- Rolling out a prompt change
- Testing AI systems in practice
- Forecasting a time series
- Machine learning on tabular data
- Geospatial data and models
- Understanding audio that is not speech
- Understanding video
- Core computer vision tasks
- Machine learning on graphs
- Point clouds and 3D
- Evaluation, benchmarks & LLM-as-judge
- Sensor and IoT data
- Logs and event streams
- Models over biological sequences
- Machine learning on molecules
- Embedding and searching code
- Extracting invoices and purchase orders
- Receipts, statements and tax forms
- Insurance policies and contracts
- Deeds, court filings and patents
- Extracting from medical records
- Observability & LLMOps
- CVs, certificates and identity documents
- Shipping, customs and technical documents
- Meetings, email, chat and filled-in forms
- Building an extraction pipeline
- Business, property and inspection documents
- Contract clauses and insurance claims
- Regulated and compliance documents
- Consumer, travel and closing documents
- Mapping one chat API onto another
- SDK and framework migrations
- Hallucination & failure modes
- Re-embedding and model deprecation
- Cutting over between providers
- Parity gaps, shims and legacy endpoints
- Moving between model versions
- Migrating vector stores and caches
- Mapping capabilities and parameters
- Migrating pipelines and agents
- Contracts, runbooks and rollback
- Auditing a codebase before a cutover
- Compliance and fine-tune migration
- LLM cost engineering
- Routing, cost tracking and multi-tenancy
- What a migration does to your prompts
- AI security & prompt injection
- Privacy, compliance & data residency
- AI governance, policy & society
- Building reliable AI applications
- AI hardware, GPUs & compute
- Open-weight models & local inference
- AI for developers & coding agents
- AI in industry: vertical playbooks
- AGI, superintelligence, alignment & the long future
- Machine learning foundations
- NLP fundamentals & classical tasks
- Data engineering for AI
- Synthetic data & dataset curation
- AI product design & UX
- Search, ranking & recommendation
- Enterprise adoption & change management
- AI careers, skills & teams
- Reading AI research
- AI in science & discovery
- Robotics & embodied AI
- AI economics, markets & business models
- AI myths, hype & media literacy
- Context engineering
- Shipping AI features: patterns & anti-patterns
- Build it: end-to-end AI tutorials
- Python for AI: hands-on recipes
- TypeScript, React and the web
- Frameworks and SDKs
- Errors and troubleshooting
- AI facts, numbers and statistics
- The history of AI
- The maths behind AI
- Architectures beyond the transformer
- Reinforcement learning
- Diffusion and generative media
- Speech, audio and voice engineering
- Benchmarks, one at a time
- AI search visibility
- Infrastructure and operations
- Databases and storage for AI
- Knowledge graphs and structured knowledge
- Classical ML in production
- Regulation, jurisdiction by jurisdiction
- Prompt recipes and pattern library
- AI for people who do not write code
- Writing, media and creative work
- Edge and on-device AI
- Interpretability and model internals
- Field notes
- OpenAI model behaviour
- Claude model behaviour
- Gemini model behaviour
- Llama model behaviour
- Mistral model behaviour
- Qwen model behaviour
- DeepSeek model behaviour
- Cohere model behaviour
- Grok model behaviour
- Small model behaviour
- Hybrid model architectures
- Token cost by language and script
- Transliteration, romanization and script handling
- Multilingual generation quality
- Multilingual pipelines
- The EU AI Act, article by article
- AI under the GDPR and EU data law
- US AI regulation, state and sector
- International AI governance and standards
- AI litigation and enforcement
- Running AI workloads on AWS
- Running AI workloads on Google Cloud
- Running AI workloads on Azure
- AI at the edge: Workers, Vercel and Netlify
- Serving models on Kubernetes
- Operating AI infrastructure
- Quantization formats and what they cost
- llama.cpp, flag by flag
- Ollama and the desktop local-model runtimes
- Local models on Apple Silicon
- Hardware for local inference
- Running speech and embedding models locally
- Model files, adapters and conversion
- VRAM arithmetic for local models