# `PhoenixKitProjects.L10n`
[🔗](https://github.com/BeamLabEU/phoenix_kit_projects/blob/v0.14.0/lib/phoenix_kit_projects/l10n.ex#L1)

Tiny locale-aware date/time formatting helpers used by the projects UI.

Unlike `Calendar.strftime(d, "%b %d, %Y")`, the output of these helpers
is safe to translate: the three-letter month labels and the surrounding
string template all go through Gettext.

The 12 month labels are intentionally listed as separate `gettext/1`
calls so the string-extraction task picks them up into the .pot file.
Don't collapse them into a map-based lookup.

# `current_content_lang`

```elixir
@spec current_content_lang() :: String.t() | nil
```

The current content-display language code.

Reads `Gettext.get_locale/1` against the parent app's gettext backend
— that's the locale Phoenix's pipeline set on the URL prefix
(`/bs/...` → `"bs"`). Used by the localized-read helpers on schemas
to pick the right entry from the `translations` JSONB; the helpers
themselves fall back to the primary-language column when the locale
has no override or is `nil`, so this never needs to validate the
result against `enabled_languages/0`.

# `format_date`

```elixir
@spec format_date(Date.t() | DateTime.t() | NaiveDateTime.t() | nil) ::
  String.t() | nil
```

Formats a `Date`/`DateTime` as `Mon DD, YYYY`. Returns `nil` for nil.

# `format_datetime`

```elixir
@spec format_datetime(DateTime.t() | nil) :: String.t() | nil
```

Formats as `Mon DD, YYYY at HH:MM`. For DateTimes.

# `format_month_day_time`

```elixir
@spec format_month_day_time(DateTime.t() | nil) :: String.t() | nil
```

Formats as `Mon DD HH:MM` — month, day, and time only.

# `format_time`

```elixir
@spec format_time(DateTime.t()) :: String.t()
```

24-hour time string as `HH:MM` (locale-neutral).

# `short_month`

```elixir
@spec short_month(1..12) :: String.t()
```

Short 3-letter month name, translated (`Jan`, `Feb`, ...).

# `valid_translations_shape?`

```elixir
@spec valid_translations_shape?(any()) :: boolean()
```

True when `translations` matches the documented JSONB shape:

    %{optional(String.t()) => %{optional(String.t()) => String.t()}}

i.e. an outer map keyed by language code (`"es-ES"`) whose values
are maps keyed by translatable field name (`"name"`) with string
values. `%{}` and `nil` are valid (empty / unset). Used by every
schema with a `translations` column to add a changeset-level guard
so a programmatic caller can't persist garbage that the read
helpers would silently fall back through.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
