目次
Temporalとは
TemporalとはJavaScriptのDateオブジェクトの長年の問題点を解決するために設計された、次世代の日時APIです。
JavaScriptの言語仕様として組み込まれるため、Temporalを使用すればdate-fnsやDay.jsなどのライブラリの依存関係が不要になります。
現在のChromeやMicrosoft Edgeの最新バージョンであるv144がTemporalに対応するようになったため、利用できるブラウザが増えました。
new Date()はデメリットが多い
JavaScriptで日時の生成にnew Date()を使用しているケースが多いと思いますが、Dateには以下の7つの問題点があるため、使用することはオススメしません。
1. 不変性ではない
Dateは不変性ではないため、意図せず参照渡しのような形になって値を変更してしまいます。
Temporalだと日付を変更しても、元の日付は変更されません。
// ❌ Date - 元のオブジェクトが変更されてしまう
const date1 = new Date('2024-01-15')
const date2 = date1
date2.setDate(20)
console.log('Date1:', date1.getDate()) // 20 (意図せず変更されている!)
console.log('Date2:', date2.getDate()) // 20
// ✅ Temporal - 常に新しいオブジェクトが返される
const temporal1 = Temporal.PlainDate.from('2024-01-15')
const temporal2 = temporal1.add({ days: 5 })
console.log('Temporal1:', temporal1.toString()) // 2024-01-15 (変更されない)
console.log('Temporal2:', temporal2.toString()) // 2024-01-202. タイムゾーンの扱いが曖昧
Dateはローカルタイムゾーンに依存、明示的な制御が困難です。
Temporalでは国別のタイムゾーンを明示的に扱えて、サマータイム(DST)も自動的に正しく処理されるので、間違った日時を設定してしまうことがありません。
// ❌ Date - タイムゾーンの扱いが曖昧
const date = new Date('2024-03-10T02:30:00')
console.log('Date:', date.toString())
// ローカルタイムゾーンに依存、明示的な制御が困難
// ✅ Temporal - タイムゾーンを明示的に扱える
const zonedDateTime = Temporal.ZonedDateTime.from({
timeZone: 'America/New_York',
year: 2024,
month: 3,
day: 10,
hour: 2,
minute: 30
})
console.log('Temporal:', zonedDateTime.toString())
// サマータイム(DST)も自動的に正しく処理される3. 文字列へ変換しにくい
Dateだと直接yyyy-mm-ddの文字列に変換できませんが、Temporalなら直接変換できます。
// ❌ Date - 文字列に変換しにくい
const date = new Date('2024-03-21')
const yyyy = date.getFullYear()
const mm = String(date.getMonth() + 1).padStart(2, '0')
const dd = String(date.getDate()).padStart(2, '0')
const text = `${yyyy}-${mm}-${dd}`
console.log(text) // 2024-03-21
// ✅ Temporal - 文字列に変換しやすい
const date = Temporal.PlainDate.from('2024-03-21')
console.log(date.toString()) // 2024-03-214. ハイフン(-)とスラッシュ(/)のどちらも使える
Dateはハイフン(-)とスラッシュ(/)のどちらも日付形式が使えますが、結果が変わってしまいます。
この違いによってバグが発生することがあるのですが、Temporalだとハイフン(-)のみ使用可能となっているため、前述のような表記による問題は発生しません。
// ❌ Date - ハイフンとスラッシュのどちらも使用可
const date1 = new Date('2024-03-21')
console.log(date1) // Thu Mar 21 2024 09:00:00 GMT+0900 (日本標準時)
const date2 = new Date('2024/03/21')
console.log(date2) // Thu Mar 21 2024 00:00:00 GMT+0900 (日本標準時)
// ✅ Temporal - ハイフンは使用可だが、スラッシュは使用不可
const date1 = Temporal.PlainDate.from('2024-03-21') // エラーにならない
const date2 = Temporal.PlainDate.from('2024/03/21') // エラーになる5. 0を1月とする一貫性のない動作
Dateはnew Date(2026, 1, 1)のように書くと1を2月にするという一貫性のない動作になります。これはバグ発生の要因になりやすいです。
Temporalではこのように月の始まりを0とする動作をしないので、1月は1であるという一貫性のある動作になります。
// ❌ Date - 一貫性のない動作
new Date(2026, 0, 1) // 2026年1月1日 (月が0始まり)
new Date(2026, 1, 1) // 2026年2月1日 (月が0始まり)
// ✅ Temporal - 一貫性のある動作
Temporal.PlainDate.from(2026, 0, 1) // これはエラーになる
Temporal.PlainDate.from('2026-01-01') // 2026年2月1日 (月が1始まり)6. 日付の計算がしにくい
Dateは日付の加算や減算を行うときは以下のようなコードとなり、直感的にわかりにくいです。
Temporalならaddおよびsubstractのメソッドチェーンを使用できるので直感的に計算可能です。
// ❌ Date - 日付の計算がしにくい
const today = new Date()
const result = new Date(today)
result.setMonth(result.getMonth() + 1)
result.setDate(result.getDate() + 2)
result.setFullYear(result.getFullYear() - 3)
console.log(result.toISOString().split('T')[0])
// 2023-02-20 (1ヶ月2日後から3年前)
// ✅ Temporal - 日付の計算がしやすい
const today = Temporal.Now.plainDateISO()
const result = today
.add({ months: 1, days: 2 })
.subtract({ years: 3 })
console.log(result.toString())
// 2023-02-20 (1ヶ月2日後から3年前)7. 日付の期間が計算しにくい
Dateは期間の処理が複雑で面倒です。
Temporalならt1.since(t2)という書き方で期間を取得できます。
// ❌ Date - 複雑で面倒
const date1 = new Date('2026-01-18')
const date2 = new Date('2024-03-15')
const diffMs = date1 - date2
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))
console.log(`${diffDays}日`) // 674日 (日数のみしか出せない)
// ✅ Temporal - 簡単に期間を出せる
const temporal1 = Temporal.PlainDate.from('2026-01-18')
const temporal2 = Temporal.PlainDate.from('2024-03-15')
const durationDay = temporal1.since(temporal2, { largestUnit: 'day' });
const duration = temporal1.since(temporal2, { largestUnit: 'year' })
console.log(`${durationDay.days}日`) // 674日 (日数のみの場合)
console.log(`${duration.years}年${duration.months}ヶ月${duration.days}日`)
// 1年10ヶ月3日 (年月日も出せる)まとめ
TemporalはDateが抱えてきた設計上の不整合や扱いにくさを解消し、より安全で直感的な日時処理を可能にする標準APIであり、今後のJavaScript開発では重要な選択肢になります。
最新のChromeやMicrosoft Edgeでは使用可能になっているので、Consoleで記事内のコードを実行して、利便性を実感してみてください。
