# Converti un codice di locale in tutti i formati

> Converti codici di lingua e paese fra BCP 47, POSIX, ICU, Java, Android, Apple e gettext, anche a decine. Anteprima di date e numeri, errori hreflang segnalati.

Strumento gratuito nel browser (nessun upload): https://www.mauriziofonte.it/strumenti/convertitore-locale

**it-IT**, **it_IT.UTF-8**, **values-it-rIT**, **it.lproj**: lo stesso italiano d'Italia scritto in quattro modi diversi, uno per ogni piattaforma. Incolla un codice o un elenco intero e ottieni tutte le forme corrette, la verifica che il codice esista davvero e un'**anteprima di come quella lingua scrive date, numeri e valute**. Tutto nel browser.

## Come usare il convertitore

1. **Incolla uno o più codici** - Va bene qualunque forma: pt-BR, pt_BR.UTF-8, values-b+sr+Latn, zh_Hant_TW, es-419. Per convertirne tanti insieme mettine uno per riga, oppure incolla un intero header Accept-Language.
2. **Leggi la scomposizione** - Per ogni codice vedi lingua, sistema di scrittura e paese con il loro nome in italiano, la forma canonica e quella più completa (per esempio zh-TW diventa zh-Hant-TW).
3. **Copia la forma che ti serve** - Trovi una riga per ogni piattaforma: BCP 47 per HTML e JavaScript, POSIX e gettext per Linux e PHP, ICU e Java per i backend, qualificatore Android, cartella Apple .lproj e valore per hreflang.
4. **Controlla anteprima e avvisi** - L'anteprima mostra data, ora, numeri, valuta, percentuali e forme del plurale come le scrive il browser in quella lingua. Gli avvisi segnalano codici scritti male, codici storici e valori che Google non accetta in hreflang.
5. **Esporta** - Con un elenco di codici ottieni una tabella completa da copiare o scaricare in CSV o JSON, pronta per un file di configurazione.

## Perché lo stesso locale si scrive in tanti modi

Un **locale** è la combinazione di lingua, eventuale sistema di scrittura e paese che un programma usa per tradurre i testi e formattare date, numeri e valute. Il problema è che ogni mondo lo scrive a modo suo. Il web e JavaScript usano i tag **BCP 47** con il trattino (*pt-BR*). Linux e le librerie C usano la forma **POSIX** con il trattino basso e la codifica (*pt_BR.UTF-8*). Java e ICU usano il trattino basso senza codifica. Android vuole un prefisso e una r davanti al paese (*values-pt-rBR*), e quando c'è anche lo script cambia sintassi del tutto (*values-b+sr+Latn*). Apple nomina le cartelle *pt-BR.lproj*.

Finché si lavora su una sola piattaforma va tutto bene. Quando una stessa lista di lingue deve finire nell'HTML, nel backend, nell'app Android e in quella iOS, la conversione a mano produce errori che non danno nessun messaggio: la traduzione semplicemente non viene caricata e l'utente vede l'inglese.

I convertitori che si trovano online ricostruiscono di solito tre forme e si fermano. Qui ogni codice viene prima **validato con l'API Intl del browser**, la stessa che userà il tuo codice JavaScript, poi scomposto e ricomposto per ogni piattaforma, compresi i casi difficili: script, varianti, codici di regione numerici, codici storici. E l'anteprima ti fa vedere subito se hai scelto il locale giusto: se le cifre decimali escono con il punto invece che con la virgola, il problema è nel codice, non nel tuo programma.

## Le forme, piattaforma per piattaforma

**BCP 47 (RFC 5646).** Lo standard del web: lingua minuscola, script con l'iniziale maiuscola, regione maiuscola, separati da trattini. *sr-Latn-RS* è serbo in alfabeto latino, in Serbia. Si usa nell'attributo *lang* dell'HTML, nelle API Intl di JavaScript, negli header HTTP e in quasi tutte le librerie moderne.

**POSIX e gettext.** La forma delle variabili LANG e LC_ALL: *sr_RS.UTF-8@latin*. Lingua e paese con il trattino basso, poi la codifica dopo il punto e lo script come modificatore dopo la chiocciola. È anche il nome delle cartelle di traduzione gettext usate da PHP, WordPress e molti progetti open source.

**ICU e Java.** ICU scrive *sr_Latn_RS*; Java accetta la stessa idea con Locale.forLanguageTag("sr-Latn-RS") e restituisce sr_RS_#Latn con toString. Per evitare sorprese conviene passare sempre da forLanguageTag.

**Android.** Le cartelle delle risorse usano *values-it-rIT* per lingua e paese. Quando servono script o codici di tre lettere si passa alla sintassi BCP 47 con il prefisso b+: *values-b+sr+Latn+RS*. Usare la forma vecchia con uno script fa ignorare la cartella senza errori.

**Apple.** Le cartelle .lproj di iOS e macOS usano gli identificatori di lingua di Apple: *pt-BR.lproj*, *zh-Hans.lproj*. Per il cinese Apple distingue sullo script e non sul paese.

**hreflang.** Google vuole il codice della lingua in ISO 639-1 e, se serve, il paese in ISO 3166-1 alpha-2. Un codice valido in BCP 47 può non esserlo qui: lo segnaliamo.

## Gli errori più comuni (e come li segnaliamo)

**en-UK al posto di en-GB.** Il codice ISO del Regno Unito è GB, non UK. Le API Intl dei browser correggono da sole en-UK in en-GB, e per questo l'errore passa inosservato nei test. Ma dove il codice viene confrontato come testo (un hreflang, una cartella Android o iOS, un file di configurazione del backend) en-UK non corrisponde a nulla. Ti mostriamo la forma corretta e ti avvisiamo.

**Il trattino basso nell'HTML.** *lang="it_IT"* non è un tag valido: lo standard vuole il trattino. Il browser lo tratta come lingua sconosciuta, con conseguenze su sillabazione, sintesi vocale e controllo ortografico.

**Codici storici.** Ebraico, indonesiano e yiddish avevano codici diversi (*iw*, *in*, *ji*) poi sostituiti da *he*, *id*, *yi*. Java li ha restituiti nella forma vecchia per anni, e molti database li conservano ancora. Il norvegese generico *no* va quasi sempre scritto *nb* (bokmål) o *nn* (nynorsk).

**Cinese per paese invece che per scrittura.** *zh_TW* e *zh_CN* indicano il paese, ma quello che conta è la scrittura: tradizionale (*zh-Hant*) o semplificata (*zh-Hans*). Mostriamo sempre la forma completa con lo script.

**Regioni numeriche in hreflang.** *es-419* (spagnolo dell'America Latina) è un ottimo tag BCP 47, ma Google non accetta codici di regione numerici in hreflang. Bisogna usare *es* oppure un tag per ogni paese.

**Maiuscole e minuscole.** *IT-it* o *pt-br* funzionano quasi ovunque perché i tag non distinguono le maiuscole, ma alcuni confronti fatti come stringhe falliscono. La forma canonica è sempre quella mostrata in cima.

## Glossario

- **Locale**: La combinazione di lingua, scrittura e paese che un programma usa per tradurre e formattare.
- **BCP 47**: Lo standard IETF per i tag di lingua usati sul web (RFC 5646 più l'elenco dei sottotag).
- **Sottotag di script**: Quattro lettere che indicano l'alfabeto: Latn (latino), Cyrl (cirillico), Hans e Hant (cinese semplificato e tradizionale).
- **POSIX locale**: La forma usata da Linux e dalle librerie C: lingua_PAESE.codifica@modificatore, per esempio it_IT.UTF-8.
- **CLDR**: Il Common Locale Data Repository di Unicode: i dati che dicono come ogni lingua scrive date, numeri e plurali.
- **Forma massimizzata**: Il tag completato con i sottotag più probabili: zh-TW diventa zh-Hant-TW, sr diventa sr-Cyrl-RS.
- **Accept-Language**: L'header HTTP con cui il browser dichiara le lingue preferite, con un peso per ognuna (q=0.9).
- **hreflang**: L'attributo che indica a Google le versioni linguistiche di una pagina.

## Domande frequenti

### Che differenza c'è fra pt-BR e pt_BR?

Indicano la stessa cosa, portoghese del Brasile, in due convenzioni diverse. pt-BR è la forma BCP 47 usata dal web e da JavaScript; pt_BR è quella di POSIX, Java e ICU. Il convertitore te le dà entrambe, insieme a quelle per Android e Apple.

### Quale forma devo usare nell'attributo lang dell'HTML?

Sempre BCP 47, con il trattino: lang="it" o lang="it-IT". Il trattino basso non è valido nell'HTML e fa trattare la pagina come lingua sconosciuta.

### Come si scrive una cartella values di Android con lo script?

Con la sintassi b+: values-b+sr+Latn per il serbo in alfabeto latino, values-b+zh+Hant+TW per il cinese tradizionale di Taiwan. La forma con la r (values-sr-rRS) non può contenere lo script.

### en-UK è un codice valido?

No, anche se molti lo usano. Il Regno Unito nello standard ISO è GB, quindi il tag corretto è en-GB. I browser lo correggono da soli quando passa dalle API Intl, ma nei confronti fra stringhe, nelle cartelle delle app e in hreflang en-UK resta un codice sbagliato.

### Posso usare es-419 in hreflang?

No. es-419 è un tag BCP 47 valido per lo spagnolo dell'America Latina, ma Google accetta in hreflang solo codici di paese a due lettere. Usa es come lingua generica oppure un tag per ogni paese, come es-MX o es-AR.

### Che cos'è la forma massimizzata?

È il tag completato con le parti sottintese più probabili secondo i dati CLDR. zh-TW diventa zh-Hant-TW perché a Taiwan si scrive in cinese tradizionale. È utile per capire cosa intende davvero un codice corto.

### Perché l'anteprima mostra le date in un formato diverso da quello che mi aspetto?

Perché viene dal tuo browser, che usa i dati CLDR della sua versione. Browser e sistemi diversi possono avere dati leggermente diversi, per esempio nella posizione del simbolo della valuta. È proprio il motivo per cui vale la pena guardarla prima di pubblicare.

### Posso convertire un header Accept-Language?

Sì. Incollalo così com'è, per esempio it-IT,it;q=0.9,en;q=0.8: il convertitore lo divide nelle singole lingue, rispetta l'ordine dei pesi e converte ognuna.

### Funziona con decine di codici insieme?

Sì. Incolla un codice per riga e ottieni una tabella con tutte le forme, da copiare o scaricare in CSV o JSON. Comodo quando devi allineare l'elenco delle lingue fra web, backend e app.

### I codici che incollo vengono inviati da qualche parte?

No. Validazione, conversione e anteprima usano le API Intl del browser e avvengono sul tuo dispositivo. Nessun dato viene inviato a un server.

## Fonti usate

- [RFC 5646, Tags for Identifying Languages](https://www.rfc-editor.org/rfc/rfc5646): sintassi dei tag BCP 47
- [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry): elenco ufficiale dei sottotag e dei codici deprecati
- [Unicode CLDR](https://cldr.unicode.org/): dati di formattazione e sottotag probabili
- [Android, supporto di lingue e culture](https://developer.android.com/guide/topics/resources/multilingual-support): qualificatori values e sintassi b+
- [Google Search Central, versioni localizzate](https://developers.google.com/search/docs/specialty/international/localized-versions): codici accettati in hreflang
- [ECMAScript Internationalization API (ECMA-402)](https://tc39.es/ecma402/): Intl.Locale e Intl.getCanonicalLocales

---
Uno strumento di Maurizio Fonte, senior backend engineer. Tutti gli strumenti: https://www.mauriziofonte.it/strumenti/
