Intl.DateTimeFormat.prototype.formatToParts()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2017.
Intl.DateTimeFormat.prototype.formatToParts()
メソッドは、ロケールを考慮した Intl.DateTimeFormat
フォーマッターが生成する文字列のロケールを考慮した書式化を可能にします。
試してみましょう
構文
formatToParts(date);
引数
date
省略可-
書式化する日付。
返値
Array
で、書式化された日付のパーツを含むオブジェクトの配列です。
解説
formatToParts()
メソッドは、日付文字列のフォーマットをカスタマイズするときに役立ちます。これは、ロケール特有の部分を保持しながら、カスタム文字列を構築できるロケール特有のトークンを含むオブジェクトの Array
を返します。formatToParts()
メソッドが返却する構造は、このようになります。
[
{ type: "day", value: "17" },
{ type: "weekday", value: "Monday" },
];
渡される可能性がある type は以下のとおりです。
- day
-
日付として使用される文字列。たとえば、 "
17
"。 - dayPeriod
-
日付期間として使用される文字列。たとえば、 "
AM
", "PM
", "in the morning
", "noon
" など。 - era
-
時代として使用される文字列。たとえば、"
BC
" や "AD
"。 - fractionalSecond
-
小数点以下の秒として使用される文字列です。例えば "
0
" や "00
" や "000
" です。 - hour
-
時刻として使用される文字列。たとえば "
3
" や "03
"。 - literal
-
日付や時刻の区切りとして使用される文字列。たとえば "
/
"、",
"、"o'clock
"、"de
"。 - minute
-
分として使用される文字列。たとえば、"
00
"。 - month
-
月として使用される文字列。たとえば、"
12
"。 -
カレンダーの表現が year ではなくyearNameである場合、関連する4桁のグレゴリオ暦の年に使用される文字列です。例えば "
2019
" です。 - second
-
秒として使用される文字列。たとえば、"
07
" や "42
"。 - timeZoneName
-
タイムゾーン名として使用される文字列。たとえば、"
UTC
"。 - weekday
-
曜日として使用される文字列。たとえば、"
M
" や "Monday
"、"Montag
"。 - year
-
年として使用される文字列。たとえば、"
2012
" や "96
"。 - yearName
-
関連するコンテキストで yearName に使用される文字列、例えば "
geng-zi
" など。
ポリフィル
この機能のポリフィルは、提案リポジトリーから利用できます。
例
DateTimeFormat
は、直接操作できないローカライズされた透過的でない文字列を出力します。
var date = Date.UTC(2012, 11, 17, 3, 0, 42);
var formatter = new Intl.DateTimeFormat("en-us", {
weekday: "long",
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
fractionalSecondDigits: 3,
hour12: true,
timeZone: "UTC",
});
formatter.format(date);
// "Monday, 12/17/2012, 3:00:42.000 AM"
しかし、多くのユーザーインターフェイスでは、この文字列の書式をカスタマイズしたいという要望があります。 formatToParts
メソッドは、文字列を部品単位で提供することで、 DateTimeFormat
フォーマッターによって生成された文字列のロケールを意識した書式設定ができるようになります。
formatter.formatToParts(date);
// return value:
[
{ type: "weekday", value: "Monday" },
{ type: "literal", value: ", " },
{ type: "month", value: "12" },
{ type: "literal", value: "/" },
{ type: "day", value: "17" },
{ type: "literal", value: "/" },
{ type: "year", value: "2012" },
{ type: "literal", value: ", " },
{ type: "hour", value: "3" },
{ type: "literal", value: ":" },
{ type: "minute", value: "00" },
{ type: "literal", value: ":" },
{ type: "second", value: "42" },
{ type: "fractionalSecond", value: "000" },
{ type: "literal", value: " " },
{ type: "dayPeriod", value: "AM" },
];
これで情報は個別に利用可能になり、カスタマイズされた方法で再び書式化して連結することができます。例えば、Array.prototype.map()
、アロー関数、 switch 文、テンプレートリテラル、 Array.prototype.join()
などを使用しています。
var dateString = formatter
.formatToParts(date)
.map(({ type, value }) => {
switch (type) {
case "dayPeriod":
return `<b>${value}</b>`;
default:
return value;
}
})
.join("");
これにより、 formatToParts()
メソッドを使用する際に、日の部分が太字になります。
console.log(formatter.format(date));
// "Monday, 12/17/2012, 3:00:42.000 AM"
console.log(dateString);
// "Monday, 12/17/2012, 3:00:42.000 <b>AM</b>"
名前付きの年と混合カレンダー
名前付きの年を使用している暦もあります。例えば、中国やチベットの暦では、 60 年周期の干支を使用しています。これらの年は、グレゴリオ暦の年と関連付けて識別されます。このような場合、 formatToParts()
の結果は、通常は年が存在するはずなのに、年の項目ではなく、 4 桁のグレゴリオ暦の年を含む relatedYear
の項目を含むことになります。バッグの中の項目を (任意の値で) year
に設定すると、年と yearName
グレゴリオ暦の relatedYear
の両方が得られます。
let opts = { year: "numeric", month: "numeric", day: "numeric" };
let df = new Intl.DateTimeFormat("zh-u-ca-chinese", opts);
df.formatToParts(Date.UTC(2012, 11, 17, 3, 0, 42));
// return value
[
{ type: "relatedYear", value: "2012" },
{ type: "literal", value: "年" },
{ type: "month", value: "十一月" },
{ type: "day", value: "4" },
];
year
オプションがバッグ内で設定されていない場合 (任意の値に設定されている場合)、結果には relatedYear
のみが含まれます。
let df = new Intl.DateTimeFormat("zh-u-ca-chinese");
df.formatToParts(Date.UTC(2012, 11, 17, 3, 0, 42));
// 返値
[
{ type: "relatedYear", value: "2012" },
{ type: "literal", value: "年" },
{ type: "month", value: "十一月" },
{ type: "day", value: "4" },
];
year
を出力したい場合は、 .format()
は一般的にこれらを並べて表示することができます。
let df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"});
df.format(Date.UTC(2012, 11, 17, 3, 0, 42));
// 返値
2012壬辰年
これにより、ロケールとカレンダーを両方の format
で混在させることも可能になります。
let df = new Intl.DateTimeFormat("en-u-ca-chinese", { year: "numeric" });
let date = Date.UTC(2012, 11, 17, 3, 0, 42);
df.format(date);
// 返値
2012(ren - chen);
および formatToParts
の場合
let opts = { month: "numeric", day: "numeric", year: "numeric" };
let df = new Intl.DateTimeFormat("en-u-ca-chinese", opts);
let date = Date.UTC(2012, 11, 17, 3);
df.formatToParts(date)[
// 返値
({ type: "month", value: "11" },
{ type: "literal", value: "/" },
{ type: "day", value: "4" },
{ type: "literal", value: "/" },
{ type: "relatedYear", value: "2012" })
];
仕様書
Specification |
---|
ECMAScript Internationalization API Specification # sec-Intl.DateTimeFormat.prototype.formatToParts |
ブラウザーの互換性
BCD tables only load in the browser