0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

i18nextで文言だけでなく日付フォーマットも言語切り替えへ対応する

0
Posted at

React Nativeアプリへi18nextを導入したあとも、画面には7月24日(金)のような日本語の日付が残っていました。翻訳JSONを増やすだけでは、Dateを直接整形している箇所は変わりません。

文言と日付が別々の言語にならないよう、言語判定を共通化してIntl.DateTimeFormatへ渡しました。

言語設定は3種類にする

設定値は日本語、英語、端末に従う、の3種類です。

export type LanguagePreference = "system" | "ja" | "en";

ユーザーの選択はSecureStoreへ保存します。systemの場合だけ、HermesのIntlから端末ロケールを読み取ります。

function detectSystemLanguage(): "ja" | "en" {
  const locale = Intl.DateTimeFormat().resolvedOptions().locale;
  return locale.toLowerCase().startsWith("ja") ? "ja" : "en";
}

この実装では、UIを変えた瞬間にi18n.changeLanguageも呼びます。

export async function setLanguagePreference(pref: LanguagePreference) {
  await SecureStore.setItemAsync(LANGUAGE_KEY, pref);
  const language = pref === "system" ? detectSystemLanguage() : pref;
  await i18n.changeLanguage(language);
}

日付を手書きしない

以前は月や曜日を配列で持ち、文字列を組み立てていました。これをIntl.DateTimeFormatへ置き換えます。

export function formatScheduleDate(value: Date, language: string) {
  const locale = language === "ja" ? "ja-JP" : "en-US";

  return new Intl.DateTimeFormat(locale, {
    month: "long",
    day: "numeric",
    weekday: "short",
  }).format(value);
}

コンポーネントではi18n.resolvedLanguageを使います。

const { t, i18n } = useTranslation();
const label = formatScheduleDate(date, i18n.resolvedLanguage ?? "ja");

resolvedLanguageを見るのは、フォールバックを含めてi18nextが実際に採用した言語へ揃えるためです。

翻訳対象を段階的に増やす

全画面を一度に置き換えると、翻訳漏れと画面崩れを同時に追うことになります。実際には次の順で進めました。

  1. 言語保存とダッシュボード、タブ
  2. 出欠登録の主要画面
  3. 設定、通知、管理画面と日付表示

日付対応を最後に回したことで、文字列の翻訳漏れとは別に確認できました。曜日が変わったか、月日の順序が変わったか、長い英語表記でレイアウトが崩れないかを見ます。

翻訳関数を通している文字列だけを数えても、多言語対応の完了判定にはなりません。日付、時刻、数値、エラーメッセージのように、JSONの外で生成する表示も言語設定へつなぐ必要があります。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?