5キロメートルや10ポンドなどの測定値をフォーマットする方法
距離、重量、温度、その他の測定値をロケールに適した形式と単位で表示する
はじめに
測定値は、意味を持たせる単位とともに数量を伝えます。5キロメートルは距離を示し、10ポンドは重量を示し、20度は温度を示します。測定値を表示するアプリケーションは、ユーザーが理解できる形式で数値と単位の両方を表示する必要があります。
ロケールによって測定値のフォーマットは異なります。アメリカ人は文脈に応じて「5 km」または「5 kilometers」と書きます。ドイツ人は異なる空白の規則で「5 km」と書くかもしれません。同じ測定値でも、ロケールや望ましい詳細度に応じて「5 km」、「5km」、または「5 kilometers」と表示されることがあります。一部の地域ではメートル法の単位を使用し、他の地域ではヤード・ポンド法の単位を使用しますが、単位のフォーマットもロケールによって異なります。
JavaScriptはIntl.NumberFormat APIを提供し、ロケールに適した単位フォーマットで測定値をフォーマットします。このレッスンでは、距離、重量、温度、体積、速度などの測定値を、任意のロケールに対して正しい単位表示でフォーマットする方法を説明します。
測定値には文脈のための単位が必要
多くの文脈において、単位のない数値は意味を持ちません。数値5は、5キロメートル、5マイル、5メートル、または5フィートを表す可能性があります。ユーザーは測定されている単位を知らなければ、その値を解釈できません。
単位は数値と一貫して表示される必要があります。「5キロメートル」と書く場合、単位「キロメートル」は不可欠な情報です。「10ポンド」と書く場合、単位「ポンド」は測定値が通貨ではなく重量であることを識別します。
同じ種類の測定に対して異なる単位系が存在します。距離はキロメートル、マイル、メートル、フィート、またはその他の単位で測定できます。重量はキログラム、ポンド、オンス、またはグラムで測定できます。温度は摂氏、華氏、またはケルビンで測定できます。アプリケーションは、使用する単位系をユーザーの期待に合った方法でフォーマットする必要があります。
Intl.NumberFormatで単位をフォーマットする
Intl.NumberFormatコンストラクタは、オプションにstyle: 'unit'を渡すと単位フォーマッタを作成します。また、unitオプションを使用して、単位識別子でフォーマットする単位を指定する必要があります。
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
console.log(formatter.format(5));
// Output: "5 km"
これにより、米国英語用のフォーマッタが作成され、値がキロメートル単位で表示されます。format()メソッドは、数値をキロメートル単位の略語付きの文字列に変換します。
unitオプションは、標準化された単位識別子を受け入れます。これらの識別子は、ハイフンで区切られた小文字の単語を使用します。一般的な識別子には、kilometer、meter、mile、pound、kilogram、celsius、fahrenheit、liter、gallonなどがあります。
const distanceFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
const weightFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'pound'
});
console.log(distanceFormatter.format(5));
// Output: "5 km"
console.log(weightFormatter.format(10));
// Output: "10 lb"
各フォーマッタは、指定された単位に対して適切な単位略語を自動的に適用します。どの略語がどの単位識別子に対応するかを知る必要はありません。
ロケールが単位のフォーマットを決定する
ロケールパラメータは、スペース、区切り文字、単位略語を含む単位のフォーマット方法を制御します。同じ単位でも、ロケールによって異なる出力が生成されます。
const usFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
const deFormatter = new Intl.NumberFormat('de-DE', {
style: 'unit',
unit: 'kilometer'
});
const frFormatter = new Intl.NumberFormat('fr-FR', {
style: 'unit',
unit: 'kilometer'
});
console.log(usFormatter.format(5));
// Output: "5 km"
console.log(deFormatter.format(5));
// Output: "5 km"
console.log(frFormatter.format(5));
// Output: "5 km"
キロメートルはロケール間で類似した略語を使用しますが、スペースと区切り文字の規則は異なります。Intl APIは、これらのロケール固有のフォーマット規則を自動的に処理します。
単位表示の詳細度を制御する
unitDisplayオプションは、単位を略語形式、完全形式、または最小形式で表示するかを制御します。このオプションは3つの値を受け入れます。略語の場合は"short"、完全な単位名の場合は"long"、最小表示の場合は"narrow"です。
const shortFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'short'
});
const longFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
const narrowFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'narrow'
});
console.log(shortFormatter.format(5));
// Output: "5 km"
console.log(longFormatter.format(5));
// Output: "5 kilometers"
console.log(narrowFormatter.format(5));
// Output: "5km"
short形式は、「km」や「lb」などの標準的な略語を使用します。long形式は、「kilometers」や「pounds」などの完全な単位名を使用します。narrow形式は、スペースを削減またはなくした最小表示を使用します。unitDisplayを指定しない場合、デフォルトはshortです。
ロケールは、長形式の単位の表示方法に影響します。完全な単位名は翻訳され、各言語の文法規則に合わせて調整されます。
const enFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
const deFormatter = new Intl.NumberFormat('de-DE', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
const esFormatter = new Intl.NumberFormat('es-ES', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
console.log(enFormatter.format(5));
// Output: "5 kilometers"
console.log(deFormatter.format(5));
// Output: "5 Kilometer"
console.log(esFormatter.format(5));
// Output: "5 kilómetros"
各ロケールは、単位名に適切な翻訳と文法形式を提供します。
重量測定のフォーマット
重量測定では、pound、kilogram、ounce、gramなどの単位識別子を使用します。これらの識別子は、距離単位と同じように機能します。
const poundFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'pound'
});
const kilogramFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilogram'
});
console.log(poundFormatter.format(10));
// Output: "10 lb"
console.log(kilogramFormatter.format(10));
// Output: "10 kg"
重量を長形式でフォーマットして、完全な単位名を表示できます。
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'pound',
unitDisplay: 'long'
});
console.log(formatter.format(1));
// Output: "1 pound"
console.log(formatter.format(10));
// Output: "10 pounds"
フォーマッターは、値に基づいて単数形と複数形を自動的に処理します。1ポンドは単数形を使用し、10ポンドは複数形を使用します。
温度測定のフォーマット
温度測定では、celsiusやfahrenheitなどの単位識別子を使用します。これらの単位は、短形式では度記号付きでフォーマットされます。
const celsiusFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius'
});
const fahrenheitFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'fahrenheit'
});
console.log(celsiusFormatter.format(20));
// Output: "20°C"
console.log(fahrenheitFormatter.format(68));
// Output: "68°F"
長形式では、完全な温度目盛名が表示されます。
const celsiusFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius',
unitDisplay: 'long'
});
const fahrenheitFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'fahrenheit',
unitDisplay: 'long'
});
console.log(celsiusFormatter.format(20));
// Output: "20 degrees Celsius"
console.log(fahrenheitFormatter.format(68));
// Output: "68 degrees Fahrenheit"
温度のフォーマットには、各目盛に適切な度の用語が自動的に含まれます。
体積測定のフォーマット
体積測定では、liter、gallon、milliliter、fluid-ounceなどの単位識別子を使用します。これらは他の単位タイプと同様に機能します。
const literFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'liter'
});
const gallonFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'gallon'
});
console.log(literFormatter.format(2));
// Output: "2 L"
console.log(gallonFormatter.format(2));
// Output: "2 gal"
体積単位は、ロケール固有のスペルで長形式表示もサポートしています。
const usFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'liter',
unitDisplay: 'long'
});
const gbFormatter = new Intl.NumberFormat('en-GB', {
style: 'unit',
unit: 'liter',
unitDisplay: 'long'
});
console.log(usFormatter.format(2));
// Output: "2 liters"
console.log(gbFormatter.format(2));
// Output: "2 litres"
イギリス英語ロケールでは「litres」を使用し、アメリカ英語では「liters」を使用します。
複合単位のフォーマット
複合単位は、2つの単純な単位を「per」の関係で組み合わせたものです。時速マイルや時速キロメートルなどの速度測定では、複合単位を使用します。100キロメートルあたりのリットルなどの燃費測定でも、複合単位を使用します。
複合単位識別子は、2つの単純な単位を-per-で結合します。例えば、mile-per-hourはマイルと時間を組み合わせ、kilometer-per-hourはキロメートルと時間を組み合わせます。
const mphFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'mile-per-hour'
});
const kphFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer-per-hour'
});
console.log(mphFormatter.format(60));
// Output: "60 mph"
console.log(kphFormatter.format(100));
// Output: "100 km/h"
各複合単位は、両方の単位部分を組み合わせた適切な略語で表示されます。
長い形式では、複合単位が完全な名前とロケールに適した前置詞で表示されます。
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'mile-per-hour',
unitDisplay: 'long'
});
console.log(formatter.format(60));
// Output: "60 miles per hour"
フォーマッターは、ロケールに適した文法を使用して複合単位のフレーズを自動的に構築します。
利用可能な単位識別子を取得する
Intl.supportedValuesOf()メソッドは、JavaScript環境でサポートされているすべての単位識別子の配列を返します。このメソッドは、引数として文字列'unit'を受け取ります。
const units = Intl.supportedValuesOf('unit');
console.log(units);
// Output: Array of unit identifiers like:
// ["acre", "bit", "byte", "celsius", "centimeter", "day",
// "degree", "fahrenheit", "fluid-ounce", "foot", "gallon",
// "gram", "hectare", "hour", "inch", "kilogram", "kilometer",
// "liter", "meter", "mile", "millimeter", "ounce", "pound",
// "second", "stone", "week", "yard", ...]
返される配列には、フォーマットに使用できるすべての単純な単位が含まれます。この配列の任意の識別子をunitオプションで使用できます。
このメソッドは、特定の単位がサポートされているかどうかを確認する必要がある場合や、ユーザーに利用可能な単位のリストを提供する場合に役立ちます。
const units = Intl.supportedValuesOf('unit');
const hasKilometer = units.includes('kilometer');
const hasPound = units.includes('pound');
console.log(hasKilometer);
// Output: true
console.log(hasPound);
// Output: true
フォーマッターを作成する前に特定の単位を確認することで、異なるサポートレベルの環境に対応できます。
数値フォーマットオプションと組み合わせる
単位フォーマッターは、他のIntl.NumberFormatスタイルと同じ数値フォーマットオプションをサポートしています。小数点以下の桁数、有効桁数、その他の数値プロパティを制御できます。
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
maximumFractionDigits: 2
});
console.log(formatter.format(5.123));
// Output: "5.12 km"
console.log(formatter.format(5.5));
// Output: "5.5 km"
フォーマッターは、単位を追加する前に丸めと小数点以下の桁数のルールを適用します。
大きな数値を千の位の区切り記号付きでフォーマットできます。
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
console.log(formatter.format(12345.67));
// Output: "12,345.67 km"
すべての標準的な数値フォーマット機能が単位フォーマットで動作します。
ユーザーのロケールに合わせて測定値をフォーマットする
特定のロケールをハードコーディングする代わりに、ユーザーのブラウザ言語設定を使用できます。navigator.languageプロパティは、ユーザーの優先ロケールを返します。
const userLocale = navigator.language;
const formatter = new Intl.NumberFormat(userLocale, {
style: 'unit',
unit: 'kilometer'
});
console.log(formatter.format(5));
// Output varies by user's locale
このアプローチでは、各ユーザーの書式設定の期待に応じて測定値が表示されます。異なるユーザーには、それぞれのロケール規則に従って書式設定された同じ測定値が表示されます。
アプリケーションで測定値を表示する
ユーザーに測定値を表示する場所であれば、どこでも単位フォーマッターを使用できます。これには、距離や体重を表示するフィットネスアプリケーション、気温を表示する天気アプリケーション、容量を表示するレシピアプリケーション、速度を表示するナビゲーションアプリケーションなどが含まれます。
const distanceFormatter = new Intl.NumberFormat(navigator.language, {
style: 'unit',
unit: 'kilometer',
maximumFractionDigits: 1
});
const distance = 5.234;
document.getElementById('distance').textContent = distanceFormatter.format(distance);
// Displays: "5.2 km" (or locale equivalent)
書式設定された文字列は、他の文字列値と同様に機能します。テキストコンテンツ、属性、またはユーザーに情報を表示する任意のコンテキストに挿入できます。
単位フォーマッターの再利用
新しいIntl.NumberFormatインスタンスを作成するには、ロケールデータの読み込みとオプションの処理が必要です。同じロケールと単位で複数の測定値を書式設定する場合は、フォーマッターを一度作成して再利用してください。
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
const distances = [1.5, 3.2, 5.0, 10.8];
distances.forEach(distance => {
console.log(formatter.format(distance));
});
// Output:
// "1.5 km"
// "3.2 km"
// "5 km"
// "10.8 km"
このパターンは、値ごとに新しいフォーマッターを作成するよりも効率的です。多数の測定値を含む配列やリストを書式設定する場合、パフォーマンスの差が顕著になります。