Intl APIを使った国際化対応について

こんにちはhiro08です。

仕事で国際化対応することが多々あり、国際化に向けた実装について考える機会が多くあります。Webアプリケーションの国際化は、単に多言語化するだけではありません。例えば、日時や通貨のフォーマットは各国でそれぞれ違いますし、言語によってUIが大きく変わるケースもあります。

すぐに試せる例として、Twitterの言語設定をアラビア語に変更してください。アラビア語は右から左に文字を読むため、TwitterのUIもそれに応じて変わっています。

このように、国際化はその国や土地に合わせたデザイン (設計) をすることで適切にサービス提供する必要があります。

Intl APIについて

下記はMDNからの引用です。

Intl オブジェクトは、 ECMAScript の国際化 API名前空間で、言語に依存した文字列の比較、数値の書式化と、日付の書式化を提供します。 Intl オブジェクトは、いくつかのコンストラクターに加え、国際化コンストラクターや他の言語に関する関数に共通する機能へのアクセスを提供します。

各国に対応したフォーマットの実装は非常に難しいと感じます。ですが、Intl APIを使うことで各国に合わせたフォーマットに変換してくれます。下記は一例です。特に、ライブラリを使わず円表記に変換することができました。

const en = new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(123456789));
// ¥123,456,789

Intl APIはMDNで詳しく取り上げられています。

developer.mozilla.org

主なAPIの紹介

ここでは、実際に実践で使えそうなAPIを紹介していきます。

DateTimeFormat()

日時をフォーマットする場合は、Moment.jsやDay.jsを使うことが多いと思います。日時は国際化において優先して考慮すべき事項でしょう。Intl APIではDateTimeFomrt()としてサポートされています。引数にロケールの識別子を指定します。

const date = new Date();
const format = new Intl.DateTimeFormat('en-US').format(date);
// 6/10/2022

NumberFormat()

次に紹介するのが、数値のフォーマットです。下記例では、1~9が羅列した文字列をカンマ区切りでフォーマットしてくれます。また、currencyとして通貨のフォーマットに変換してくれるオプションもあります。

const number = 123456789
const formatNumber = new Intl.NumberFormat("en-Us").format(number);
// 123,456,789
const formatDollar = new Intl.NumberFormat('en-Us', { style: 'currency', currency: 'USD' }).format(number);
// $123,456,789.00

DisplayNames()

各国の表示名をフォーマットしてくれます。例えば、DisplayNames()にjaロケールを渡します。そして、初期化したregionの値はof()として、USを渡すとアメリカ合衆国に翻訳されました。

const region = new Intl.DisplayNames(['ja'], { type: 'region' });
const region = region.of('US');
// アメリカ合衆国

その他にも

  • PluralRules() -> 単数・複数
  • Intl.Segmenter() -> テキスト区切り
  • RelativeTimeFormat() -> 相対時刻
  • Locale() -> 各国のロケール識別子の取得

などがあります。Intl APIをある程度抑えておくことで、国際化に向けた実装範囲が見えてきます。

最後に

今回はIntl APIについて調べたまとめでした。国際化に向けた実装は予想以上に難しいです。ある程度、標準APIに乗っかることで、外部のライブライに依存せず国際化の実装が完結するのは便利だなと感じます。現在、日本でも多くのサービスが海外に向けた動き出しをしています。今後、国際化対応はエンジニアとってマストになるかもしれません。

参考

Intl - JavaScript | MDN

ep.115 『言語だけじゃない! 国際化対応の切り札 Intl API』 | UIT INSIDE - LINE UIT の開発者による「最新のフロントエンド」をキャッチアップできる Podcast

JavaScriptで連想配列に対して配列でfilterする方法

こんにちはhiro08です。

JavaScript連想配列に対して、配列のデータにマッチする値を取り出したい場面がありました。結果として連想配列に対してfilterをして、includesを使って配列にマッチするデータを取り出す方法で解決しました。そのときのメモです。

// 連想配列
const data = [
  {
    id: 1
  },
  {
    id: 2 
  },
  {
    id: 3 
  }
];

// 配列
const arrData = ["1", "2"];

// 配列にマッチするデータを検索
const filterData = data.filter((v) => arrData.includes(v.id));

console.log(filterData); // [ { id: 1 }, { id: 2 } ]

Day.jsで月末までの日数を割り出す方法

こんにちはhiro08です。

Day.jsで本日の日付から月末までの日数を知りたい機会がありました。結論としてはDay.jsに内包されているdiffを使えば簡単に割り出すことができたのでご紹介します。

const dayjs = require("dayjs");

const today = dayjs().format("YYYY-MM-DD"); //今日の日付を取得 2021-06-12
const monthEnd = dayjs().endOf("month").format("YYYY-MM-DD"); //今月末を取得 2021-06-30

console.log(dayjs(monthEnd).diff(today, "day")); // 差分18が取得できる

diffはday, week, month..等さまざまな形で指定することができます。

参考
day.js.org

Gatsby Cloud + AWS S3 + microCMSのビルドとデプロイ設定

この記事はJamstackその2 Advent Calendar 2020 21日目の記事です。

こんにちはhiro08です。

GatsbyJSのような、SSG(Static Site Generation)の機能を備えたフレームワークは、ビルドが非常に重要になってきます。そして、GatsbyJS向けにビルド周りの足回りや、URLプレビュー機能、アクセスコントロールといった便利な機能を提供しているサービスがあります。それがGatsby Cloudです。

続きを読む

私のWrite Code Every Day戦略

こんにちはhiro08です。

ソフトウェアエンジニアとして成長するためには?といった話題で頻繁に登場するのが、Write Code Every Dayでした。私はWrite Code Every Dayをそのままの直訳で、毎日コードを書こう = コードを書く習慣化しよう、といった単純な意味として捉えていました。

しかし、Wite Code Every Dayの元になったJohn Resig氏の原文を読んで、いくつかのルールを設けてることを知りました。以下は、Write Code Every Dayの原文のリンクです。
johnresig.com

続きを読む

2020年私のアウトプット総括

こんにちはhiro08です。

2020年もそろそろ終わりですね。去年の12月~今年の3月まで、カックさんのブログメンタリング(外部リンク)に参加した経緯もあって、アウトプットに力を入れた年でした。(まとめ記事書けなくてすみません!!)

上半期は順調でしたが、下半期になるとアウトプットの量が落ちてしまったのが反省点です。理由はモチベーションの維持ができなかったこと、アウトプットに対する心理的障壁が高くなってしまったことの2つです。この辺の反省点は、後日自分なりに処理していきます。

そんな私ですが今年のアウトプットを総括してみます。

続きを読む