set default territory
woylie opened this issue · comments
Is there any way to set the default territory for a language?
We have these settings:
use Cldr,
locales: ["ja", "en"],
default_locale: "ja"
"en" has US-style date formats, though, so we'd like to use "en_SE" instead. However, just changing it to:
use Cldr,
locales: ["ja", "en_SE"],
default_locale: "ja"
will only work if the user actually requests that territory. If the accept-language header requests "en" or any other territory, it will fall back to "en" instead of "en_SE". Is there any way to get around this?
TLDR; no automated way to do this.
Longer version: If the user requests en
, then the locale will be interpreted as en-US
as you have found. This is typical in CLDR - the default territory is that which has the largest number of native speakers of the given language. Sometimes this is surprising since it means that pt
is interpreted as pt-BR
because there are more native Portuguese speakers in Brazil than there are in Portugal.
Secondly, the formats (number, dates, times, units, ...) are linked to the locale (en-SE
for example), not en
or SE
. There are some situations where it's possible to override the territory code. For example, en-u-rg-SEzzzz
. But that does not affect locale formats like this for dates.
There is, as you have seen, a locale fallback mechanism. And ex_cldr
bends over backwards to resolve at least one locale - even if it's just the default locale. The rules can get complicated, but it will never fallback from en
to en-SE
- there's simply no way to infer that. The user is expected to provide the locale they want the information presented it. Basically, the user should send you en-SE
if thats what they want.
But ... that doesn't always work in the real world of course.
I think there are a couple of ways forward:
- Add your own plug that will replace
en
withen-SE
. It's the clearest and most unambiguous path I think. But if in the future you have users that actually want to useen
then this won't be appropriate. - If the data format you want is invariant - never changes no matter the locale, then you could just pass that format. For example:
iex> MyApp.Cldr.Date.to_string Date.utc_today(), format: "yyyy/MM/dd", locale: "en-SE"
{:ok, "2024/05/13"}
Do either of those show some hope for you? I'm open to ideas.