# `Locale`

A CLDR locale, written as its BCP 47 tag, `en-GB`.

[Places](types.md#places); not ordered; since Jadpo 0.1.0.

## Make one

Pick one of its variants, `Locale.af`.

`text.parse(raw, as: Locale)` reads one from its text; text that isn't one at all fails `malformed`, such as `english` or `xx-YY`.

This operation gives one: `locale.from_accept_language`.

## Variants

534 variants. Each is its code in lower case, with `_` for every other character: `Locale.af` is written `af`. The first 40: `af`, `af-NA`, `af-ZA`, `ak`, `ak-GH`, `am`, `am-ET`, `ar`, `ar-AE`, `ar-BH`, `ar-DJ`, `ar-DZ`, `ar-EG`, `ar-EH`, `ar-ER`, `ar-IL`, `ar-IQ`, `ar-JO`, `ar-KM`, `ar-KW`, `ar-LB`, `ar-LY`, `ar-MA`, `ar-MR`, `ar-OM`, `ar-PS`, `ar-QA`, `ar-SA`, `ar-SD`, `ar-SO`, `ar-SS`, `ar-SY`, `ar-TD`, `ar-TN`, `ar-YE`, `as`, `as-IN`, `az`, `az-AZ`, `az-Latn`.

## Text, JSON and storage

`text.from` writes its canonical text, the one form `text.parse` reads back. JSON sends its canonical text as a string.

| Text | JSON |
|---|---|
| `en-GB` | `"en-GB"` |
| `fr-FR` | `"fr-FR"` |

It is stored in one column named for the field, of type `text`. `fr-FR` is stored as `'fr-FR'`.

## Shown to people

`text.format(value, locale:)` shows it to people in their locale.

With `locale: Locale.en_gb`:

| Value | Shown |
|---|---|
| `en-GB` | `British English` |
| `fr-FR` | `French (France)` |

## Operations

- `list.sort_by(items: List<T>, key: Function<T, K>, locale: Locale?) -> List<T>`: A new list ordered by `key`, smallest first; items with equal keys keep their order. Text keys go by code point, or by `locale`'s rules when it is given.
- `locale.direction(value: Locale) -> TextDirection`: Which way `value`'s text runs, as CLDR says: `TextDirection.left_to_right` for English, `TextDirection.right_to_left` for Arabic and Hebrew.
- `locale.from_accept_language(header: Text?) -> Locale`: The supported `Locale` an `Accept-Language` header asks for, or `locales { default: }` when it names none the application supports, is malformed or is `none`.
- `temporal.format_relative(value: T, now: Instant, zone: Zone?, locale: Locale) -> PresentationText`: `value` shown to a person in `locale` as how long ago it was from `now`: "just now", minutes, "Today at", "Yesterday at", the weekday, then the long date.
- `text.lower(value: Text, locale: Locale?) -> Text`: `value` in lower case, by `locale`'s rules when it is given.
- `text.pick(value: LocalisedText, locale: Locale) -> Text`: The text in `value` for `locale`: its entry, else the entry of its language (the locale CLDR's likely subtags give for the language first), else the application's default locale's, else the first.
- `text.upper(value: Text, locale: Locale?) -> Text`: `value` in upper case, by `locale`'s rules when it is given.

Like every standard type, it also has the contract's own operations: `text.parse`, `text.from`, `text.format`, `json.read`, `json.write` and `==`. It isn't ordered, so `<` and sorting don't take it. [Every standard type meets one contract](../topics/every-standard-type-meets-one-contract.md) says how they work.
