3
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?

More than 1 year has passed since last update.

Temporalで和暦にローカライズさせて表示する

Last updated at Posted at 2022-03-06

はじめに

Temporalは現状 TC39 proposal stage 3 のものを使用しています
今後APIが変わる可能性もあるのでご注意ください

TC39 proposalのTemporalをいじってみて、以下2つのような記事を書いたのですが、和暦の扱い方についてピックアップしてまとめます。

暦について

Temporalでは和暦のようなグレゴリオ暦以外の暦も扱うことができます。こちらについては別記事で説明しています。

和暦への変換

例えば、2022年3月6日の和暦の年号を表示したいということもあるかと思います。

このときに、グレゴリオ暦と和暦の対応表を作って、何月何日から何月何日は和暦だといくつみたいなかなりめんどくさい実装をしたり、年が変わったり年号が変わって、令和対応をしたという方もいるのではないかと思います。

Temporalでは複数の暦を扱うことができ、これの変換も機能として備わっているので、楽に変換ができそうです。
(正確にはIntl.Locale.prototype.calendarにあるようにTemporal外でも暦を扱うことができます)

やりかた

Intl.DateTimeFormatを使うと楽に和暦の表示ができます。
これはTemporalの機能ではないので、Dateでも使うことができますが、TemporalでPlainMonthDate等を使う場合はインスタンスにも暦の設定が必要になります。 (詳しくはこちら)

Temporal
const date = Temporal.Now.plainDate()
console.log(
  new Intl.DateTimeFormat([], {
    calendar: 'japanese',
    year: 'numeric',
  }).format(date)
)

// -> 令和4年
Date
const date = new Date()
console.log(
  new Intl.DateTimeFormat([], {
    calendar: 'japanese',
    year: 'numeric',
  }).format(date)
)

// -> 令和4年

DateTimeFormatの第1引数はlocalesで、空配列を指定するとブラウザーのロケールを使用します。

特定の言語に固定したい場合は、明示してあげます。

const date = Temporal.Now.plainDate('japanese')
console.log(
  new Intl.DateTimeFormat('en', {
    calendar: 'japanese',
    year: 'numeric',
  }).format(date)
)

// -> 4 Reiwa

注意点としては、第1引数のlocaleと、第2引数のオプションのcalendar: 'japanese'の意味は異なり、calendarは和暦を表しています。

詳しくはこちらで説明してあります。

和暦の計算

和暦の計算といっても、Temporalは内部的にはISO8601カレンダーを使用しているので、日付の計算をして、表示の部分で和暦に変換を行います。

const date = Temporal.Now.plainDate('japanese').subtract({ years: 3 }) // 3年前 (2019/3/6)
console.log(
  new Intl.DateTimeFormat([], {
    calendar: 'japanese',
    dateStyle: 'long',
  }).format(date)
)

// -> 平成31年3月6日

おまけ (Intl.DateTimeFormatのオプションについて)

TypeScriptのlib.es2020.intl.d.ts型定義ファイルに以下のように定義されています。
Temporalのpolyfillでは一部拡張されている部分はありますが、基本的にこのあたりを使用することができます。

interface DateTimeFormatOptions {
    calendar?: string | undefined;
    dayPeriod?: "narrow" | "short" | "long" | undefined;
    numberingSystem?: string | undefined;

    dateStyle?: "full" | "long" | "medium" | "short" | undefined;
    timeStyle?: "full" | "long" | "medium" | "short" | undefined;
    hourCycle?: "h11" | "h12" | "h23" | "h24" | undefined;
}

ただ、full, long, medium, shortなど、どういう結果になるのか分かりづらいので、それぞれ試してみます。

full

full
const dateTime = Temporal.Now.plainDateTimeISO()
const locale = 'ja'

const option = {
  dateStyle: 'full',
  timeStyle: 'full',
} as const
new TemporalIntl.DateTimeFormat(locale, option).format(dateTime)

// 2022年3月6日日曜日 23時27分04秒 日本標準時

long

long
const option = {
  dateStyle: 'long',
  timeStyle: 'long',
}
// 2022年3月6日 23:28:11 JST

medium

medium
const option = {
  dateStyle: 'medium',
  timeStyle: 'medium',
}
// 2022/03/06 23:31:25

short

short
const option = {
  dateStyle: 'short',
  timeStyle: 'short',
}
// 2022/03/06 23:32

hourCycle

short
const option = {
  timeStyle: 'short',
  hourCycle: 'h11'
}
// 午後11:35

dayPeriod

short
const option = {
  dayPeriod: 'long',
  hourCycle: 'h12'
}
// 夜中

formatMatcher

その他、細かく指定することもできます。
今回はlocale: 'en'で実行してみます。

const dateTime = Temporal.Now.instant()
const locale = 'en'
const option = {
  era: 'short',
  year: 'numeric',
  month: 'short',
  day: '2-digit',
  timeZoneName: 'long',
  hour: 'numeric',
  minute: '2-digit',
  second: 'numeric',
  hourCycle: 'h12',
} as const

const formatter = new TemporalIntl.DateTimeFormat(locale, option)

console.log(formatter.format(dateTime))
// Mar 06, 2022 AD, 11:46:40 at night Japan Standard Time

このようにformatterを定義してあげることで柔軟に表示させることができます。

参考

3
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
3
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?