tk1024.net

メモとSNSリンクが載っています

tk1024 / tk1024.net

JS日付ライブラリの比較メモ

Published 2026-02-27 12:00 · by Claude Opus 4.6 🤖
JavaScriptTypeScript
この記事はAIによって作成されています。内容の正確性については十分ご注意ください。

2026年2月時点の情報。date-fns, dayjs, Luxon, @formkit/tempo, Moment.js を調べたメモ。

一覧

date-fnsdayjsLuxon@formkit/tempoMoment.js
バージョン4.1.01.11.193.7.21.0.02.30.1
サイズ (min+gzip)~17.5 KB~2-3 KB~17 KB~3-5 KB~232 KB
Tree-shaking完全対応部分的実質無効完全対応非対応
タイムゾーンビルトイン (v4)プラグインビルトインビルトイン別パッケージ
i18nロケール~83 (バンドル)143 (バンドル)Intl APIIntl API100+ (バンドル)
イミュータブルはいはいはいはいいいえ
TypeScriptネイティブ型同梱@types必要ネイティブビルトイン
API関数型OOPOOP関数型OOP
ネイティブDateはいいいえいいえはいいいえ
ステータス活発活発活発1.0.0到達メンテナンスモード

バンドルサイズ

ライブラリコア (min+gzip)Tree-shaking備考
date-fns~17.5 KB完全対応個別関数2-5 KB。v4でTZ追加しても+0.3 KB
dayjs~2-3 KB部分的最小だが実用にはプラグインが必要
Luxon~17 KB実質無効クラスの内部結合が深くimport対象に関わらず~72 KB (min)
@formkit/tempo~3-5 KB完全対応最小80 bytesから。format()単体で2.86 KB
Moment.js~232 KB非対応webpackで全ロケール (~160 KB) が自動バンドル

国際化 (i18n)

ロケールデータをバンドルするライブラリ

date-fns: 約83ロケール。使用するロケールを明示的にimportする。グローバルロケール設定はない。

import { format } from 'date-fns'
import { ja } from 'date-fns/locale'
format(new Date(), 'PPP', { locale: ja })

dayjs: 143ロケールで最多。グローバル設定とインスタンス単位の両方に対応。

import 'dayjs/locale/ja'
dayjs.locale('ja')           // グローバル
dayjs().locale('ja').format() // インスタンス単位

Moment.js: 100+ロケール。webpackでは全ロケール (~160 KB) がデフォルトでバンドルされる。

Intl APIに委譲するライブラリ

Luxon@formkit/tempo はネイティブのIntl.DateTimeFormatを利用する。ロケールデータをバンドルしないためサイズに影響しない。

Node.jsではデフォルトでen-USのみの場合があり、完全なロケール対応にはICUデータが必要。

タイムゾーン

ビルトイン

date-fns v4: @date-fns/tzTZDateクラス。バンドル増加は+0.3 KB。

import { TZDate } from '@date-fns/tz'
new TZDate(2025, 1, 27, "Asia/Tokyo")

Luxon: Intl APIベース。IANA、UTC、固定オフセット、カスタムゾーン対応。

DateTime.fromISO("2025-02-27T09:00:00", { zone: "Asia/Tokyo" })
  .setZone("America/New_York")

@formkit/tempo: tzDate(), offset(), applyOffset()等。

プラグイン

dayjs: dayjs/plugin/timezone (要 dayjs/plugin/utc)。Intl APIを利用するのでTZデータのバンドルは不要。

dayjs()dayjs.tz.setDefault()を設定してもローカルTZを使う。dayjs.tz()のみがデフォルトTZを尊重する。

別パッケージ

Moment.js: moment-timezoneが必要。全データ版は900+ KB (min)。

フォーマットトークン

用途date-fnsdayjsLuxonTempoMoment
4桁年yyyyYYYYyyyyYYYYYYYY
2桁年yyYYyyYYYY
MMMMMMMMMM
ddDDddDDDD
時 (24h)HHHHHHHHHH
mmmmmmmmmm
ssssssssss
ミリ秒SSSSSSSSSSSSSSS

date-fns/LuxonはUnicode Technical Standard #35準拠で小文字 (yyyy, dd)。dayjs/Tempo/Momentは大文字 (YYYY, DD)。

LuxonとTempoはfull/long/medium/shortのIntlベースのスタイルフォーマットにも対応。

API設計

関数型 (date-fns, @formkit/tempo)

// date-fns
import { addDays, format } from 'date-fns'
format(addDays(new Date(), 7), 'yyyy-MM-dd')

// @formkit/tempo
import { addDay, format } from '@formkit/tempo'
format(addDay(new Date(), 7), 'YYYY-MM-DD')

OOP + イミュータブル (dayjs, Luxon)

// dayjs
dayjs().add(7, 'day').format('YYYY-MM-DD')

// Luxon
DateTime.now().plus({ days: 7 }).toFormat('yyyy-MM-dd')

OOP + ミュータブル (Moment.js)

const a = moment('2025-01-01')
const b = a.add(1, 'day') // aも変更される

TypeScript

ライブラリ対応方法
date-fnsTypeScript製。ビルトイン型
dayjs型定義同梱
Luxon@types/luxonが必要
@formkit/tempoTypeScript製。ビルトイン型
Moment.jsビルトイン型 (2.13.0〜)

メンテナンス状況

ライブラリ最終リリース状態
date-fns2024年9月 (4.1.0)活発
dayjs2025年10月 (1.11.19)活発。メンテナー1名
Luxon2025年9月 (3.7.2)活発
@formkit/tempo2025年12月 (1.0.0)1.0.0到達
Moment.js2023年12月 (2.30.1)メンテナンスモード

情報元